Merge branch 'lineage-21.0' of https://github.com/LineageOS/android_hardware_lineage_interfaces into leaf-3.2

Change-Id: Ie5675527523bc843ed3dbb690a92cefdbb606af6
diff --git a/radio/1.4/legacy/Android.bp b/radio/1.4/legacy/Android.bp
new file mode 100644
index 0000000..8d2894e
--- /dev/null
+++ b/radio/1.4/legacy/Android.bp
@@ -0,0 +1,32 @@
+//
+// Copyright (C) 2024 The LineageOS Project
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+
+cc_binary {
+    name: "android.hardware.radio@1.4-service.legacy",
+    owner: "lineage",
+    relative_install_path: "hw",
+    vendor: true,
+    init_rc: ["android.hardware.radio@1.4-service.legacy.rc"],
+    srcs: [
+        "Radio.cpp",
+        "RadioIndication.cpp",
+        "RadioResponse.cpp",
+        "service.cpp",
+        "Helpers.cpp",
+        "hidl-utils.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libutils",
+        "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.hidl.safe_union@1.0",
+    ],
+}
diff --git a/radio/1.4/legacy/Helpers.cpp b/radio/1.4/legacy/Helpers.cpp
new file mode 100644
index 0000000..76c1f32
--- /dev/null
+++ b/radio/1.4/legacy/Helpers.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "Helpers.h"
+#include <regex>
+#include <vector>
+using namespace android::hardware::radio;
+
+V1_4::SignalStrength Create1_4SignalStrength(const V1_0::SignalStrength& sigStrength){
+
+    V1_4::SignalStrength newSigStrength = {};
+    newSigStrength.gsm = sigStrength.gw;
+    newSigStrength.cdma = sigStrength.cdma;
+    newSigStrength.evdo = sigStrength.evdo;
+    newSigStrength.lte = sigStrength.lte;
+
+    newSigStrength.tdscdma.signalStrength = INT_MAX;
+    newSigStrength.tdscdma.bitErrorRate = INT_MAX;
+    newSigStrength.tdscdma.rscp = sigStrength.tdScdma.rscp != INT_MAX ?
+        -sigStrength.tdScdma.rscp + 120 : INT_MAX;
+
+    newSigStrength.wcdma.base.signalStrength = INT_MAX;
+    newSigStrength.wcdma.base.bitErrorRate = INT_MAX;
+    newSigStrength.wcdma.rscp = INT_MAX;
+    newSigStrength.wcdma.ecno = INT_MAX;
+
+    newSigStrength.nr.ssRsrp = INT_MAX;
+    newSigStrength.nr.ssRsrq = INT_MAX;
+    newSigStrength.nr.ssSinr = INT_MAX;
+    newSigStrength.nr.csiRsrp = INT_MAX;
+    newSigStrength.nr.csiRsrq = INT_MAX;
+    newSigStrength.nr.csiSinr = INT_MAX;
+
+    return newSigStrength;
+}
+
+V1_4::SignalStrength Create1_4SignalStrength(const V1_2::SignalStrength& sigStrength){
+
+    V1_4::SignalStrength newSigStrength = {};
+    newSigStrength.gsm = sigStrength.gsm;
+    newSigStrength.cdma = sigStrength.cdma;
+    newSigStrength.evdo = sigStrength.evdo;
+    newSigStrength.lte = sigStrength.lte;
+    newSigStrength.wcdma = sigStrength.wcdma;
+
+    newSigStrength.tdscdma.signalStrength = INT_MAX;
+    newSigStrength.tdscdma.bitErrorRate = INT_MAX;
+    newSigStrength.tdscdma.rscp = sigStrength.tdScdma.rscp != INT_MAX ?
+        -sigStrength.tdScdma.rscp + 120 : INT_MAX;
+
+    newSigStrength.nr.ssRsrp = INT_MAX;
+    newSigStrength.nr.ssRsrq = INT_MAX;
+    newSigStrength.nr.ssSinr = INT_MAX;
+    newSigStrength.nr.csiRsrp = INT_MAX;
+    newSigStrength.nr.csiRsrq = INT_MAX;
+    newSigStrength.nr.csiSinr = INT_MAX;
+
+    return newSigStrength;
+}
+
+hidl_vec<V1_4::CellInfo> Create1_4CellInfoList(const hidl_vec<V1_0::CellInfo>& cellInfo) {
+    hidl_vec<V1_4::CellInfo> newCI;
+    newCI.resize(cellInfo.size());
+
+    for(int x = 0; x < cellInfo.size(); ++x){
+        newCI[x].isRegistered = cellInfo[x].registered;
+        newCI[x].connectionStatus = (V1_2::CellConnectionStatus) INT_MAX;
+        if(cellInfo[x].gsm.size() == 1){
+            V1_2::CellInfoGsm GsmInfo = {};
+            GsmInfo.cellIdentityGsm.base = cellInfo[x].gsm[0].cellIdentityGsm;
+            GsmInfo.signalStrengthGsm = cellInfo[x].gsm[0].signalStrengthGsm;
+            newCI[x].info.gsm(GsmInfo);
+        }
+        else if(cellInfo[x].cdma.size() == 1){
+            V1_2::CellInfoCdma CdmaInfo = {};
+            CdmaInfo.cellIdentityCdma.base = cellInfo[x].cdma[0].cellIdentityCdma;
+            CdmaInfo.signalStrengthCdma = cellInfo[x].cdma[0].signalStrengthCdma;
+            CdmaInfo.signalStrengthEvdo = cellInfo[x].cdma[0].signalStrengthEvdo;
+            newCI[x].info.cdma(CdmaInfo);
+        }
+        else if(cellInfo[x].lte.size() == 1){
+            V1_4::CellInfoLte LteInfo = {};
+            LteInfo.base.cellIdentityLte.base = cellInfo[x].lte[0].cellIdentityLte;
+            LteInfo.base.cellIdentityLte.bandwidth = INT_MAX;
+            LteInfo.cellConfig.isEndcAvailable = false;
+            LteInfo.base.signalStrengthLte = cellInfo[x].lte[0].signalStrengthLte;
+            newCI[x].info.lte(LteInfo);
+        }
+        else if(cellInfo[x].wcdma.size() == 1){
+            V1_2::CellInfoWcdma WcdmaInfo = {};
+            WcdmaInfo.cellIdentityWcdma.base = cellInfo[x].wcdma[0].cellIdentityWcdma;
+            WcdmaInfo.signalStrengthWcdma.base = cellInfo[x].wcdma[0].signalStrengthWcdma;
+            WcdmaInfo.signalStrengthWcdma.rscp = INT_MAX;
+            WcdmaInfo.signalStrengthWcdma.ecno = INT_MAX;
+            newCI[x].info.wcdma(WcdmaInfo);
+        }
+        else if(cellInfo[x].tdscdma.size() == 1){
+            V1_2::CellInfoTdscdma TdscdmaInfo = {};
+            TdscdmaInfo.cellIdentityTdscdma.base = cellInfo[x].tdscdma[0].cellIdentityTdscdma;
+            TdscdmaInfo.cellIdentityTdscdma.uarfcn = INT_MAX;
+            TdscdmaInfo.signalStrengthTdscdma.signalStrength = INT_MAX;
+            TdscdmaInfo.signalStrengthTdscdma.bitErrorRate = INT_MAX;
+            TdscdmaInfo.signalStrengthTdscdma.rscp = cellInfo[x].tdscdma[0].signalStrengthTdscdma.rscp != INT_MAX ?
+                -cellInfo[x].tdscdma[0].signalStrengthTdscdma.rscp + 120 : INT_MAX;
+            newCI[x].info.tdscdma(TdscdmaInfo);
+        }
+    }
+
+    return newCI;
+}
+
+hidl_vec<V1_4::CellInfo> Create1_4CellInfoList(const hidl_vec<V1_2::CellInfo>& cellInfo) {
+    hidl_vec<V1_4::CellInfo> newCI;
+    newCI.resize(cellInfo.size());
+
+    for(int x = 0; x < cellInfo.size(); ++x){
+        newCI[x].isRegistered = cellInfo[x].registered;
+        newCI[x].connectionStatus = cellInfo[x].connectionStatus;
+        if(cellInfo[x].gsm.size() == 1)
+            newCI[x].info.gsm(cellInfo[x].gsm[0]);
+
+        else if(cellInfo[x].cdma.size() == 1)
+            newCI[x].info.cdma(cellInfo[x].cdma[0]);
+
+        else if(cellInfo[x].lte.size() == 1){
+            V1_4::CellInfoLte LteInfo = {};
+            LteInfo.base = cellInfo[x].lte[0];
+            LteInfo.cellConfig.isEndcAvailable = false;
+            newCI[x].info.lte(LteInfo);
+        }
+        else if(cellInfo[x].wcdma.size() == 1)
+            newCI[x].info.wcdma(cellInfo[x].wcdma[0]);
+
+        else if(cellInfo[x].tdscdma.size() == 1)
+            newCI[x].info.tdscdma(cellInfo[x].tdscdma[0]);
+    }
+
+    return newCI;
+}
+
+hidl_vec<hidl_string> DelimitedStrToVec(std::string delimitedStr){
+    std::regex rgx("\\s+");
+    std::sregex_token_iterator iter(delimitedStr.begin(), delimitedStr.end(), rgx, -1);
+    std::sregex_token_iterator end;
+
+    std::vector<hidl_string> tokens;
+    for ( ; iter != end; ++iter)
+        tokens.push_back(hidl_string(*iter));
+
+    return hidl_vec(tokens);
+}
+
+V1_4::SetupDataCallResult Create1_4SetupDataCallResult(const V1_0::SetupDataCallResult& dcResponse){
+    V1_4::SetupDataCallResult newDCR = {};
+    newDCR.cause = (V1_4::DataCallFailCause) dcResponse.status;
+    newDCR.suggestedRetryTime = dcResponse.suggestedRetryTime;
+    newDCR.cid = dcResponse.cid;
+    newDCR.active = (V1_4::DataConnActiveStatus) dcResponse.active;
+    newDCR.ifname = dcResponse.ifname;
+    newDCR.mtu = dcResponse.mtu;
+    newDCR.addresses = DelimitedStrToVec(dcResponse.addresses);
+    newDCR.dnses = DelimitedStrToVec(dcResponse.dnses);
+    newDCR.gateways = DelimitedStrToVec(dcResponse.gateways);
+    newDCR.pcscf = DelimitedStrToVec(dcResponse.pcscf);
+    if(dcResponse.type == std::string("IP"))
+        newDCR.type= V1_4::PdpProtocolType::IP;
+    else if(dcResponse.type == std::string("IPV6"))
+        newDCR.type= V1_4::PdpProtocolType::IPV6;
+    else if(dcResponse.type == std::string("IPV4V6"))
+        newDCR.type= V1_4::PdpProtocolType::IPV4V6;
+    else if(dcResponse.type == std::string("PPP"))
+        newDCR.type= V1_4::PdpProtocolType::PPP;
+    else if(dcResponse.type == std::string("NON-IP"))
+        newDCR.type= V1_4::PdpProtocolType::NON_IP;
+    else if(dcResponse.type == std::string("UNSTRUCTURED"))
+        newDCR.type= V1_4::PdpProtocolType::UNSTRUCTURED;
+    else
+        newDCR.type= V1_4::PdpProtocolType::UNKNOWN;
+
+    return newDCR;
+}
diff --git a/radio/1.4/legacy/Helpers.h b/radio/1.4/legacy/Helpers.h
new file mode 100644
index 0000000..3a7a93d
--- /dev/null
+++ b/radio/1.4/legacy/Helpers.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+#include <android/hardware/radio/1.4/IRadioResponse.h>
+#include <android/hardware/radio/1.4/IRadio.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+#define GSMBITS (V1_0::RadioAccessFamily::GSM | V1_0::RadioAccessFamily::GPRS | V1_0::RadioAccessFamily::EDGE)
+#define CDMABITS (V1_0::RadioAccessFamily::IS95A | V1_0::RadioAccessFamily::IS95B | V1_0::RadioAccessFamily::ONE_X_RTT)
+#define EVDOBITS (V1_0::RadioAccessFamily::EVDO_0 | V1_0::RadioAccessFamily::EVDO_A | V1_0::RadioAccessFamily::EVDO_B | V1_0::RadioAccessFamily::EHRPD)
+#define WCDMABITS (V1_0::RadioAccessFamily::HSUPA | V1_0::RadioAccessFamily::HSDPA | V1_0::RadioAccessFamily::HSPA | V1_0::RadioAccessFamily::HSPAP | V1_0::RadioAccessFamily::UMTS)
+#define LTEBITS (V1_0::RadioAccessFamily::LTE | V1_0::RadioAccessFamily::LTE_CA)
+#define TDSCDMABIT ((int) V1_0::RadioAccessFamily::TD_SCDMA)
+
+android::hardware::radio::V1_4::SignalStrength Create1_4SignalStrength(const android::hardware::radio::V1_0::SignalStrength& sigStrength);
+android::hardware::radio::V1_4::SignalStrength Create1_4SignalStrength(const android::hardware::radio::V1_2::SignalStrength& sigStrength);
+hidl_vec<android::hardware::radio::V1_4::CellInfo> Create1_4CellInfoList(const hidl_vec<android::hardware::radio::V1_0::CellInfo>& cellInfo);
+hidl_vec<android::hardware::radio::V1_4::CellInfo> Create1_4CellInfoList(const hidl_vec<android::hardware::radio::V1_2::CellInfo>& cellInfo);
+android::hardware::radio::V1_4::SetupDataCallResult Create1_4SetupDataCallResult(const android::hardware::radio::V1_0::SetupDataCallResult& dcResponse);
diff --git a/radio/1.4/legacy/Radio.cpp b/radio/1.4/legacy/Radio.cpp
new file mode 100644
index 0000000..4af7e35
--- /dev/null
+++ b/radio/1.4/legacy/Radio.cpp
@@ -0,0 +1,984 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define LOG_TAG "android.hardware.radio@1.4-service.legacy"
+
+#include "Radio.h"
+#include "Helpers.h"
+#include <vector>
+#include <string>
+
+#include <android-base/logging.h>
+
+#define WRAP_V1_0_CALL(method, ...)                                            \
+    do {                                                                       \
+        auto realRadio = mRealRadio;                                           \
+        if (realRadio != nullptr) {                                            \
+            return realRadio->method(__VA_ARGS__);                             \
+        }                                                                      \
+        return Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE); \
+    } while (0)
+
+#define MAYBE_WRAP_V1_1_CALL(method, ...)               \
+    do {                                                \
+        auto realRadio_V1_1 = getRealRadio_V1_1();      \
+        if (realRadio_V1_1 != nullptr) {                \
+            return realRadio_V1_1->method(__VA_ARGS__); \
+        }                                               \
+    } while (0)
+
+#define MAYBE_WRAP_V1_2_CALL(method, ...)               \
+    do {                                                \
+        auto realRadio_V1_2 = getRealRadio_V1_2();      \
+        if (realRadio_V1_2 != nullptr) {                \
+            return realRadio_V1_2->method(__VA_ARGS__); \
+        }                                               \
+    } while (0)
+
+#define MAYBE_WRAP_V1_3_CALL(method, ...)               \
+    do {                                                \
+        auto realRadio_V1_3 = getRealRadio_V1_3();      \
+        if (realRadio_V1_3 != nullptr) {                \
+            return realRadio_V1_3->method(__VA_ARGS__); \
+        }                                               \
+    } while (0)
+
+#define MAYBE_WRAP_V1_4_CALL(method, ...)                    \
+    do {                                                     \
+        auto realRadio_V1_4 = getRealRadio_V1_4();           \
+        if (realRadio_V1_4 != nullptr) {                     \
+            LOG(WARNING) << "Using wrapper when not needed"; \
+            return realRadio_V1_4->method(__VA_ARGS__);      \
+        }                                                    \
+    } while (0)
+
+namespace android::hardware::radio::implementation {
+
+Radio::Radio(sp<V1_0::IRadio> realRadio) : mRealRadio(realRadio) {}
+
+// Methods from ::android::hardware::radio::V1_0::IRadio follow.
+Return<void> Radio::setResponseFunctions(const sp<V1_0::IRadioResponse>& radioResponse,
+                                         const sp<V1_0::IRadioIndication>& radioIndication) {
+    mRadioResponse->mRealRadioResponse = V1_4::IRadioResponse::castFrom(radioResponse);
+    mRadioIndication->mRealRadioIndication = V1_4::IRadioIndication::castFrom(radioIndication);
+    WRAP_V1_0_CALL(setResponseFunctions, mRadioResponse, mRadioIndication);
+}
+
+Return<void> Radio::getIccCardStatus(int32_t serial) {
+    WRAP_V1_0_CALL(getIccCardStatus, serial);
+}
+
+Return<void> Radio::supplyIccPinForApp(int32_t serial, const hidl_string& pin,
+                                       const hidl_string& aid) {
+    WRAP_V1_0_CALL(supplyIccPinForApp, serial, pin, aid);
+}
+
+Return<void> Radio::supplyIccPukForApp(int32_t serial, const hidl_string& puk,
+                                       const hidl_string& pin, const hidl_string& aid) {
+    WRAP_V1_0_CALL(supplyIccPukForApp, serial, puk, pin, aid);
+}
+
+Return<void> Radio::supplyIccPin2ForApp(int32_t serial, const hidl_string& pin2,
+                                        const hidl_string& aid) {
+    WRAP_V1_0_CALL(supplyIccPin2ForApp, serial, pin2, aid);
+}
+
+Return<void> Radio::supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2,
+                                        const hidl_string& pin2, const hidl_string& aid) {
+    WRAP_V1_0_CALL(supplyIccPuk2ForApp, serial, puk2, pin2, aid);
+}
+
+Return<void> Radio::changeIccPinForApp(int32_t serial, const hidl_string& oldPin,
+                                       const hidl_string& newPin, const hidl_string& aid) {
+    WRAP_V1_0_CALL(changeIccPinForApp, serial, oldPin, newPin, aid);
+}
+
+Return<void> Radio::changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2,
+                                        const hidl_string& newPin2, const hidl_string& aid) {
+    WRAP_V1_0_CALL(changeIccPin2ForApp, serial, oldPin2, newPin2, aid);
+}
+
+Return<void> Radio::supplyNetworkDepersonalization(int32_t serial, const hidl_string& netPin) {
+    WRAP_V1_0_CALL(supplyNetworkDepersonalization, serial, netPin);
+}
+
+Return<void> Radio::getCurrentCalls(int32_t serial) {
+    WRAP_V1_0_CALL(getCurrentCalls, serial);
+}
+
+Return<void> Radio::dial(int32_t serial, const V1_0::Dial& dialInfo) {
+    WRAP_V1_0_CALL(dial, serial, dialInfo);
+}
+
+Return<void> Radio::getImsiForApp(int32_t serial, const hidl_string& aid) {
+    WRAP_V1_0_CALL(getImsiForApp, serial, aid);
+}
+
+Return<void> Radio::hangup(int32_t serial, int32_t gsmIndex) {
+    WRAP_V1_0_CALL(hangup, serial, gsmIndex);
+}
+
+Return<void> Radio::hangupWaitingOrBackground(int32_t serial) {
+    WRAP_V1_0_CALL(hangupWaitingOrBackground, serial);
+}
+
+Return<void> Radio::hangupForegroundResumeBackground(int32_t serial) {
+    WRAP_V1_0_CALL(hangupForegroundResumeBackground, serial);
+}
+
+Return<void> Radio::switchWaitingOrHoldingAndActive(int32_t serial) {
+    WRAP_V1_0_CALL(switchWaitingOrHoldingAndActive, serial);
+}
+
+Return<void> Radio::conference(int32_t serial) {
+    WRAP_V1_0_CALL(conference, serial);
+}
+
+Return<void> Radio::rejectCall(int32_t serial) {
+    WRAP_V1_0_CALL(rejectCall, serial);
+}
+
+Return<void> Radio::getLastCallFailCause(int32_t serial) {
+    WRAP_V1_0_CALL(getLastCallFailCause, serial);
+}
+
+Return<void> Radio::getSignalStrength(int32_t serial) {
+    WRAP_V1_0_CALL(getSignalStrength, serial);
+}
+
+Return<void> Radio::getVoiceRegistrationState(int32_t serial) {
+    WRAP_V1_0_CALL(getVoiceRegistrationState, serial);
+}
+
+Return<void> Radio::getDataRegistrationState(int32_t serial) {
+    WRAP_V1_0_CALL(getDataRegistrationState, serial);
+}
+
+Return<void> Radio::getOperator(int32_t serial) {
+    WRAP_V1_0_CALL(getOperator, serial);
+}
+
+Return<void> Radio::setRadioPower(int32_t serial, bool on) {
+    WRAP_V1_0_CALL(setRadioPower, serial, on);
+}
+
+Return<void> Radio::sendDtmf(int32_t serial, const hidl_string& s) {
+    WRAP_V1_0_CALL(sendDtmf, serial, s);
+}
+
+Return<void> Radio::sendSms(int32_t serial, const V1_0::GsmSmsMessage& message) {
+    WRAP_V1_0_CALL(sendSms, serial, message);
+}
+
+Return<void> Radio::sendSMSExpectMore(int32_t serial, const V1_0::GsmSmsMessage& message) {
+    WRAP_V1_0_CALL(sendSMSExpectMore, serial, message);
+}
+
+Return<void> Radio::setupDataCall(int32_t serial, V1_0::RadioTechnology radioTechnology,
+                                  const V1_0::DataProfileInfo& dataProfileInfo, bool modemCognitive,
+                                  bool roamingAllowed, bool isRoaming) {
+    WRAP_V1_0_CALL(setupDataCall, serial, radioTechnology, dataProfileInfo, modemCognitive,
+                   roamingAllowed, isRoaming);
+}
+
+Return<void> Radio::iccIOForApp(int32_t serial, const V1_0::IccIo& iccIo) {
+    WRAP_V1_0_CALL(iccIOForApp, serial, iccIo);
+}
+
+Return<void> Radio::sendUssd(int32_t serial, const hidl_string& ussd) {
+    WRAP_V1_0_CALL(sendUssd, serial, ussd);
+}
+
+Return<void> Radio::cancelPendingUssd(int32_t serial) {
+    WRAP_V1_0_CALL(cancelPendingUssd, serial);
+}
+
+Return<void> Radio::getClir(int32_t serial) {
+    WRAP_V1_0_CALL(getClir, serial);
+}
+
+Return<void> Radio::setClir(int32_t serial, int32_t status) {
+    WRAP_V1_0_CALL(setClir, serial, status);
+}
+
+Return<void> Radio::getCallForwardStatus(int32_t serial, const V1_0::CallForwardInfo& callInfo) {
+    WRAP_V1_0_CALL(getCallForwardStatus, serial, callInfo);
+}
+
+Return<void> Radio::setCallForward(int32_t serial, const V1_0::CallForwardInfo& callInfo) {
+    WRAP_V1_0_CALL(setCallForward, serial, callInfo);
+}
+
+Return<void> Radio::getCallWaiting(int32_t serial, int32_t serviceClass) {
+    WRAP_V1_0_CALL(getCallWaiting, serial, serviceClass);
+}
+
+Return<void> Radio::setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) {
+    WRAP_V1_0_CALL(setCallWaiting, serial, enable, serviceClass);
+}
+
+Return<void> Radio::acknowledgeLastIncomingGsmSms(int32_t serial, bool success,
+                                                  V1_0::SmsAcknowledgeFailCause cause) {
+    WRAP_V1_0_CALL(acknowledgeLastIncomingGsmSms, serial, success, cause);
+}
+
+Return<void> Radio::acceptCall(int32_t serial) {
+    WRAP_V1_0_CALL(acceptCall, serial);
+}
+
+Return<void> Radio::deactivateDataCall(int32_t serial, int32_t cid, bool reasonRadioShutDown) {
+    WRAP_V1_0_CALL(deactivateDataCall, serial, cid, reasonRadioShutDown);
+}
+
+Return<void> Radio::getFacilityLockForApp(int32_t serial, const hidl_string& facility,
+                                          const hidl_string& password, int32_t serviceClass,
+                                          const hidl_string& appId) {
+    WRAP_V1_0_CALL(getFacilityLockForApp, serial, facility, password, serviceClass, appId);
+}
+
+Return<void> Radio::setFacilityLockForApp(int32_t serial, const hidl_string& facility,
+                                          bool lockState, const hidl_string& password,
+                                          int32_t serviceClass, const hidl_string& appId) {
+    WRAP_V1_0_CALL(setFacilityLockForApp, serial, facility, lockState, password, serviceClass,
+                   appId);
+}
+
+Return<void> Radio::setBarringPassword(int32_t serial, const hidl_string& facility,
+                                       const hidl_string& oldPassword,
+                                       const hidl_string& newPassword) {
+    WRAP_V1_0_CALL(setBarringPassword, serial, facility, oldPassword, newPassword);
+}
+
+Return<void> Radio::getNetworkSelectionMode(int32_t serial) {
+    WRAP_V1_0_CALL(getNetworkSelectionMode, serial);
+}
+
+Return<void> Radio::setNetworkSelectionModeAutomatic(int32_t serial) {
+    WRAP_V1_0_CALL(setNetworkSelectionModeAutomatic, serial);
+}
+
+Return<void> Radio::setNetworkSelectionModeManual(int32_t serial,
+                                                  const hidl_string& operatorNumeric) {
+    WRAP_V1_0_CALL(setNetworkSelectionModeManual, serial, operatorNumeric);
+}
+
+Return<void> Radio::getAvailableNetworks(int32_t serial) {
+    WRAP_V1_0_CALL(getAvailableNetworks, serial);
+}
+
+Return<void> Radio::startDtmf(int32_t serial, const hidl_string& s) {
+    WRAP_V1_0_CALL(startDtmf, serial, s);
+}
+
+Return<void> Radio::stopDtmf(int32_t serial) {
+    WRAP_V1_0_CALL(stopDtmf, serial);
+}
+
+Return<void> Radio::getBasebandVersion(int32_t serial) {
+    WRAP_V1_0_CALL(getBasebandVersion, serial);
+}
+
+Return<void> Radio::separateConnection(int32_t serial, int32_t gsmIndex) {
+    WRAP_V1_0_CALL(separateConnection, serial, gsmIndex);
+}
+
+Return<void> Radio::setMute(int32_t serial, bool enable) {
+    WRAP_V1_0_CALL(setMute, serial, enable);
+}
+
+Return<void> Radio::getMute(int32_t serial) {
+    WRAP_V1_0_CALL(getMute, serial);
+}
+
+Return<void> Radio::getClip(int32_t serial) {
+    WRAP_V1_0_CALL(getClip, serial);
+}
+
+Return<void> Radio::getDataCallList(int32_t serial) {
+    WRAP_V1_0_CALL(getDataCallList, serial);
+}
+
+Return<void> Radio::setSuppServiceNotifications(int32_t serial, bool enable) {
+    WRAP_V1_0_CALL(setSuppServiceNotifications, serial, enable);
+}
+
+Return<void> Radio::writeSmsToSim(int32_t serial, const V1_0::SmsWriteArgs& smsWriteArgs) {
+    WRAP_V1_0_CALL(writeSmsToSim, serial, smsWriteArgs);
+}
+
+Return<void> Radio::deleteSmsOnSim(int32_t serial, int32_t index) {
+    WRAP_V1_0_CALL(deleteSmsOnSim, serial, index);
+}
+
+Return<void> Radio::setBandMode(int32_t serial, V1_0::RadioBandMode mode) {
+    WRAP_V1_0_CALL(setBandMode, serial, mode);
+}
+
+Return<void> Radio::getAvailableBandModes(int32_t serial) {
+    WRAP_V1_0_CALL(getAvailableBandModes, serial);
+}
+
+Return<void> Radio::sendEnvelope(int32_t serial, const hidl_string& command) {
+    WRAP_V1_0_CALL(sendEnvelope, serial, command);
+}
+
+Return<void> Radio::sendTerminalResponseToSim(int32_t serial, const hidl_string& commandResponse) {
+    WRAP_V1_0_CALL(sendTerminalResponseToSim, serial, commandResponse);
+}
+
+Return<void> Radio::handleStkCallSetupRequestFromSim(int32_t serial, bool accept) {
+    WRAP_V1_0_CALL(handleStkCallSetupRequestFromSim, serial, accept);
+}
+
+Return<void> Radio::explicitCallTransfer(int32_t serial) {
+    WRAP_V1_0_CALL(explicitCallTransfer, serial);
+}
+
+Return<void> Radio::setPreferredNetworkType(int32_t serial, V1_0::PreferredNetworkType nwType) {
+    WRAP_V1_0_CALL(setPreferredNetworkType, serial, nwType);
+}
+
+Return<void> Radio::getPreferredNetworkType(int32_t serial) {
+    WRAP_V1_0_CALL(getPreferredNetworkType, serial);
+}
+
+Return<void> Radio::getNeighboringCids(int32_t serial) {
+    WRAP_V1_0_CALL(getNeighboringCids, serial);
+}
+
+Return<void> Radio::setLocationUpdates(int32_t serial, bool enable) {
+    WRAP_V1_0_CALL(setLocationUpdates, serial, enable);
+}
+
+Return<void> Radio::setCdmaSubscriptionSource(int32_t serial,
+                                              V1_0::CdmaSubscriptionSource cdmaSub) {
+    WRAP_V1_0_CALL(setCdmaSubscriptionSource, serial, cdmaSub);
+}
+
+Return<void> Radio::setCdmaRoamingPreference(int32_t serial, V1_0::CdmaRoamingType type) {
+    WRAP_V1_0_CALL(setCdmaRoamingPreference, serial, type);
+}
+
+Return<void> Radio::getCdmaRoamingPreference(int32_t serial) {
+    WRAP_V1_0_CALL(getCdmaRoamingPreference, serial);
+}
+
+Return<void> Radio::setTTYMode(int32_t serial, V1_0::TtyMode mode) {
+    WRAP_V1_0_CALL(setTTYMode, serial, mode);
+}
+
+Return<void> Radio::getTTYMode(int32_t serial) {
+    WRAP_V1_0_CALL(getTTYMode, serial);
+}
+
+Return<void> Radio::setPreferredVoicePrivacy(int32_t serial, bool enable) {
+    WRAP_V1_0_CALL(setPreferredVoicePrivacy, serial, enable);
+}
+
+Return<void> Radio::getPreferredVoicePrivacy(int32_t serial) {
+    WRAP_V1_0_CALL(getPreferredVoicePrivacy, serial);
+}
+
+Return<void> Radio::sendCDMAFeatureCode(int32_t serial, const hidl_string& featureCode) {
+    WRAP_V1_0_CALL(sendCDMAFeatureCode, serial, featureCode);
+}
+
+Return<void> Radio::sendBurstDtmf(int32_t serial, const hidl_string& dtmf, int32_t on,
+                                  int32_t off) {
+    WRAP_V1_0_CALL(sendBurstDtmf, serial, dtmf, on, off);
+}
+
+Return<void> Radio::sendCdmaSms(int32_t serial, const V1_0::CdmaSmsMessage& sms) {
+    WRAP_V1_0_CALL(sendCdmaSms, serial, sms);
+}
+
+Return<void> Radio::acknowledgeLastIncomingCdmaSms(int32_t serial, const V1_0::CdmaSmsAck& smsAck) {
+    WRAP_V1_0_CALL(acknowledgeLastIncomingCdmaSms, serial, smsAck);
+}
+
+Return<void> Radio::getGsmBroadcastConfig(int32_t serial) {
+    WRAP_V1_0_CALL(getGsmBroadcastConfig, serial);
+}
+
+Return<void> Radio::setGsmBroadcastConfig(
+        int32_t serial, const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& configInfo) {
+    WRAP_V1_0_CALL(setGsmBroadcastConfig, serial, configInfo);
+}
+
+Return<void> Radio::setGsmBroadcastActivation(int32_t serial, bool activate) {
+    WRAP_V1_0_CALL(setGsmBroadcastActivation, serial, activate);
+}
+
+Return<void> Radio::getCdmaBroadcastConfig(int32_t serial) {
+    WRAP_V1_0_CALL(getCdmaBroadcastConfig, serial);
+}
+
+Return<void> Radio::setCdmaBroadcastConfig(
+        int32_t serial, const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configInfo) {
+    WRAP_V1_0_CALL(setCdmaBroadcastConfig, serial, configInfo);
+}
+
+Return<void> Radio::setCdmaBroadcastActivation(int32_t serial, bool activate) {
+    WRAP_V1_0_CALL(setCdmaBroadcastActivation, serial, activate);
+}
+
+Return<void> Radio::getCDMASubscription(int32_t serial) {
+    WRAP_V1_0_CALL(getCDMASubscription, serial);
+}
+
+Return<void> Radio::writeSmsToRuim(int32_t serial, const V1_0::CdmaSmsWriteArgs& cdmaSms) {
+    WRAP_V1_0_CALL(writeSmsToRuim, serial, cdmaSms);
+}
+
+Return<void> Radio::deleteSmsOnRuim(int32_t serial, int32_t index) {
+    WRAP_V1_0_CALL(deleteSmsOnRuim, serial, index);
+}
+
+Return<void> Radio::getDeviceIdentity(int32_t serial) {
+    WRAP_V1_0_CALL(getDeviceIdentity, serial);
+}
+
+Return<void> Radio::exitEmergencyCallbackMode(int32_t serial) {
+    WRAP_V1_0_CALL(exitEmergencyCallbackMode, serial);
+}
+
+Return<void> Radio::getSmscAddress(int32_t serial) {
+    WRAP_V1_0_CALL(getSmscAddress, serial);
+}
+
+Return<void> Radio::setSmscAddress(int32_t serial, const hidl_string& smsc) {
+    WRAP_V1_0_CALL(setSmscAddress, serial, smsc);
+}
+
+Return<void> Radio::reportSmsMemoryStatus(int32_t serial, bool available) {
+    WRAP_V1_0_CALL(reportSmsMemoryStatus, serial, available);
+}
+
+Return<void> Radio::reportStkServiceIsRunning(int32_t serial) {
+    WRAP_V1_0_CALL(reportStkServiceIsRunning, serial);
+}
+
+Return<void> Radio::getCdmaSubscriptionSource(int32_t serial) {
+    WRAP_V1_0_CALL(getCdmaSubscriptionSource, serial);
+}
+
+Return<void> Radio::requestIsimAuthentication(int32_t serial, const hidl_string& challenge) {
+    WRAP_V1_0_CALL(requestIsimAuthentication, serial, challenge);
+}
+
+Return<void> Radio::acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success,
+                                                     const hidl_string& ackPdu) {
+    WRAP_V1_0_CALL(acknowledgeIncomingGsmSmsWithPdu, serial, success, ackPdu);
+}
+
+Return<void> Radio::sendEnvelopeWithStatus(int32_t serial, const hidl_string& contents) {
+    WRAP_V1_0_CALL(sendEnvelopeWithStatus, serial, contents);
+}
+
+Return<void> Radio::getVoiceRadioTechnology(int32_t serial) {
+    WRAP_V1_0_CALL(getVoiceRadioTechnology, serial);
+}
+
+Return<void> Radio::getCellInfoList(int32_t serial) {
+    WRAP_V1_0_CALL(getCellInfoList, serial);
+}
+
+Return<void> Radio::setCellInfoListRate(int32_t serial, int32_t rate) {
+    WRAP_V1_0_CALL(setCellInfoListRate, serial, rate);
+}
+
+Return<void> Radio::setInitialAttachApn(int32_t serial,
+                                        const V1_0::DataProfileInfo& dataProfileInfo,
+                                        bool modemCognitive, bool isRoaming) {
+    WRAP_V1_0_CALL(setInitialAttachApn, serial, dataProfileInfo, modemCognitive, isRoaming);
+}
+
+Return<void> Radio::getImsRegistrationState(int32_t serial) {
+    WRAP_V1_0_CALL(getImsRegistrationState, serial);
+}
+
+Return<void> Radio::sendImsSms(int32_t serial, const V1_0::ImsSmsMessage& message) {
+    WRAP_V1_0_CALL(sendImsSms, serial, message);
+}
+
+Return<void> Radio::iccTransmitApduBasicChannel(int32_t serial, const V1_0::SimApdu& message) {
+    WRAP_V1_0_CALL(iccTransmitApduBasicChannel, serial, message);
+}
+
+Return<void> Radio::iccOpenLogicalChannel(int32_t serial, const hidl_string& aid, int32_t p2) {
+    WRAP_V1_0_CALL(iccOpenLogicalChannel, serial, aid, p2);
+}
+
+Return<void> Radio::iccCloseLogicalChannel(int32_t serial, int32_t channelId) {
+    WRAP_V1_0_CALL(iccCloseLogicalChannel, serial, channelId);
+}
+
+Return<void> Radio::iccTransmitApduLogicalChannel(int32_t serial, const V1_0::SimApdu& message) {
+    WRAP_V1_0_CALL(iccTransmitApduLogicalChannel, serial, message);
+}
+
+Return<void> Radio::nvReadItem(int32_t serial, V1_0::NvItem itemId) {
+    WRAP_V1_0_CALL(nvReadItem, serial, itemId);
+}
+
+Return<void> Radio::nvWriteItem(int32_t serial, const V1_0::NvWriteItem& item) {
+    WRAP_V1_0_CALL(nvWriteItem, serial, item);
+}
+
+Return<void> Radio::nvWriteCdmaPrl(int32_t serial, const hidl_vec<uint8_t>& prl) {
+    WRAP_V1_0_CALL(nvWriteCdmaPrl, serial, prl);
+}
+
+Return<void> Radio::nvResetConfig(int32_t serial, V1_0::ResetNvType resetType) {
+    WRAP_V1_0_CALL(nvResetConfig, serial, resetType);
+}
+
+Return<void> Radio::setUiccSubscription(int32_t serial, const V1_0::SelectUiccSub& uiccSub) {
+    WRAP_V1_0_CALL(setUiccSubscription, serial, uiccSub);
+}
+
+Return<void> Radio::setDataAllowed(int32_t serial, bool allow) {
+    WRAP_V1_0_CALL(setDataAllowed, serial, allow);
+}
+
+Return<void> Radio::getHardwareConfig(int32_t serial) {
+    WRAP_V1_0_CALL(getHardwareConfig, serial);
+}
+
+Return<void> Radio::requestIccSimAuthentication(int32_t serial, int32_t authContext,
+                                                const hidl_string& authData,
+                                                const hidl_string& aid) {
+    WRAP_V1_0_CALL(requestIccSimAuthentication, serial, authContext, authData, aid);
+}
+
+Return<void> Radio::setDataProfile(int32_t serial, const hidl_vec<V1_0::DataProfileInfo>& profiles,
+                                   bool isRoaming) {
+    WRAP_V1_0_CALL(setDataProfile, serial, profiles, isRoaming);
+}
+
+Return<void> Radio::requestShutdown(int32_t serial) {
+    WRAP_V1_0_CALL(requestShutdown, serial);
+}
+
+Return<void> Radio::getRadioCapability(int32_t serial) {
+    WRAP_V1_0_CALL(getRadioCapability, serial);
+}
+
+Return<void> Radio::setRadioCapability(int32_t serial, const V1_0::RadioCapability& rc) {
+    WRAP_V1_0_CALL(setRadioCapability, serial, rc);
+}
+
+Return<void> Radio::startLceService(int32_t serial, int32_t reportInterval, bool pullMode) {
+    WRAP_V1_0_CALL(startLceService, serial, reportInterval, pullMode);
+}
+
+Return<void> Radio::stopLceService(int32_t serial) {
+    WRAP_V1_0_CALL(stopLceService, serial);
+}
+
+Return<void> Radio::pullLceData(int32_t serial) {
+    WRAP_V1_0_CALL(pullLceData, serial);
+}
+
+Return<void> Radio::getModemActivityInfo(int32_t serial) {
+    WRAP_V1_0_CALL(getModemActivityInfo, serial);
+}
+
+Return<void> Radio::setAllowedCarriers(int32_t serial, bool allAllowed,
+                                       const V1_0::CarrierRestrictions& carriers) {
+    WRAP_V1_0_CALL(setAllowedCarriers, serial, allAllowed, carriers);
+}
+
+Return<void> Radio::getAllowedCarriers(int32_t serial) {
+    WRAP_V1_0_CALL(getAllowedCarriers, serial);
+}
+
+Return<void> Radio::sendDeviceState(int32_t serial, V1_0::DeviceStateType deviceStateType,
+                                    bool state) {
+    WRAP_V1_0_CALL(sendDeviceState, serial, deviceStateType, state);
+}
+
+Return<void> Radio::setIndicationFilter(int32_t serial,
+                                        hidl_bitfield<V1_0::IndicationFilter> indicationFilter) {
+    WRAP_V1_0_CALL(setIndicationFilter, serial, indicationFilter);
+}
+
+Return<void> Radio::setSimCardPower(int32_t serial, bool powerUp) {
+    WRAP_V1_0_CALL(setSimCardPower, serial, powerUp);
+}
+
+Return<void> Radio::responseAcknowledgement() {
+    WRAP_V1_0_CALL(responseAcknowledgement);
+}
+
+// Methods from ::android::hardware::radio::V1_1::IRadio follow.
+Return<void> Radio::setCarrierInfoForImsiEncryption(
+        int32_t serial, const V1_1::ImsiEncryptionInfo& imsiEncryptionInfo) {
+    MAYBE_WRAP_V1_1_CALL(setCarrierInfoForImsiEncryption, serial, imsiEncryptionInfo);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::setSimCardPower_1_1(int32_t serial, V1_1::CardPowerState powerUp) {
+    MAYBE_WRAP_V1_1_CALL(setSimCardPower_1_1, serial, powerUp);
+
+    if(powerUp != V1_1::CardPowerState::POWER_UP_PASS_THROUGH)
+        WRAP_V1_0_CALL(setSimCardPower, serial, (bool) powerUp);
+
+    return Void();
+}
+
+Return<void> Radio::startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request) {
+    MAYBE_WRAP_V1_1_CALL(startNetworkScan, serial, request);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::stopNetworkScan(int32_t serial) {
+    MAYBE_WRAP_V1_1_CALL(stopNetworkScan, serial);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::startKeepalive(int32_t serial, const V1_1::KeepaliveRequest& keepalive) {
+    MAYBE_WRAP_V1_1_CALL(startKeepalive, serial, keepalive);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::stopKeepalive(int32_t serial, int32_t sessionHandle) {
+    MAYBE_WRAP_V1_1_CALL(stopKeepalive, serial, sessionHandle);
+
+    // TODO implement
+    return Void();
+}
+
+// Methods from ::android::hardware::radio::V1_2::IRadio follow.
+Return<void> Radio::startNetworkScan_1_2(int32_t serial, const V1_2::NetworkScanRequest& request) {
+    MAYBE_WRAP_V1_2_CALL(startNetworkScan_1_2, serial, request);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::setIndicationFilter_1_2(
+        int32_t serial, hidl_bitfield<V1_2::IndicationFilter> indicationFilter) {
+    MAYBE_WRAP_V1_2_CALL(setIndicationFilter_1_2, serial, indicationFilter);
+    WRAP_V1_0_CALL(setIndicationFilter, serial, indicationFilter & V1_0::IndicationFilter::ALL);
+}
+
+Return<void> Radio::setSignalStrengthReportingCriteria(int32_t serial, int32_t hysteresisMs,
+                                                       int32_t hysteresisDb,
+                                                       const hidl_vec<int32_t>& thresholdsDbm,
+                                                       V1_2::AccessNetwork accessNetwork) {
+    MAYBE_WRAP_V1_2_CALL(setSignalStrengthReportingCriteria, serial, hysteresisMs, hysteresisDb,
+                         thresholdsDbm, accessNetwork);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::setLinkCapacityReportingCriteria(
+        int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps, int32_t hysteresisUlKbps,
+        const hidl_vec<int32_t>& thresholdsDownlinkKbps,
+        const hidl_vec<int32_t>& thresholdsUplinkKbps, V1_2::AccessNetwork accessNetwork) {
+    MAYBE_WRAP_V1_2_CALL(setLinkCapacityReportingCriteria, serial, hysteresisMs, hysteresisDlKbps,
+                         hysteresisUlKbps, thresholdsDownlinkKbps, thresholdsUplinkKbps,
+                         accessNetwork);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::setupDataCall_1_2(int32_t serial, V1_2::AccessNetwork accessNetwork,
+                                      const V1_0::DataProfileInfo& dataProfileInfo,
+                                      bool modemCognitive, bool roamingAllowed, bool isRoaming,
+                                      V1_2::DataRequestReason reason,
+                                      const hidl_vec<hidl_string>& addresses,
+                                      const hidl_vec<hidl_string>& dnses) {
+    MAYBE_WRAP_V1_2_CALL(setupDataCall_1_2, serial, accessNetwork, dataProfileInfo, modemCognitive,
+                         roamingAllowed, isRoaming, reason, addresses, dnses);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::deactivateDataCall_1_2(int32_t serial, int32_t cid,
+                                           V1_2::DataRequestReason reason) {
+    MAYBE_WRAP_V1_2_CALL(deactivateDataCall_1_2, serial, cid, reason);
+    WRAP_V1_0_CALL(deactivateDataCall, serial, cid, reason == V1_2::DataRequestReason::SHUTDOWN);
+}
+
+// Methods from ::android::hardware::radio::V1_3::IRadio follow.
+Return<void> Radio::setSystemSelectionChannels(
+        int32_t serial, bool specifyChannels,
+        const hidl_vec<V1_1::RadioAccessSpecifier>& specifiers) {
+    MAYBE_WRAP_V1_3_CALL(setSystemSelectionChannels, serial, specifyChannels, specifiers);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::enableModem(int32_t serial, bool on) {
+    MAYBE_WRAP_V1_3_CALL(enableModem, serial, on);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::getModemStackStatus(int32_t serial) {
+    MAYBE_WRAP_V1_3_CALL(getModemStackStatus, serial);
+
+    // TODO implement
+    return Void();
+}
+
+hidl_string getProtocolStringFromInt(const V1_4::PdpProtocolType protocol){
+    const hidl_string protocolStrings[] = {hidl_string("IP"), hidl_string("IPV6"), hidl_string("IPV4V6"), hidl_string("PPP"),
+        hidl_string("NON-IP"), hidl_string("UNSTRUCTURED")};
+
+    if(protocol >= V1_4::PdpProtocolType::IP && protocol <= V1_4::PdpProtocolType::UNSTRUCTURED)
+        return protocolStrings[(int)protocol];
+
+    return hidl_string("");
+}
+
+V1_0::DataProfileInfo Get1_0DataProfileInfo(const V1_4::DataProfileInfo& dataProfileInfo){
+    V1_0::DataProfileInfo legacyProfile = {};
+    legacyProfile.profileId = dataProfileInfo.profileId;
+    legacyProfile.apn = dataProfileInfo.apn;
+    legacyProfile.protocol = getProtocolStringFromInt(dataProfileInfo.protocol);
+    legacyProfile.roamingProtocol = getProtocolStringFromInt(dataProfileInfo.roamingProtocol);
+    legacyProfile.authType = dataProfileInfo.authType;
+    legacyProfile.user = dataProfileInfo.user;
+    legacyProfile.password = dataProfileInfo.password;
+    legacyProfile.type = dataProfileInfo.type;
+    legacyProfile.maxConnsTime = dataProfileInfo.maxConnsTime;
+    legacyProfile.maxConns = dataProfileInfo.maxConns;
+    legacyProfile.waitTime = dataProfileInfo.waitTime;
+    legacyProfile.enabled = dataProfileInfo.enabled;
+    legacyProfile.supportedApnTypesBitmap = dataProfileInfo.supportedApnTypesBitmap;
+    legacyProfile.bearerBitmap = dataProfileInfo.bearerBitmap;
+    legacyProfile.mtu = dataProfileInfo.mtu;
+    legacyProfile.mvnoType = V1_0::MvnoType::NONE;
+
+    return legacyProfile;
+}
+
+// Methods from ::android::hardware::radio::V1_4::IRadio follow.
+Return<void> Radio::setupDataCall_1_4(int32_t serial, V1_4::AccessNetwork accessNetwork,
+                                      const V1_4::DataProfileInfo& dataProfileInfo,
+                                      bool roamingAllowed, V1_2::DataRequestReason reason,
+                                      const hidl_vec<hidl_string>& addresses,
+                                      const hidl_vec<hidl_string>& dnses) {
+    MAYBE_WRAP_V1_4_CALL(setupDataCall_1_4, serial, accessNetwork, dataProfileInfo, roamingAllowed,
+                         reason, addresses, dnses);
+
+    MAYBE_WRAP_V1_2_CALL(setupDataCall_1_2, serial, (V1_2::AccessNetwork) accessNetwork, Get1_0DataProfileInfo(dataProfileInfo),
+                         dataProfileInfo.persistent, roamingAllowed, mRadioResponse->mDataRoaming, reason, addresses, dnses);
+
+    WRAP_V1_0_CALL(setupDataCall, serial, mRadioResponse->mRat, Get1_0DataProfileInfo(dataProfileInfo),
+                         dataProfileInfo.persistent, roamingAllowed, mRadioResponse->mDataRoaming);
+}
+
+Return<void> Radio::setInitialAttachApn_1_4(int32_t serial,
+                                            const V1_4::DataProfileInfo& dataProfileInfo) {
+    MAYBE_WRAP_V1_4_CALL(setInitialAttachApn_1_4, serial, dataProfileInfo);
+
+    WRAP_V1_0_CALL(setInitialAttachApn, serial, Get1_0DataProfileInfo(dataProfileInfo),
+                         dataProfileInfo.persistent, mRadioResponse->mDataRoaming);
+}
+
+Return<void> Radio::setDataProfile_1_4(int32_t serial,
+                                       const hidl_vec<V1_4::DataProfileInfo>& profiles) {
+    MAYBE_WRAP_V1_4_CALL(setDataProfile_1_4, serial, profiles);
+
+    std::vector<V1_0::DataProfileInfo> legacyProfiles;
+    for(const V1_4::DataProfileInfo &profile : profiles){
+        if(profile.persistent)
+            legacyProfiles.push_back(Get1_0DataProfileInfo(profile));
+    }
+
+    if(legacyProfiles.size())
+        WRAP_V1_0_CALL(setDataProfile, serial, hidl_vec(legacyProfiles), mRadioResponse->mDataRoaming);
+
+    return Void();
+}
+
+Return<void> Radio::emergencyDial(int32_t serial, const V1_0::Dial& dialInfo,
+                                  hidl_bitfield<V1_4::EmergencyServiceCategory> categories,
+                                  const hidl_vec<hidl_string>& urns,
+                                  V1_4::EmergencyCallRouting routing,
+                                  bool hasKnownUserIntentEmergency, bool isTesting) {
+    MAYBE_WRAP_V1_4_CALL(emergencyDial, serial, dialInfo, categories, urns, routing,
+                         hasKnownUserIntentEmergency, isTesting);
+
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::startNetworkScan_1_4(int32_t serial, const V1_2::NetworkScanRequest& request) {
+    MAYBE_WRAP_V1_4_CALL(startNetworkScan_1_4, serial, request);
+    MAYBE_WRAP_V1_2_CALL(startNetworkScan_1_2, serial, request);
+
+    V1_1::NetworkScanRequest legacyRequest = {};
+    legacyRequest.type = request.type;
+    legacyRequest.interval = request.interval;
+    legacyRequest.specifiers = request.specifiers;
+
+    MAYBE_WRAP_V1_1_CALL(startNetworkScan, serial, legacyRequest);
+    // TODO implement
+    return Void();
+}
+
+Return<void> Radio::getPreferredNetworkTypeBitmap(int32_t serial) {
+    MAYBE_WRAP_V1_4_CALL(getPreferredNetworkTypeBitmap, serial);
+
+    WRAP_V1_0_CALL(getPreferredNetworkType, serial);
+}
+
+Return<void> Radio::setPreferredNetworkTypeBitmap(
+        int32_t serial, hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) {
+    MAYBE_WRAP_V1_4_CALL(setPreferredNetworkTypeBitmap, serial, networkTypeBitmap);
+
+    if(networkTypeBitmap & GSMBITS)
+        networkTypeBitmap |= GSMBITS;
+    if(networkTypeBitmap & CDMABITS)
+        networkTypeBitmap |= CDMABITS;
+    if(networkTypeBitmap & EVDOBITS)
+        networkTypeBitmap |= EVDOBITS;
+    if(networkTypeBitmap & WCDMABITS)
+        networkTypeBitmap |= WCDMABITS;
+    if(networkTypeBitmap & LTEBITS)
+        networkTypeBitmap |= LTEBITS;
+
+    V1_0::PreferredNetworkType nwType;
+    switch(networkTypeBitmap){
+        case (GSMBITS | WCDMABITS):
+            nwType = V1_0::PreferredNetworkType::GSM_WCDMA_AUTO;
+            break;
+        case GSMBITS:
+            nwType = V1_0::PreferredNetworkType::GSM_ONLY;
+            break;
+        case WCDMABITS:
+            nwType = V1_0::PreferredNetworkType::WCDMA;
+            break;
+        case (CDMABITS | EVDOBITS):
+            nwType = V1_0::PreferredNetworkType::CDMA_EVDO_AUTO;
+            break;
+        case CDMABITS:
+            nwType = V1_0::PreferredNetworkType::CDMA_ONLY;
+            break;
+        case EVDOBITS:
+            nwType = V1_0::PreferredNetworkType::EVDO_ONLY;
+            break;
+        case (GSMBITS | WCDMABITS | CDMABITS | EVDOBITS):
+            nwType = V1_0::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO;
+            break;
+        case (LTEBITS | CDMABITS | EVDOBITS):
+            nwType = V1_0::PreferredNetworkType::LTE_CDMA_EVDO;
+            break;
+        case (LTEBITS | GSMBITS | WCDMABITS):
+            nwType = V1_0::PreferredNetworkType::LTE_GSM_WCDMA;
+            break;
+        case (LTEBITS | CDMABITS | EVDOBITS | GSMBITS | WCDMABITS):
+            nwType = V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA;
+            break;
+        case LTEBITS:
+            nwType = V1_0::PreferredNetworkType::LTE_ONLY;
+            break;
+        case (LTEBITS | WCDMABITS):
+            nwType = V1_0::PreferredNetworkType::LTE_WCDMA;
+            break;
+        case TDSCDMABIT:
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_ONLY;
+            break;
+        case (TDSCDMABIT | WCDMABITS):
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_WCDMA;
+            break;
+        case (TDSCDMABIT | LTEBITS):
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_LTE;
+            break;
+        case (TDSCDMABIT | GSMBITS):
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_GSM;
+            break;
+        case (TDSCDMABIT | GSMBITS | LTEBITS):
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_GSM_LTE;
+            break;
+        case (TDSCDMABIT | GSMBITS | WCDMABITS):
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA;
+            break;
+        case (TDSCDMABIT | WCDMABITS | LTEBITS):
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_WCDMA_LTE;
+            break;
+        case (TDSCDMABIT | GSMBITS | WCDMABITS | LTEBITS):
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE;
+            break;
+        case (TDSCDMABIT | GSMBITS | WCDMABITS | CDMABITS | EVDOBITS):
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO;
+            break;
+        case (TDSCDMABIT | LTEBITS | CDMABITS | EVDOBITS | GSMBITS | WCDMABITS):
+            nwType = V1_0::PreferredNetworkType::TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA;
+            break;
+        default:
+            nwType = V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA;
+    }
+    WRAP_V1_0_CALL(setPreferredNetworkType, serial, nwType);
+}
+
+Return<void> Radio::setAllowedCarriers_1_4(int32_t serial,
+                                           const V1_4::CarrierRestrictionsWithPriority& carriers,
+                                           V1_4::SimLockMultiSimPolicy multiSimPolicy) {
+    MAYBE_WRAP_V1_4_CALL(setAllowedCarriers_1_4, serial, carriers, multiSimPolicy);
+
+    bool isAllCarriersAllowed = carriers.allowedCarriers.size() == 0 &&
+        carriers.excludedCarriers.size() == 0 && !carriers.allowedCarriersPrioritized;
+
+    bool supported = (isAllCarriersAllowed
+        || (carriers.excludedCarriers.size() == 0
+        && carriers.allowedCarriersPrioritized))
+        && multiSimPolicy == V1_4::SimLockMultiSimPolicy::NO_MULTISIM_POLICY;
+
+    if(supported){
+        V1_0::CarrierRestrictions legacyCarriers = {};
+        legacyCarriers.allowedCarriers = carriers.allowedCarriers;
+        WRAP_V1_0_CALL(setAllowedCarriers, serial, isAllCarriersAllowed, legacyCarriers);
+    }
+
+    return Void();
+}
+
+Return<void> Radio::getAllowedCarriers_1_4(int32_t serial) {
+    MAYBE_WRAP_V1_4_CALL(getAllowedCarriers_1_4, serial);
+    WRAP_V1_0_CALL(getAllowedCarriers, serial);
+}
+
+Return<void> Radio::getSignalStrength_1_4(int32_t serial) {
+    MAYBE_WRAP_V1_4_CALL(getSignalStrength_1_4, serial);
+    WRAP_V1_0_CALL(getSignalStrength, serial);
+}
+
+sp<V1_1::IRadio> Radio::getRealRadio_V1_1() {
+    return V1_1::IRadio::castFrom(mRealRadio).withDefault(nullptr);
+}
+
+sp<V1_2::IRadio> Radio::getRealRadio_V1_2() {
+    return V1_2::IRadio::castFrom(mRealRadio).withDefault(nullptr);
+}
+
+sp<V1_3::IRadio> Radio::getRealRadio_V1_3() {
+    return V1_3::IRadio::castFrom(mRealRadio).withDefault(nullptr);
+}
+
+sp<V1_4::IRadio> Radio::getRealRadio_V1_4() {
+    return V1_4::IRadio::castFrom(mRealRadio).withDefault(nullptr);
+}
+
+}  // namespace android::hardware::radio::implementation
diff --git a/radio/1.4/legacy/Radio.h b/radio/1.4/legacy/Radio.h
new file mode 100644
index 0000000..f79096b
--- /dev/null
+++ b/radio/1.4/legacy/Radio.h
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <android/hardware/radio/1.4/IRadio.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include "RadioIndication.h"
+#include "RadioResponse.h"
+
+namespace android::hardware::radio::implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct Radio : public V1_4::IRadio {
+  public:
+    Radio(sp<V1_0::IRadio> realRadio);
+
+    // Methods from ::android::hardware::radio::V1_0::IRadio follow.
+    Return<void> setResponseFunctions(const sp<V1_0::IRadioResponse>& radioResponse,
+                                      const sp<V1_0::IRadioIndication>& radioIndication) override;
+    Return<void> getIccCardStatus(int32_t serial) override;
+    Return<void> supplyIccPinForApp(int32_t serial, const hidl_string& pin,
+                                    const hidl_string& aid) override;
+    Return<void> supplyIccPukForApp(int32_t serial, const hidl_string& puk, const hidl_string& pin,
+                                    const hidl_string& aid) override;
+    Return<void> supplyIccPin2ForApp(int32_t serial, const hidl_string& pin2,
+                                     const hidl_string& aid) override;
+    Return<void> supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2,
+                                     const hidl_string& pin2, const hidl_string& aid) override;
+    Return<void> changeIccPinForApp(int32_t serial, const hidl_string& oldPin,
+                                    const hidl_string& newPin, const hidl_string& aid) override;
+    Return<void> changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2,
+                                     const hidl_string& newPin2, const hidl_string& aid) override;
+    Return<void> supplyNetworkDepersonalization(int32_t serial, const hidl_string& netPin) override;
+    Return<void> getCurrentCalls(int32_t serial) override;
+    Return<void> dial(int32_t serial, const V1_0::Dial& dialInfo) override;
+    Return<void> getImsiForApp(int32_t serial, const hidl_string& aid) override;
+    Return<void> hangup(int32_t serial, int32_t gsmIndex) override;
+    Return<void> hangupWaitingOrBackground(int32_t serial) override;
+    Return<void> hangupForegroundResumeBackground(int32_t serial) override;
+    Return<void> switchWaitingOrHoldingAndActive(int32_t serial) override;
+    Return<void> conference(int32_t serial) override;
+    Return<void> rejectCall(int32_t serial) override;
+    Return<void> getLastCallFailCause(int32_t serial) override;
+    Return<void> getSignalStrength(int32_t serial) override;
+    Return<void> getVoiceRegistrationState(int32_t serial) override;
+    Return<void> getDataRegistrationState(int32_t serial) override;
+    Return<void> getOperator(int32_t serial) override;
+    Return<void> setRadioPower(int32_t serial, bool on) override;
+    Return<void> sendDtmf(int32_t serial, const hidl_string& s) override;
+    Return<void> sendSms(int32_t serial, const V1_0::GsmSmsMessage& message) override;
+    Return<void> sendSMSExpectMore(int32_t serial, const V1_0::GsmSmsMessage& message) override;
+    Return<void> setupDataCall(int32_t serial, V1_0::RadioTechnology radioTechnology,
+                               const V1_0::DataProfileInfo& dataProfileInfo, bool modemCognitive,
+                               bool roamingAllowed, bool isRoaming) override;
+    Return<void> iccIOForApp(int32_t serial, const V1_0::IccIo& iccIo) override;
+    Return<void> sendUssd(int32_t serial, const hidl_string& ussd) override;
+    Return<void> cancelPendingUssd(int32_t serial) override;
+    Return<void> getClir(int32_t serial) override;
+    Return<void> setClir(int32_t serial, int32_t status) override;
+    Return<void> getCallForwardStatus(int32_t serial,
+                                      const V1_0::CallForwardInfo& callInfo) override;
+    Return<void> setCallForward(int32_t serial, const V1_0::CallForwardInfo& callInfo) override;
+    Return<void> getCallWaiting(int32_t serial, int32_t serviceClass) override;
+    Return<void> setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) override;
+    Return<void> acknowledgeLastIncomingGsmSms(int32_t serial, bool success,
+                                               V1_0::SmsAcknowledgeFailCause cause) override;
+    Return<void> acceptCall(int32_t serial) override;
+    Return<void> deactivateDataCall(int32_t serial, int32_t cid, bool reasonRadioShutDown) override;
+    Return<void> getFacilityLockForApp(int32_t serial, const hidl_string& facility,
+                                       const hidl_string& password, int32_t serviceClass,
+                                       const hidl_string& appId) override;
+    Return<void> setFacilityLockForApp(int32_t serial, const hidl_string& facility, bool lockState,
+                                       const hidl_string& password, int32_t serviceClass,
+                                       const hidl_string& appId) override;
+    Return<void> setBarringPassword(int32_t serial, const hidl_string& facility,
+                                    const hidl_string& oldPassword,
+                                    const hidl_string& newPassword) override;
+    Return<void> getNetworkSelectionMode(int32_t serial) override;
+    Return<void> setNetworkSelectionModeAutomatic(int32_t serial) override;
+    Return<void> setNetworkSelectionModeManual(int32_t serial,
+                                               const hidl_string& operatorNumeric) override;
+    Return<void> getAvailableNetworks(int32_t serial) override;
+    Return<void> startDtmf(int32_t serial, const hidl_string& s) override;
+    Return<void> stopDtmf(int32_t serial) override;
+    Return<void> getBasebandVersion(int32_t serial) override;
+    Return<void> separateConnection(int32_t serial, int32_t gsmIndex) override;
+    Return<void> setMute(int32_t serial, bool enable) override;
+    Return<void> getMute(int32_t serial) override;
+    Return<void> getClip(int32_t serial) override;
+    Return<void> getDataCallList(int32_t serial) override;
+    Return<void> setSuppServiceNotifications(int32_t serial, bool enable) override;
+    Return<void> writeSmsToSim(int32_t serial, const V1_0::SmsWriteArgs& smsWriteArgs) override;
+    Return<void> deleteSmsOnSim(int32_t serial, int32_t index) override;
+    Return<void> setBandMode(int32_t serial, V1_0::RadioBandMode mode) override;
+    Return<void> getAvailableBandModes(int32_t serial) override;
+    Return<void> sendEnvelope(int32_t serial, const hidl_string& command) override;
+    Return<void> sendTerminalResponseToSim(int32_t serial,
+                                           const hidl_string& commandResponse) override;
+    Return<void> handleStkCallSetupRequestFromSim(int32_t serial, bool accept) override;
+    Return<void> explicitCallTransfer(int32_t serial) override;
+    Return<void> setPreferredNetworkType(int32_t serial,
+                                         V1_0::PreferredNetworkType nwType) override;
+    Return<void> getPreferredNetworkType(int32_t serial) override;
+    Return<void> getNeighboringCids(int32_t serial) override;
+    Return<void> setLocationUpdates(int32_t serial, bool enable) override;
+    Return<void> setCdmaSubscriptionSource(int32_t serial,
+                                           V1_0::CdmaSubscriptionSource cdmaSub) override;
+    Return<void> setCdmaRoamingPreference(int32_t serial, V1_0::CdmaRoamingType type) override;
+    Return<void> getCdmaRoamingPreference(int32_t serial) override;
+    Return<void> setTTYMode(int32_t serial, V1_0::TtyMode mode) override;
+    Return<void> getTTYMode(int32_t serial) override;
+    Return<void> setPreferredVoicePrivacy(int32_t serial, bool enable) override;
+    Return<void> getPreferredVoicePrivacy(int32_t serial) override;
+    Return<void> sendCDMAFeatureCode(int32_t serial, const hidl_string& featureCode) override;
+    Return<void> sendBurstDtmf(int32_t serial, const hidl_string& dtmf, int32_t on,
+                               int32_t off) override;
+    Return<void> sendCdmaSms(int32_t serial, const V1_0::CdmaSmsMessage& sms) override;
+    Return<void> acknowledgeLastIncomingCdmaSms(int32_t serial,
+                                                const V1_0::CdmaSmsAck& smsAck) override;
+    Return<void> getGsmBroadcastConfig(int32_t serial) override;
+    Return<void> setGsmBroadcastConfig(
+            int32_t serial, const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& configInfo) override;
+    Return<void> setGsmBroadcastActivation(int32_t serial, bool activate) override;
+    Return<void> getCdmaBroadcastConfig(int32_t serial) override;
+    Return<void> setCdmaBroadcastConfig(
+            int32_t serial, const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configInfo) override;
+    Return<void> setCdmaBroadcastActivation(int32_t serial, bool activate) override;
+    Return<void> getCDMASubscription(int32_t serial) override;
+    Return<void> writeSmsToRuim(int32_t serial, const V1_0::CdmaSmsWriteArgs& cdmaSms) override;
+    Return<void> deleteSmsOnRuim(int32_t serial, int32_t index) override;
+    Return<void> getDeviceIdentity(int32_t serial) override;
+    Return<void> exitEmergencyCallbackMode(int32_t serial) override;
+    Return<void> getSmscAddress(int32_t serial) override;
+    Return<void> setSmscAddress(int32_t serial, const hidl_string& smsc) override;
+    Return<void> reportSmsMemoryStatus(int32_t serial, bool available) override;
+    Return<void> reportStkServiceIsRunning(int32_t serial) override;
+    Return<void> getCdmaSubscriptionSource(int32_t serial) override;
+    Return<void> requestIsimAuthentication(int32_t serial, const hidl_string& challenge) override;
+    Return<void> acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success,
+                                                  const hidl_string& ackPdu) override;
+    Return<void> sendEnvelopeWithStatus(int32_t serial, const hidl_string& contents) override;
+    Return<void> getVoiceRadioTechnology(int32_t serial) override;
+    Return<void> getCellInfoList(int32_t serial) override;
+    Return<void> setCellInfoListRate(int32_t serial, int32_t rate) override;
+    Return<void> setInitialAttachApn(int32_t serial, const V1_0::DataProfileInfo& dataProfileInfo,
+                                     bool modemCognitive, bool isRoaming) override;
+    Return<void> getImsRegistrationState(int32_t serial) override;
+    Return<void> sendImsSms(int32_t serial, const V1_0::ImsSmsMessage& message) override;
+    Return<void> iccTransmitApduBasicChannel(int32_t serial, const V1_0::SimApdu& message) override;
+    Return<void> iccOpenLogicalChannel(int32_t serial, const hidl_string& aid, int32_t p2) override;
+    Return<void> iccCloseLogicalChannel(int32_t serial, int32_t channelId) override;
+    Return<void> iccTransmitApduLogicalChannel(int32_t serial,
+                                               const V1_0::SimApdu& message) override;
+    Return<void> nvReadItem(int32_t serial, V1_0::NvItem itemId) override;
+    Return<void> nvWriteItem(int32_t serial, const V1_0::NvWriteItem& item) override;
+    Return<void> nvWriteCdmaPrl(int32_t serial, const hidl_vec<uint8_t>& prl) override;
+    Return<void> nvResetConfig(int32_t serial, V1_0::ResetNvType resetType) override;
+    Return<void> setUiccSubscription(int32_t serial, const V1_0::SelectUiccSub& uiccSub) override;
+    Return<void> setDataAllowed(int32_t serial, bool allow) override;
+    Return<void> getHardwareConfig(int32_t serial) override;
+    Return<void> requestIccSimAuthentication(int32_t serial, int32_t authContext,
+                                             const hidl_string& authData,
+                                             const hidl_string& aid) override;
+    Return<void> setDataProfile(int32_t serial, const hidl_vec<V1_0::DataProfileInfo>& profiles,
+                                bool isRoaming) override;
+    Return<void> requestShutdown(int32_t serial) override;
+    Return<void> getRadioCapability(int32_t serial) override;
+    Return<void> setRadioCapability(int32_t serial, const V1_0::RadioCapability& rc) override;
+    Return<void> startLceService(int32_t serial, int32_t reportInterval, bool pullMode) override;
+    Return<void> stopLceService(int32_t serial) override;
+    Return<void> pullLceData(int32_t serial) override;
+    Return<void> getModemActivityInfo(int32_t serial) override;
+    Return<void> setAllowedCarriers(int32_t serial, bool allAllowed,
+                                    const V1_0::CarrierRestrictions& carriers) override;
+    Return<void> getAllowedCarriers(int32_t serial) override;
+    Return<void> sendDeviceState(int32_t serial, V1_0::DeviceStateType deviceStateType,
+                                 bool state) override;
+    Return<void> setIndicationFilter(
+            int32_t serial, hidl_bitfield<V1_0::IndicationFilter> indicationFilter) override;
+    Return<void> setSimCardPower(int32_t serial, bool powerUp) override;
+    Return<void> responseAcknowledgement() override;
+
+    // Methods from ::android::hardware::radio::V1_1::IRadio follow.
+    Return<void> setCarrierInfoForImsiEncryption(
+            int32_t serial, const V1_1::ImsiEncryptionInfo& imsiEncryptionInfo) override;
+    Return<void> setSimCardPower_1_1(int32_t serial, V1_1::CardPowerState powerUp) override;
+    Return<void> startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request) override;
+    Return<void> stopNetworkScan(int32_t serial) override;
+    Return<void> startKeepalive(int32_t serial, const V1_1::KeepaliveRequest& keepalive) override;
+    Return<void> stopKeepalive(int32_t serial, int32_t sessionHandle) override;
+
+    // Methods from ::android::hardware::radio::V1_2::IRadio follow.
+    Return<void> startNetworkScan_1_2(int32_t serial,
+                                      const V1_2::NetworkScanRequest& request) override;
+    Return<void> setIndicationFilter_1_2(
+            int32_t serial, hidl_bitfield<V1_2::IndicationFilter> indicationFilter) override;
+    Return<void> setSignalStrengthReportingCriteria(int32_t serial, int32_t hysteresisMs,
+                                                    int32_t hysteresisDb,
+                                                    const hidl_vec<int32_t>& thresholdsDbm,
+                                                    V1_2::AccessNetwork accessNetwork) override;
+    Return<void> setLinkCapacityReportingCriteria(int32_t serial, int32_t hysteresisMs,
+                                                  int32_t hysteresisDlKbps,
+                                                  int32_t hysteresisUlKbps,
+                                                  const hidl_vec<int32_t>& thresholdsDownlinkKbps,
+                                                  const hidl_vec<int32_t>& thresholdsUplinkKbps,
+                                                  V1_2::AccessNetwork accessNetwork) override;
+    Return<void> setupDataCall_1_2(int32_t serial, V1_2::AccessNetwork accessNetwork,
+                                   const V1_0::DataProfileInfo& dataProfileInfo,
+                                   bool modemCognitive, bool roamingAllowed, bool isRoaming,
+                                   V1_2::DataRequestReason reason,
+                                   const hidl_vec<hidl_string>& addresses,
+                                   const hidl_vec<hidl_string>& dnses) override;
+    Return<void> deactivateDataCall_1_2(int32_t serial, int32_t cid,
+                                        V1_2::DataRequestReason reason) override;
+
+    // Methods from ::android::hardware::radio::V1_3::IRadio follow.
+    Return<void> setSystemSelectionChannels(
+            int32_t serial, bool specifyChannels,
+            const hidl_vec<V1_1::RadioAccessSpecifier>& specifiers) override;
+    Return<void> enableModem(int32_t serial, bool on) override;
+    Return<void> getModemStackStatus(int32_t serial) override;
+
+    // Methods from ::android::hardware::radio::V1_4::IRadio follow.
+    Return<void> setupDataCall_1_4(int32_t serial, V1_4::AccessNetwork accessNetwork,
+                                   const V1_4::DataProfileInfo& dataProfileInfo,
+                                   bool roamingAllowed, V1_2::DataRequestReason reason,
+                                   const hidl_vec<hidl_string>& addresses,
+                                   const hidl_vec<hidl_string>& dnses) override;
+    Return<void> setInitialAttachApn_1_4(int32_t serial,
+                                         const V1_4::DataProfileInfo& dataProfileInfo) override;
+    Return<void> setDataProfile_1_4(int32_t serial,
+                                    const hidl_vec<V1_4::DataProfileInfo>& profiles) override;
+    Return<void> emergencyDial(int32_t serial, const V1_0::Dial& dialInfo,
+                               hidl_bitfield<V1_4::EmergencyServiceCategory> categories,
+                               const hidl_vec<hidl_string>& urns,
+                               V1_4::EmergencyCallRouting routing, bool hasKnownUserIntentEmergency,
+                               bool isTesting) override;
+    Return<void> startNetworkScan_1_4(int32_t serial,
+                                      const V1_2::NetworkScanRequest& request) override;
+    Return<void> getPreferredNetworkTypeBitmap(int32_t serial) override;
+    Return<void> setPreferredNetworkTypeBitmap(
+            int32_t serial, hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) override;
+    Return<void> setAllowedCarriers_1_4(int32_t serial,
+                                        const V1_4::CarrierRestrictionsWithPriority& carriers,
+                                        V1_4::SimLockMultiSimPolicy multiSimPolicy) override;
+    Return<void> getAllowedCarriers_1_4(int32_t serial) override;
+    Return<void> getSignalStrength_1_4(int32_t serial) override;
+
+  private:
+    sp<V1_0::IRadio> mRealRadio;
+    sp<RadioResponse> mRadioResponse = new RadioResponse();
+    sp<RadioIndication> mRadioIndication = new RadioIndication();
+
+    sp<V1_1::IRadio> getRealRadio_V1_1();
+    sp<V1_2::IRadio> getRealRadio_V1_2();
+    sp<V1_3::IRadio> getRealRadio_V1_3();
+    sp<V1_4::IRadio> getRealRadio_V1_4();
+};
+
+}  // namespace android::hardware::radio::implementation
diff --git a/radio/1.4/legacy/RadioIndication.cpp b/radio/1.4/legacy/RadioIndication.cpp
new file mode 100644
index 0000000..202b180
--- /dev/null
+++ b/radio/1.4/legacy/RadioIndication.cpp
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "RadioIndication.h"
+#include "Helpers.h"
+
+namespace android::hardware::radio::implementation {
+
+// Methods from ::android::hardware::radio::V1_0::IRadioIndication follow.
+Return<void> RadioIndication::radioStateChanged(V1_0::RadioIndicationType type,
+                                                V1_0::RadioState radioState) {
+    return mRealRadioIndication->radioStateChanged(type, radioState);
+}
+
+Return<void> RadioIndication::callStateChanged(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->callStateChanged(type);
+}
+
+Return<void> RadioIndication::networkStateChanged(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->networkStateChanged(type);
+}
+
+Return<void> RadioIndication::newSms(V1_0::RadioIndicationType type, const hidl_vec<uint8_t>& pdu) {
+    return mRealRadioIndication->newSms(type, pdu);
+}
+
+Return<void> RadioIndication::newSmsStatusReport(V1_0::RadioIndicationType type,
+                                                 const hidl_vec<uint8_t>& pdu) {
+    return mRealRadioIndication->newSmsStatusReport(type, pdu);
+}
+
+Return<void> RadioIndication::newSmsOnSim(V1_0::RadioIndicationType type, int32_t recordNumber) {
+    return mRealRadioIndication->newSmsOnSim(type, recordNumber);
+}
+
+Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
+                                     const hidl_string& msg) {
+    return mRealRadioIndication->onUssd(type, modeType, msg);
+}
+
+Return<void> RadioIndication::nitzTimeReceived(V1_0::RadioIndicationType type,
+                                               const hidl_string& nitzTime, uint64_t receivedTime) {
+    return mRealRadioIndication->nitzTimeReceived(type, nitzTime, receivedTime);
+}
+
+Return<void> RadioIndication::currentSignalStrength(V1_0::RadioIndicationType type,
+                                                    const V1_0::SignalStrength& signalStrength) {
+    return mRealRadioIndication->currentSignalStrength_1_4(type, Create1_4SignalStrength(signalStrength));
+}
+
+Return<void> RadioIndication::dataCallListChanged(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_0::SetupDataCallResult>& dcList) {
+    hidl_vec<V1_4::SetupDataCallResult> newDcList;
+    newDcList.resize(dcList.size());
+    for(int x = 0; x < dcList.size(); ++x)
+        newDcList[x] = Create1_4SetupDataCallResult(dcList[x]);
+    return mRealRadioIndication->dataCallListChanged_1_4(type, newDcList);
+}
+
+Return<void> RadioIndication::suppSvcNotify(V1_0::RadioIndicationType type,
+                                            const V1_0::SuppSvcNotification& suppSvc) {
+    return mRealRadioIndication->suppSvcNotify(type, suppSvc);
+}
+
+Return<void> RadioIndication::stkSessionEnd(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->stkSessionEnd(type);
+}
+
+Return<void> RadioIndication::stkProactiveCommand(V1_0::RadioIndicationType type,
+                                                  const hidl_string& cmd) {
+    return mRealRadioIndication->stkProactiveCommand(type, cmd);
+}
+
+Return<void> RadioIndication::stkEventNotify(V1_0::RadioIndicationType type,
+                                             const hidl_string& cmd) {
+    return mRealRadioIndication->stkEventNotify(type, cmd);
+}
+
+Return<void> RadioIndication::stkCallSetup(V1_0::RadioIndicationType type, int64_t timeout) {
+    return mRealRadioIndication->stkCallSetup(type, timeout);
+}
+
+Return<void> RadioIndication::simSmsStorageFull(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->simSmsStorageFull(type);
+}
+
+Return<void> RadioIndication::simRefresh(V1_0::RadioIndicationType type,
+                                         const V1_0::SimRefreshResult& refreshResult) {
+    return mRealRadioIndication->simRefresh(type, refreshResult);
+}
+
+Return<void> RadioIndication::callRing(V1_0::RadioIndicationType type, bool isGsm,
+                                       const V1_0::CdmaSignalInfoRecord& record) {
+    return mRealRadioIndication->callRing(type, isGsm, record);
+}
+
+Return<void> RadioIndication::simStatusChanged(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->simStatusChanged(type);
+}
+
+Return<void> RadioIndication::cdmaNewSms(V1_0::RadioIndicationType type,
+                                         const V1_0::CdmaSmsMessage& msg) {
+    return mRealRadioIndication->cdmaNewSms(type, msg);
+}
+
+Return<void> RadioIndication::newBroadcastSms(V1_0::RadioIndicationType type,
+                                              const hidl_vec<uint8_t>& data) {
+    return mRealRadioIndication->newBroadcastSms(type, data);
+}
+
+Return<void> RadioIndication::cdmaRuimSmsStorageFull(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->cdmaRuimSmsStorageFull(type);
+}
+
+Return<void> RadioIndication::restrictedStateChanged(V1_0::RadioIndicationType type,
+                                                     V1_0::PhoneRestrictedState state) {
+    return mRealRadioIndication->restrictedStateChanged(type, state);
+}
+
+Return<void> RadioIndication::enterEmergencyCallbackMode(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->enterEmergencyCallbackMode(type);
+}
+
+Return<void> RadioIndication::cdmaCallWaiting(V1_0::RadioIndicationType type,
+                                              const V1_0::CdmaCallWaiting& callWaitingRecord) {
+    return mRealRadioIndication->cdmaCallWaiting(type, callWaitingRecord);
+}
+
+Return<void> RadioIndication::cdmaOtaProvisionStatus(V1_0::RadioIndicationType type,
+                                                     V1_0::CdmaOtaProvisionStatus status) {
+    return mRealRadioIndication->cdmaOtaProvisionStatus(type, status);
+}
+
+Return<void> RadioIndication::cdmaInfoRec(V1_0::RadioIndicationType type,
+                                          const V1_0::CdmaInformationRecords& records) {
+    return mRealRadioIndication->cdmaInfoRec(type, records);
+}
+
+Return<void> RadioIndication::indicateRingbackTone(V1_0::RadioIndicationType type, bool start) {
+    return mRealRadioIndication->indicateRingbackTone(type, start);
+}
+
+Return<void> RadioIndication::resendIncallMute(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->resendIncallMute(type);
+}
+
+Return<void> RadioIndication::cdmaSubscriptionSourceChanged(
+        V1_0::RadioIndicationType type, V1_0::CdmaSubscriptionSource cdmaSource) {
+    return mRealRadioIndication->cdmaSubscriptionSourceChanged(type, cdmaSource);
+}
+
+Return<void> RadioIndication::cdmaPrlChanged(V1_0::RadioIndicationType type, int32_t version) {
+    return mRealRadioIndication->cdmaPrlChanged(type, version);
+}
+
+Return<void> RadioIndication::exitEmergencyCallbackMode(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->exitEmergencyCallbackMode(type);
+}
+
+Return<void> RadioIndication::rilConnected(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->rilConnected(type);
+}
+
+Return<void> RadioIndication::voiceRadioTechChanged(V1_0::RadioIndicationType type,
+                                                    V1_0::RadioTechnology rat) {
+    return mRealRadioIndication->voiceRadioTechChanged(type, rat);
+}
+
+Return<void> RadioIndication::cellInfoList(V1_0::RadioIndicationType type,
+                                           const hidl_vec<V1_0::CellInfo>& records) {
+    return mRealRadioIndication->cellInfoList_1_4(type, Create1_4CellInfoList(records));
+}
+
+Return<void> RadioIndication::imsNetworkStateChanged(V1_0::RadioIndicationType type) {
+    return mRealRadioIndication->imsNetworkStateChanged(type);
+}
+
+Return<void> RadioIndication::subscriptionStatusChanged(V1_0::RadioIndicationType type,
+                                                        bool activate) {
+    return mRealRadioIndication->subscriptionStatusChanged(type, activate);
+}
+
+Return<void> RadioIndication::srvccStateNotify(V1_0::RadioIndicationType type,
+                                               V1_0::SrvccState state) {
+    return mRealRadioIndication->srvccStateNotify(type, state);
+}
+
+Return<void> RadioIndication::hardwareConfigChanged(V1_0::RadioIndicationType type,
+                                                    const hidl_vec<V1_0::HardwareConfig>& configs) {
+    return mRealRadioIndication->hardwareConfigChanged(type, configs);
+}
+
+Return<void> RadioIndication::radioCapabilityIndication(V1_0::RadioIndicationType type,
+                                                        const V1_0::RadioCapability& rc) {
+    return mRealRadioIndication->radioCapabilityIndication(type, rc);
+}
+
+Return<void> RadioIndication::onSupplementaryServiceIndication(V1_0::RadioIndicationType type,
+                                                               const V1_0::StkCcUnsolSsResult& ss) {
+    return mRealRadioIndication->onSupplementaryServiceIndication(type, ss);
+}
+
+Return<void> RadioIndication::stkCallControlAlphaNotify(V1_0::RadioIndicationType type,
+                                                        const hidl_string& alpha) {
+    return mRealRadioIndication->stkCallControlAlphaNotify(type, alpha);
+}
+
+Return<void> RadioIndication::lceData(V1_0::RadioIndicationType type,
+                                      const V1_0::LceDataInfo& lce) {
+    return mRealRadioIndication->lceData(type, lce);
+}
+
+Return<void> RadioIndication::pcoData(V1_0::RadioIndicationType type,
+                                      const V1_0::PcoDataInfo& pco) {
+    return mRealRadioIndication->pcoData(type, pco);
+}
+
+Return<void> RadioIndication::modemReset(V1_0::RadioIndicationType type,
+                                         const hidl_string& reason) {
+    return mRealRadioIndication->modemReset(type, reason);
+}
+
+// Methods from ::android::hardware::radio::V1_1::IRadioIndication follow.
+Return<void> RadioIndication::carrierInfoForImsiEncryption(V1_0::RadioIndicationType info) {
+    return mRealRadioIndication->carrierInfoForImsiEncryption(info);
+}
+
+Return<void> RadioIndication::networkScanResult(V1_0::RadioIndicationType type,
+                                                const V1_1::NetworkScanResult& result) {
+    V1_4::NetworkScanResult newNSR = {};
+    newNSR.status = result.status;
+    newNSR.error = result.error;
+    newNSR.networkInfos = Create1_4CellInfoList(result.networkInfos);
+    return mRealRadioIndication->networkScanResult_1_4(type, newNSR);
+}
+
+Return<void> RadioIndication::keepaliveStatus(V1_0::RadioIndicationType type,
+                                              const V1_1::KeepaliveStatus& status) {
+    return mRealRadioIndication->keepaliveStatus(type, status);
+}
+
+// Methods from ::android::hardware::radio::V1_2::IRadioIndication follow.
+Return<void> RadioIndication::networkScanResult_1_2(V1_0::RadioIndicationType type,
+                                                    const V1_2::NetworkScanResult& result) {
+    V1_4::NetworkScanResult newNSR = {};
+    newNSR.status = result.status;
+    newNSR.error = result.error;
+    newNSR.networkInfos = Create1_4CellInfoList(result.networkInfos);
+    return mRealRadioIndication->networkScanResult_1_4(type, newNSR);
+}
+
+Return<void> RadioIndication::cellInfoList_1_2(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_2::CellInfo>& records) {
+    return mRealRadioIndication->cellInfoList_1_4(type, Create1_4CellInfoList(records));
+}
+
+Return<void> RadioIndication::currentLinkCapacityEstimate(V1_0::RadioIndicationType type,
+                                                          const V1_2::LinkCapacityEstimate& lce) {
+    return mRealRadioIndication->currentLinkCapacityEstimate(type, lce);
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_2::PhysicalChannelConfig>& configs) {
+    hidl_vec<V1_4::PhysicalChannelConfig> newConfigs;
+    newConfigs.resize(configs.size());
+    for(int x = 0; x < configs.size(); ++x){
+        newConfigs[x].base = configs[x];
+        newConfigs[x].rat = V1_4::RadioTechnology::UNKNOWN;
+        newConfigs[x].physicalCellId = -1;
+    }
+    return mRealRadioIndication->currentPhysicalChannelConfigs_1_4(type, newConfigs);
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_2(
+        V1_0::RadioIndicationType type, const V1_2::SignalStrength& signalStrength) {
+    return mRealRadioIndication->currentSignalStrength_1_4(type, Create1_4SignalStrength(signalStrength));
+}
+
+// Methods from ::android::hardware::radio::V1_4::IRadioIndication follow.
+Return<void> RadioIndication::currentEmergencyNumberList(
+        V1_0::RadioIndicationType type,
+        const hidl_vec<V1_4::EmergencyNumber>& emergencyNumberList) {
+    return mRealRadioIndication->currentEmergencyNumberList(type, emergencyNumberList);
+}
+
+Return<void> RadioIndication::cellInfoList_1_4(V1_0::RadioIndicationType type,
+                                               const hidl_vec<V1_4::CellInfo>& records) {
+    return mRealRadioIndication->cellInfoList_1_4(type, records);
+}
+
+Return<void> RadioIndication::networkScanResult_1_4(V1_0::RadioIndicationType type,
+                                                    const V1_4::NetworkScanResult& result) {
+    return mRealRadioIndication->networkScanResult_1_4(type, result);
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs_1_4(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_4::PhysicalChannelConfig>& configs) {
+    return mRealRadioIndication->currentPhysicalChannelConfigs_1_4(type, configs);
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_4(
+        V1_0::RadioIndicationType type, const hidl_vec<V1_4::SetupDataCallResult>& dcList) {
+    return mRealRadioIndication->dataCallListChanged_1_4(type, dcList);
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_4(
+        V1_0::RadioIndicationType type, const V1_4::SignalStrength& signalStrength) {
+    return mRealRadioIndication->currentSignalStrength_1_4(type, signalStrength);
+}
+
+}  // namespace android::hardware::radio::implementation
diff --git a/radio/1.4/legacy/RadioIndication.h b/radio/1.4/legacy/RadioIndication.h
new file mode 100644
index 0000000..41cc5e6
--- /dev/null
+++ b/radio/1.4/legacy/RadioIndication.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <android/hardware/radio/1.4/IRadioIndication.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android::hardware::radio::implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct RadioIndication : public V1_4::IRadioIndication {
+    sp<V1_4::IRadioIndication> mRealRadioIndication;
+    // Methods from ::android::hardware::radio::V1_0::IRadioIndication follow.
+    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;
+
+    // Methods from ::android::hardware::radio::V1_1::IRadioIndication follow.
+    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;
+
+    // Methods from ::android::hardware::radio::V1_2::IRadioIndication follow.
+    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;
+
+    // Methods from ::android::hardware::radio::V1_4::IRadioIndication follow.
+    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;
+};
+
+}  // namespace android::hardware::radio::implementation
diff --git a/radio/1.4/legacy/RadioResponse.cpp b/radio/1.4/legacy/RadioResponse.cpp
new file mode 100644
index 0000000..3190c9d
--- /dev/null
+++ b/radio/1.4/legacy/RadioResponse.cpp
@@ -0,0 +1,906 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "RadioResponse.h"
+#include "Helpers.h"
+#include<string>
+
+namespace android::hardware::radio::implementation {
+
+// Methods from ::android::hardware::radio::V1_0::IRadioResponse follow.
+Return<void> RadioResponse::getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                     const V1_0::CardStatus& cardStatus) {
+    V1_4::CardStatus newCS = {};
+    newCS.base.base = cardStatus;
+    newCS.base.physicalSlotId = -1;
+    newCS.base.iccid = hidl_string(" ");
+    return mRealRadioResponse->getIccCardStatusResponse_1_4(info, newCS);
+}
+
+Return<void> RadioResponse::supplyIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t remainingRetries) {
+    return mRealRadioResponse->supplyIccPinForAppResponse(info, remainingRetries);
+}
+
+Return<void> RadioResponse::supplyIccPukForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t remainingRetries) {
+    return mRealRadioResponse->supplyIccPukForAppResponse(info, remainingRetries);
+}
+
+Return<void> RadioResponse::supplyIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) {
+    return mRealRadioResponse->supplyIccPin2ForAppResponse(info, remainingRetries);
+}
+
+Return<void> RadioResponse::supplyIccPuk2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) {
+    return mRealRadioResponse->supplyIccPuk2ForAppResponse(info, remainingRetries);
+}
+
+Return<void> RadioResponse::changeIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t remainingRetries) {
+    return mRealRadioResponse->changeIccPinForAppResponse(info, remainingRetries);
+}
+
+Return<void> RadioResponse::changeIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                        int32_t remainingRetries) {
+    return mRealRadioResponse->changeIccPin2ForAppResponse(info, remainingRetries);
+}
+
+Return<void> RadioResponse::supplyNetworkDepersonalizationResponse(
+        const V1_0::RadioResponseInfo& info, int32_t remainingRetries) {
+    return mRealRadioResponse->supplyNetworkDepersonalizationResponse(info, remainingRetries);
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse(const V1_0::RadioResponseInfo& info,
+                                                    const hidl_vec<V1_0::Call>& calls) {
+    hidl_vec<V1_2::Call> newCalls;
+    newCalls.resize(calls.size());
+
+    for(int x = 0; x < calls.size(); ++x){
+        newCalls[x].base = calls[x];
+        newCalls[x].audioQuality = V1_2::AudioQuality::UNSPECIFIED;
+    }
+    return mRealRadioResponse->getCurrentCallsResponse_1_2(info, newCalls);
+}
+
+Return<void> RadioResponse::dialResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->dialResponse(info);
+}
+
+Return<void> RadioResponse::getIMSIForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                  const hidl_string& imsi) {
+    return mRealRadioResponse->getIMSIForAppResponse(info, imsi);
+}
+
+Return<void> RadioResponse::hangupConnectionResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->hangupConnectionResponse(info);
+}
+
+Return<void> RadioResponse::hangupWaitingOrBackgroundResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->hangupWaitingOrBackgroundResponse(info);
+}
+
+Return<void> RadioResponse::hangupForegroundResumeBackgroundResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->hangupForegroundResumeBackgroundResponse(info);
+}
+
+Return<void> RadioResponse::switchWaitingOrHoldingAndActiveResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->switchWaitingOrHoldingAndActiveResponse(info);
+}
+
+Return<void> RadioResponse::conferenceResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->conferenceResponse(info);
+}
+
+Return<void> RadioResponse::rejectCallResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->rejectCallResponse(info);
+}
+
+Return<void> RadioResponse::getLastCallFailCauseResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::LastCallFailCauseInfo& failCauseinfo) {
+    return mRealRadioResponse->getLastCallFailCauseResponse(info, failCauseinfo);
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse(const V1_0::RadioResponseInfo& info,
+                                                      const V1_0::SignalStrength& sigStrength) {
+    return mRealRadioResponse->getSignalStrengthResponse_1_4(info, Create1_4SignalStrength(sigStrength));
+}
+
+void Init1_2CellIdentity(const V1_0::CellIdentity& legacyCI, V1_2::CellIdentity& newCI) {
+    if(legacyCI.cellIdentityGsm.size() == 1){
+        newCI.cellIdentityGsm.resize(1);
+        newCI.cellIdentityGsm[0].base = legacyCI.cellIdentityGsm[0];
+    }
+    else if(legacyCI.cellIdentityCdma.size() == 1){
+        newCI.cellIdentityCdma.resize(1);
+        newCI.cellIdentityCdma[0].base = legacyCI.cellIdentityCdma[0];
+    }
+    else if(legacyCI.cellIdentityLte.size() == 1){
+        newCI.cellIdentityLte.resize(1);
+        newCI.cellIdentityLte[0].base = legacyCI.cellIdentityLte[0];
+        newCI.cellIdentityLte[0].bandwidth = INT_MAX;
+    }
+    else if(legacyCI.cellIdentityWcdma.size() == 1){
+        newCI.cellIdentityWcdma.resize(1);
+        newCI.cellIdentityWcdma[0].base = legacyCI.cellIdentityWcdma[0];
+    }
+    else if(legacyCI.cellIdentityTdscdma.size() == 1){
+        newCI.cellIdentityTdscdma.resize(1);
+        newCI.cellIdentityTdscdma[0].base = legacyCI.cellIdentityTdscdma[0];
+        newCI.cellIdentityTdscdma[0].uarfcn = INT_MAX;
+    }
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::VoiceRegStateResult& voiceRegResponse) {
+    V1_2::VoiceRegStateResult newVRR = {};
+    newVRR.regState = voiceRegResponse.regState;
+    newVRR.rat = voiceRegResponse.rat;
+    newVRR.cssSupported  = voiceRegResponse.cssSupported;
+    newVRR.roamingIndicator = voiceRegResponse.roamingIndicator;
+    newVRR.systemIsInPrl = voiceRegResponse.systemIsInPrl;
+    newVRR.defaultRoamingIndicator = voiceRegResponse.defaultRoamingIndicator;
+    newVRR.reasonForDenial = voiceRegResponse.reasonForDenial;
+    Init1_2CellIdentity(voiceRegResponse.cellIdentity, newVRR.cellIdentity);
+
+    return mRealRadioResponse->getVoiceRegistrationStateResponse_1_2(info, newVRR);
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::DataRegStateResult& dataRegResponse) {
+    mDataRoaming = (dataRegResponse.regState == V1_0::RegState::REG_ROAMING);
+    mRat = (V1_0::RadioTechnology) dataRegResponse.rat;
+
+    V1_4::DataRegStateResult newDRR = {};
+    newDRR.base.regState = dataRegResponse.regState;
+    newDRR.base.rat = dataRegResponse.rat;
+    newDRR.base.reasonDataDenied = dataRegResponse.reasonDataDenied;
+    newDRR.base.maxDataCalls = dataRegResponse.maxDataCalls;
+    Init1_2CellIdentity(dataRegResponse.cellIdentity, newDRR.base.cellIdentity);
+
+    return mRealRadioResponse->getDataRegistrationStateResponse_1_4(info, newDRR);
+}
+
+Return<void> RadioResponse::getOperatorResponse(const V1_0::RadioResponseInfo& info,
+                                                const hidl_string& longName,
+                                                const hidl_string& shortName,
+                                                const hidl_string& numeric) {
+    return mRealRadioResponse->getOperatorResponse(info, longName, shortName, numeric);
+}
+
+Return<void> RadioResponse::setRadioPowerResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setRadioPowerResponse(info);
+}
+
+Return<void> RadioResponse::sendDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->sendDtmfResponse(info);
+}
+
+Return<void> RadioResponse::sendSmsResponse(const V1_0::RadioResponseInfo& info,
+                                            const V1_0::SendSmsResult& sms) {
+    return mRealRadioResponse->sendSmsResponse(info, sms);
+}
+
+Return<void> RadioResponse::sendSMSExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+                                                      const V1_0::SendSmsResult& sms) {
+    return mRealRadioResponse->sendSMSExpectMoreResponse(info, sms);
+}
+
+Return<void> RadioResponse::setupDataCallResponse(const V1_0::RadioResponseInfo& info,
+                                                  const V1_0::SetupDataCallResult& dcResponse) {
+    return mRealRadioResponse->setupDataCallResponse_1_4(info, Create1_4SetupDataCallResult(dcResponse));
+}
+
+Return<void> RadioResponse::iccIOForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::IccIoResult& iccIo) {
+    return mRealRadioResponse->iccIOForAppResponse(info, iccIo);
+}
+
+Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->sendUssdResponse(info);
+}
+
+Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->cancelPendingUssdResponse(info);
+}
+
+Return<void> RadioResponse::getClirResponse(const V1_0::RadioResponseInfo& info, int32_t n,
+                                            int32_t m) {
+    return mRealRadioResponse->getClirResponse(info, n, m);
+}
+
+Return<void> RadioResponse::setClirResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setClirResponse(info);
+}
+
+Return<void> RadioResponse::getCallForwardStatusResponse(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<V1_0::CallForwardInfo>& callForwardInfos) {
+    return mRealRadioResponse->getCallForwardStatusResponse(info, callForwardInfos);
+}
+
+Return<void> RadioResponse::setCallForwardResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setCallForwardResponse(info);
+}
+
+Return<void> RadioResponse::getCallWaitingResponse(const V1_0::RadioResponseInfo& info, bool enable,
+                                                   int32_t serviceClass) {
+    return mRealRadioResponse->getCallWaitingResponse(info, enable, serviceClass);
+}
+
+Return<void> RadioResponse::setCallWaitingResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setCallWaitingResponse(info);
+}
+
+Return<void> RadioResponse::acknowledgeLastIncomingGsmSmsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->acknowledgeLastIncomingGsmSmsResponse(info);
+}
+
+Return<void> RadioResponse::acceptCallResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->acceptCallResponse(info);
+}
+
+Return<void> RadioResponse::deactivateDataCallResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->deactivateDataCallResponse(info);
+}
+
+Return<void> RadioResponse::getFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                          int32_t response) {
+    return mRealRadioResponse->getFacilityLockForAppResponse(info, response);
+}
+
+Return<void> RadioResponse::setFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+                                                          int32_t retry) {
+    return mRealRadioResponse->setFacilityLockForAppResponse(info, retry);
+}
+
+Return<void> RadioResponse::setBarringPasswordResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setBarringPasswordResponse(info);
+}
+
+Return<void> RadioResponse::getNetworkSelectionModeResponse(const V1_0::RadioResponseInfo& info,
+                                                            bool manual) {
+    return mRealRadioResponse->getNetworkSelectionModeResponse(info, manual);
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeAutomaticResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setNetworkSelectionModeAutomaticResponse(info);
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeManualResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setNetworkSelectionModeManualResponse(info);
+}
+
+Return<void> RadioResponse::getAvailableNetworksResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::OperatorInfo>& networkInfos) {
+    return mRealRadioResponse->getAvailableNetworksResponse(info, networkInfos);
+}
+
+Return<void> RadioResponse::startDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->startDtmfResponse(info);
+}
+
+Return<void> RadioResponse::stopDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->stopDtmfResponse(info);
+}
+
+Return<void> RadioResponse::getBasebandVersionResponse(const V1_0::RadioResponseInfo& info,
+                                                       const hidl_string& version) {
+    return mRealRadioResponse->getBasebandVersionResponse(info, version);
+}
+
+Return<void> RadioResponse::separateConnectionResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->separateConnectionResponse(info);
+}
+
+Return<void> RadioResponse::setMuteResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setMuteResponse(info);
+}
+
+Return<void> RadioResponse::getMuteResponse(const V1_0::RadioResponseInfo& info, bool enable) {
+    return mRealRadioResponse->getMuteResponse(info, enable);
+}
+
+Return<void> RadioResponse::getClipResponse(const V1_0::RadioResponseInfo& info,
+                                            V1_0::ClipStatus status) {
+    return mRealRadioResponse->getClipResponse(info, status);
+}
+
+Return<void> RadioResponse::getDataCallListResponse(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<V1_0::SetupDataCallResult>& dcResponse) {
+    hidl_vec<V1_4::SetupDataCallResult> newResponse;
+    newResponse.resize(dcResponse.size());
+
+    for(int x = 0; x < dcResponse.size(); ++x)
+        newResponse[x] = Create1_4SetupDataCallResult(dcResponse[x]);
+
+    return mRealRadioResponse->getDataCallListResponse_1_4(info, newResponse);
+}
+
+Return<void> RadioResponse::setSuppServiceNotificationsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setSuppServiceNotificationsResponse(info);
+}
+
+Return<void> RadioResponse::writeSmsToSimResponse(const V1_0::RadioResponseInfo& info,
+                                                  int32_t index) {
+    return mRealRadioResponse->writeSmsToSimResponse(info, index);
+}
+
+Return<void> RadioResponse::deleteSmsOnSimResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->deleteSmsOnSimResponse(info);
+}
+
+Return<void> RadioResponse::setBandModeResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setBandModeResponse(info);
+}
+
+Return<void> RadioResponse::getAvailableBandModesResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::RadioBandMode>& bandModes) {
+    return mRealRadioResponse->getAvailableBandModesResponse(info, bandModes);
+}
+
+Return<void> RadioResponse::sendEnvelopeResponse(const V1_0::RadioResponseInfo& info,
+                                                 const hidl_string& commandResponse) {
+    return mRealRadioResponse->sendEnvelopeResponse(info, commandResponse);
+}
+
+Return<void> RadioResponse::sendTerminalResponseToSimResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->sendTerminalResponseToSimResponse(info);
+}
+
+Return<void> RadioResponse::handleStkCallSetupRequestFromSimResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->handleStkCallSetupRequestFromSimResponse(info);
+}
+
+Return<void> RadioResponse::explicitCallTransferResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->explicitCallTransferResponse(info);
+}
+
+Return<void> RadioResponse::setPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setPreferredNetworkTypeBitmapResponse(info);
+}
+
+Return<void> RadioResponse::getPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info,
+                                                            V1_0::PreferredNetworkType nwType) {
+    hidl_bitfield<V1_4::RadioAccessFamily> nwTypeBitmap = 0;
+    switch(nwType){
+        case V1_0::PreferredNetworkType::GSM_WCDMA:
+        case V1_0::PreferredNetworkType::GSM_WCDMA_AUTO:
+            nwTypeBitmap = GSMBITS | WCDMABITS;
+        break;
+        case V1_0::PreferredNetworkType::GSM_ONLY:
+            nwTypeBitmap = GSMBITS;
+        break;
+        case V1_0::PreferredNetworkType::WCDMA:
+            nwTypeBitmap = WCDMABITS;
+        break;
+        case V1_0::PreferredNetworkType::CDMA_EVDO_AUTO:
+            nwTypeBitmap = CDMABITS | EVDOBITS;
+        break;
+        case V1_0::PreferredNetworkType::CDMA_ONLY:
+            nwTypeBitmap = CDMABITS;
+        break;
+        case V1_0::PreferredNetworkType::EVDO_ONLY:
+            nwTypeBitmap = EVDOBITS;
+        break;
+        case V1_0::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO:
+            nwTypeBitmap = GSMBITS | WCDMABITS | CDMABITS | EVDOBITS;
+        break;
+        case V1_0::PreferredNetworkType::LTE_CDMA_EVDO:
+            nwTypeBitmap = LTEBITS | CDMABITS | EVDOBITS;
+        break;
+        case V1_0::PreferredNetworkType::LTE_GSM_WCDMA:
+            nwTypeBitmap = LTEBITS | GSMBITS | WCDMABITS;
+        break;
+        case V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA:
+            nwTypeBitmap = LTEBITS | CDMABITS | EVDOBITS | GSMBITS | WCDMABITS;
+        break;
+        case V1_0::PreferredNetworkType::LTE_ONLY:
+            nwTypeBitmap = LTEBITS;
+        break;
+        case V1_0::PreferredNetworkType::LTE_WCDMA:
+            nwTypeBitmap = LTEBITS | WCDMABITS;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_ONLY:
+            nwTypeBitmap = TDSCDMABIT;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_WCDMA:
+            nwTypeBitmap = TDSCDMABIT | WCDMABITS;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_LTE:
+            nwTypeBitmap = TDSCDMABIT | LTEBITS;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM:
+            nwTypeBitmap = TDSCDMABIT | GSMBITS;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_LTE:
+            nwTypeBitmap = TDSCDMABIT | GSMBITS | LTEBITS;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA:
+            nwTypeBitmap = TDSCDMABIT | GSMBITS | WCDMABITS;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_WCDMA_LTE:
+            nwTypeBitmap = TDSCDMABIT | WCDMABITS | LTEBITS;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE:
+            nwTypeBitmap = TDSCDMABIT | GSMBITS | WCDMABITS | LTEBITS;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO:
+            nwTypeBitmap = TDSCDMABIT | GSMBITS | WCDMABITS | CDMABITS | EVDOBITS;
+        break;
+        case V1_0::PreferredNetworkType::TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA:
+            nwTypeBitmap = TDSCDMABIT | LTEBITS | CDMABITS | EVDOBITS | GSMBITS | WCDMABITS;
+        break;
+    }
+    return mRealRadioResponse->getPreferredNetworkTypeBitmapResponse(info, nwTypeBitmap);
+}
+
+Return<void> RadioResponse::getNeighboringCidsResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::NeighboringCell>& cells) {
+    return mRealRadioResponse->getNeighboringCidsResponse(info, cells);
+}
+
+Return<void> RadioResponse::setLocationUpdatesResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setLocationUpdatesResponse(info);
+}
+
+Return<void> RadioResponse::setCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setCdmaSubscriptionSourceResponse(info);
+}
+
+Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setCdmaRoamingPreferenceResponse(info);
+}
+
+Return<void> RadioResponse::getCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info,
+                                                             V1_0::CdmaRoamingType type) {
+    return mRealRadioResponse->getCdmaRoamingPreferenceResponse(info, type);
+}
+
+Return<void> RadioResponse::setTTYModeResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setTTYModeResponse(info);
+}
+
+Return<void> RadioResponse::getTTYModeResponse(const V1_0::RadioResponseInfo& info,
+                                               V1_0::TtyMode mode) {
+    return mRealRadioResponse->getTTYModeResponse(info, mode);
+}
+
+Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setPreferredVoicePrivacyResponse(info);
+}
+
+Return<void> RadioResponse::getPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info,
+                                                             bool enable) {
+    return mRealRadioResponse->getPreferredVoicePrivacyResponse(info, enable);
+}
+
+Return<void> RadioResponse::sendCDMAFeatureCodeResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->sendCDMAFeatureCodeResponse(info);
+}
+
+Return<void> RadioResponse::sendBurstDtmfResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->sendBurstDtmfResponse(info);
+}
+
+Return<void> RadioResponse::sendCdmaSmsResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::SendSmsResult& sms) {
+    return mRealRadioResponse->sendCdmaSmsResponse(info, sms);
+}
+
+Return<void> RadioResponse::acknowledgeLastIncomingCdmaSmsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->acknowledgeLastIncomingCdmaSmsResponse(info);
+}
+
+Return<void> RadioResponse::getGsmBroadcastConfigResponse(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& configs) {
+    return mRealRadioResponse->getGsmBroadcastConfigResponse(info, configs);
+}
+
+Return<void> RadioResponse::setGsmBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setGsmBroadcastConfigResponse(info);
+}
+
+Return<void> RadioResponse::setGsmBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setGsmBroadcastActivationResponse(info);
+}
+
+Return<void> RadioResponse::getCdmaBroadcastConfigResponse(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configs) {
+    return mRealRadioResponse->getCdmaBroadcastConfigResponse(info, configs);
+}
+
+Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setCdmaBroadcastConfigResponse(info);
+}
+
+Return<void> RadioResponse::setCdmaBroadcastActivationResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setCdmaBroadcastActivationResponse(info);
+}
+
+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) {
+    return mRealRadioResponse->getCDMASubscriptionResponse(info, mdn, hSid, hNid, min, prl);
+}
+
+Return<void> RadioResponse::writeSmsToRuimResponse(const V1_0::RadioResponseInfo& info,
+                                                   uint32_t index) {
+    return mRealRadioResponse->writeSmsToRuimResponse(info, index);
+}
+
+Return<void> RadioResponse::deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->deleteSmsOnRuimResponse(info);
+}
+
+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) {
+    return mRealRadioResponse->getDeviceIdentityResponse(info, imei, imeisv, esn, meid);
+}
+
+Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->exitEmergencyCallbackModeResponse(info);
+}
+
+Return<void> RadioResponse::getSmscAddressResponse(const V1_0::RadioResponseInfo& info,
+                                                   const hidl_string& smsc) {
+    return mRealRadioResponse->getSmscAddressResponse(info, smsc);
+}
+
+Return<void> RadioResponse::setSmscAddressResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setSmscAddressResponse(info);
+}
+
+Return<void> RadioResponse::reportSmsMemoryStatusResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->reportSmsMemoryStatusResponse(info);
+}
+
+Return<void> RadioResponse::reportStkServiceIsRunningResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->reportStkServiceIsRunningResponse(info);
+}
+
+Return<void> RadioResponse::getCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info,
+                                                              V1_0::CdmaSubscriptionSource source) {
+    return mRealRadioResponse->getCdmaSubscriptionSourceResponse(info, source);
+}
+
+Return<void> RadioResponse::requestIsimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                              const hidl_string& response) {
+    return mRealRadioResponse->requestIsimAuthenticationResponse(info, response);
+}
+
+Return<void> RadioResponse::acknowledgeIncomingGsmSmsWithPduResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->acknowledgeIncomingGsmSmsWithPduResponse(info);
+}
+
+Return<void> RadioResponse::sendEnvelopeWithStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                           const V1_0::IccIoResult& iccIo) {
+    return mRealRadioResponse->sendEnvelopeWithStatusResponse(info, iccIo);
+}
+
+Return<void> RadioResponse::getVoiceRadioTechnologyResponse(const V1_0::RadioResponseInfo& info,
+                                                            V1_0::RadioTechnology rat) {
+    return mRealRadioResponse->getVoiceRadioTechnologyResponse(info, rat);
+}
+
+Return<void> RadioResponse::getCellInfoListResponse(const V1_0::RadioResponseInfo& info,
+                                                    const hidl_vec<V1_0::CellInfo>& cellInfo) {
+    return mRealRadioResponse->getCellInfoListResponse_1_4(info, Create1_4CellInfoList(cellInfo));
+}
+
+Return<void> RadioResponse::setCellInfoListRateResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setCellInfoListRateResponse(info);
+}
+
+Return<void> RadioResponse::setInitialAttachApnResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setInitialAttachApnResponse(info);
+}
+
+Return<void> RadioResponse::getImsRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+                                                            bool isRegistered,
+                                                            V1_0::RadioTechnologyFamily ratFamily) {
+    return mRealRadioResponse->getImsRegistrationStateResponse(info, isRegistered, ratFamily);
+}
+
+Return<void> RadioResponse::sendImsSmsResponse(const V1_0::RadioResponseInfo& info,
+                                               const V1_0::SendSmsResult& sms) {
+    return mRealRadioResponse->sendImsSmsResponse(info, sms);
+}
+
+Return<void> RadioResponse::iccTransmitApduBasicChannelResponse(const V1_0::RadioResponseInfo& info,
+                                                                const V1_0::IccIoResult& result) {
+    return mRealRadioResponse->iccTransmitApduBasicChannelResponse(info, result);
+}
+
+Return<void> RadioResponse::iccOpenLogicalChannelResponse(const V1_0::RadioResponseInfo& info,
+                                                          int32_t channelId,
+                                                          const hidl_vec<int8_t>& selectResponse) {
+    return mRealRadioResponse->iccOpenLogicalChannelResponse(info, channelId, selectResponse);
+}
+
+Return<void> RadioResponse::iccCloseLogicalChannelResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->iccCloseLogicalChannelResponse(info);
+}
+
+Return<void> RadioResponse::iccTransmitApduLogicalChannelResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::IccIoResult& result) {
+    return mRealRadioResponse->iccTransmitApduLogicalChannelResponse(info, result);
+}
+
+Return<void> RadioResponse::nvReadItemResponse(const V1_0::RadioResponseInfo& info,
+                                               const hidl_string& result) {
+    return mRealRadioResponse->nvReadItemResponse(info, result);
+}
+
+Return<void> RadioResponse::nvWriteItemResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->nvWriteItemResponse(info);
+}
+
+Return<void> RadioResponse::nvWriteCdmaPrlResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->nvWriteCdmaPrlResponse(info);
+}
+
+Return<void> RadioResponse::nvResetConfigResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->nvResetConfigResponse(info);
+}
+
+Return<void> RadioResponse::setUiccSubscriptionResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setUiccSubscriptionResponse(info);
+}
+
+Return<void> RadioResponse::setDataAllowedResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setDataAllowedResponse(info);
+}
+
+Return<void> RadioResponse::getHardwareConfigResponse(
+        const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::HardwareConfig>& config) {
+    return mRealRadioResponse->getHardwareConfigResponse(info, config);
+}
+
+Return<void> RadioResponse::requestIccSimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+                                                                const V1_0::IccIoResult& result) {
+    return mRealRadioResponse->requestIccSimAuthenticationResponse(info, result);
+}
+
+Return<void> RadioResponse::setDataProfileResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setDataProfileResponse(info);
+}
+
+Return<void> RadioResponse::requestShutdownResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->requestShutdownResponse(info);
+}
+
+Return<void> RadioResponse::getRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                                       const V1_0::RadioCapability& rc) {
+    return mRealRadioResponse->getRadioCapabilityResponse(info, rc);
+}
+
+Return<void> RadioResponse::setRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+                                                       const V1_0::RadioCapability& rc) {
+    return mRealRadioResponse->setRadioCapabilityResponse(info, rc);
+}
+
+Return<void> RadioResponse::startLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                                    const V1_0::LceStatusInfo& statusInfo) {
+    return mRealRadioResponse->startLceServiceResponse(info, statusInfo);
+}
+
+Return<void> RadioResponse::stopLceServiceResponse(const V1_0::RadioResponseInfo& info,
+                                                   const V1_0::LceStatusInfo& statusInfo) {
+    return mRealRadioResponse->stopLceServiceResponse(info, statusInfo);
+}
+
+Return<void> RadioResponse::pullLceDataResponse(const V1_0::RadioResponseInfo& info,
+                                                const V1_0::LceDataInfo& lceInfo) {
+    return mRealRadioResponse->pullLceDataResponse(info, lceInfo);
+}
+
+Return<void> RadioResponse::getModemActivityInfoResponse(
+        const V1_0::RadioResponseInfo& info, const V1_0::ActivityStatsInfo& activityInfo) {
+    return mRealRadioResponse->getModemActivityInfoResponse(info, activityInfo);
+}
+
+Return<void> RadioResponse::setAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
+                                                       int32_t /* numAllowed */) {
+    return mRealRadioResponse->setAllowedCarriersResponse_1_4(info);
+}
+
+Return<void> RadioResponse::getAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
+                                                       bool allAllowed,
+                                                       const V1_0::CarrierRestrictions& carriers) {
+    V1_4::CarrierRestrictionsWithPriority newCarriers = {};
+    if(allAllowed){
+        newCarriers.allowedCarriersPrioritized = false;
+        return mRealRadioResponse->getAllowedCarriersResponse_1_4(info, newCarriers, V1_4::SimLockMultiSimPolicy::NO_MULTISIM_POLICY);
+    }
+
+    newCarriers.allowedCarriers = carriers.allowedCarriers;
+    newCarriers.excludedCarriers = carriers.excludedCarriers;
+    newCarriers.allowedCarriersPrioritized = true;
+    return mRealRadioResponse->getAllowedCarriersResponse_1_4(info, newCarriers, V1_4::SimLockMultiSimPolicy::NO_MULTISIM_POLICY);
+}
+
+Return<void> RadioResponse::sendDeviceStateResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->sendDeviceStateResponse(info);
+}
+
+Return<void> RadioResponse::setIndicationFilterResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setIndicationFilterResponse(info);
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setSimCardPowerResponse_1_1(info);
+}
+
+Return<void> RadioResponse::acknowledgeRequest(int32_t serial) {
+    return mRealRadioResponse->acknowledgeRequest(serial);
+}
+
+// Methods from ::android::hardware::radio::V1_1::IRadioResponse follow.
+Return<void> RadioResponse::setCarrierInfoForImsiEncryptionResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setCarrierInfoForImsiEncryptionResponse(info);
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse_1_1(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setSimCardPowerResponse_1_1(info);
+}
+
+Return<void> RadioResponse::startNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->startNetworkScanResponse_1_4(info);
+}
+
+
+Return<void> RadioResponse::stopNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->stopNetworkScanResponse(info);
+}
+
+Return<void> RadioResponse::startKeepaliveResponse(const V1_0::RadioResponseInfo& info,
+                                                   const V1_1::KeepaliveStatus& status) {
+    return mRealRadioResponse->startKeepaliveResponse(info, status);
+}
+
+Return<void> RadioResponse::stopKeepaliveResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->stopKeepaliveResponse(info);
+}
+
+// Methods from ::android::hardware::radio::V1_2::IRadioResponse follow.
+Return<void> RadioResponse::getCellInfoListResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_2::CellInfo>& cellInfo) {
+    return mRealRadioResponse->getCellInfoListResponse_1_4(info, Create1_4CellInfoList(cellInfo));
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                         const V1_2::CardStatus& cardStatus) {
+    return mRealRadioResponse->getIccCardStatusResponse_1_4(info, {cardStatus, hidl_string("")});
+}
+
+Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setSignalStrengthReportingCriteriaResponse(info);
+}
+
+Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setLinkCapacityReportingCriteriaResponse(info);
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse_1_2(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_2::Call>& calls) {
+    return mRealRadioResponse->getCurrentCallsResponse_1_2(info, calls);
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_2(
+        const V1_0::RadioResponseInfo& info, const V1_2::SignalStrength& signalStrength) {
+    return mRealRadioResponse->getSignalStrengthResponse_1_4(info, Create1_4SignalStrength(signalStrength));
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_2(
+        const V1_0::RadioResponseInfo& info, const V1_2::VoiceRegStateResult& voiceRegResponse) {
+    return mRealRadioResponse->getVoiceRegistrationStateResponse_1_2(info, voiceRegResponse);
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_2(
+        const V1_0::RadioResponseInfo& info, const V1_2::DataRegStateResult& dataRegResponse) {
+    mDataRoaming = (dataRegResponse.regState == V1_0::RegState::REG_ROAMING);
+    V1_4::DataRegStateResult newDRR = {};
+    newDRR.base = dataRegResponse;
+    return mRealRadioResponse->getDataRegistrationStateResponse_1_4(info, newDRR);
+}
+
+// Methods from ::android::hardware::radio::V1_3::IRadioResponse follow.
+Return<void> RadioResponse::setSystemSelectionChannelsResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setSystemSelectionChannelsResponse(info);
+}
+
+Return<void> RadioResponse::enableModemResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->enableModemResponse(info);
+}
+
+Return<void> RadioResponse::getModemStackStatusResponse(const V1_0::RadioResponseInfo& info,
+                                                        bool isEnabled) {
+    return mRealRadioResponse->getModemStackStatusResponse(info, isEnabled);
+}
+
+// Methods from ::android::hardware::radio::V1_4::IRadioResponse follow.
+Return<void> RadioResponse::emergencyDialResponse(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->emergencyDialResponse(info);
+}
+
+Return<void> RadioResponse::startNetworkScanResponse_1_4(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->startNetworkScanResponse_1_4(info);
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                                        const hidl_vec<V1_4::CellInfo>& cellInfo) {
+    return mRealRadioResponse->getCellInfoListResponse_1_4(info, cellInfo);
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const V1_4::DataRegStateResult& dataRegResponse) {
+    return mRealRadioResponse->getDataRegistrationStateResponse_1_4(info, dataRegResponse);
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                                         const V1_4::CardStatus& cardStatus) {
+    return mRealRadioResponse->getIccCardStatusResponse_1_4(info, cardStatus);
+}
+
+Return<void> RadioResponse::getPreferredNetworkTypeBitmapResponse(
+        const V1_0::RadioResponseInfo& info, hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) {
+    return mRealRadioResponse->getPreferredNetworkTypeBitmapResponse(info, networkTypeBitmap);
+}
+
+Return<void> RadioResponse::setPreferredNetworkTypeBitmapResponse(
+        const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setPreferredNetworkTypeBitmapResponse(info);
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_4(
+        const V1_0::RadioResponseInfo& info,
+        const hidl_vec<V1_4::SetupDataCallResult>& dcResponse) {
+    return mRealRadioResponse->getDataCallListResponse_1_4(info, dcResponse);
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_4(const V1_0::RadioResponseInfo& info,
+                                                      const V1_4::SetupDataCallResult& dcResponse) {
+    return mRealRadioResponse->setupDataCallResponse_1_4(info, dcResponse);
+}
+
+Return<void> RadioResponse::setAllowedCarriersResponse_1_4(const V1_0::RadioResponseInfo& info) {
+    return mRealRadioResponse->setAllowedCarriersResponse_1_4(info);
+}
+
+Return<void> RadioResponse::getAllowedCarriersResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const V1_4::CarrierRestrictionsWithPriority& carriers,
+        V1_4::SimLockMultiSimPolicy multiSimPolicy) {
+    return mRealRadioResponse->getAllowedCarriersResponse_1_4(info, carriers, multiSimPolicy);
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_4(
+        const V1_0::RadioResponseInfo& info, const V1_4::SignalStrength& signalStrength) {
+    return mRealRadioResponse->getSignalStrengthResponse_1_4(info, signalStrength);
+}
+
+}  // namespace android::hardware::radio::implementation
diff --git a/radio/1.4/legacy/RadioResponse.h b/radio/1.4/legacy/RadioResponse.h
new file mode 100644
index 0000000..aecd38d
--- /dev/null
+++ b/radio/1.4/legacy/RadioResponse.h
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <android/hardware/radio/1.4/IRadioResponse.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android::hardware::radio::implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct RadioResponse : public V1_4::IRadioResponse {
+    sp<V1_4::IRadioResponse> mRealRadioResponse;
+    V1_0::RadioTechnology mRat = V1_0::RadioTechnology::UNKNOWN;
+    bool mDataRoaming = false;
+    // Methods from ::android::hardware::radio::V1_0::IRadioResponse follow.
+    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;
+
+    // Methods from ::android::hardware::radio::V1_1::IRadioResponse follow.
+    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;
+
+    // Methods from ::android::hardware::radio::V1_2::IRadioResponse follow.
+    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;
+
+    // Methods from ::android::hardware::radio::V1_3::IRadioResponse follow.
+    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;
+
+    // Methods from ::android::hardware::radio::V1_4::IRadioResponse follow.
+    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_0::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;
+};
+
+}  // namespace android::hardware::radio::implementation
diff --git a/radio/1.4/legacy/android.hardware.radio@1.4-service.legacy.rc b/radio/1.4/legacy/android.hardware.radio@1.4-service.legacy.rc
new file mode 100644
index 0000000..c3b2060
--- /dev/null
+++ b/radio/1.4/legacy/android.hardware.radio@1.4-service.legacy.rc
@@ -0,0 +1,9 @@
+service vendor.radio-1-4-legacy /vendor/bin/hw/android.hardware.radio@1.4-service.legacy
+    interface android.hardware.radio@1.0::IRadio default
+    interface android.hardware.radio@1.1::IRadio default
+    interface android.hardware.radio@1.2::IRadio default
+    interface android.hardware.radio@1.3::IRadio default
+    interface android.hardware.radio@1.4::IRadio default
+    class hal
+    user system
+    group system
diff --git a/radio/1.4/legacy/hidl-utils.cpp b/radio/1.4/legacy/hidl-utils.cpp
new file mode 100644
index 0000000..fc0d54d
--- /dev/null
+++ b/radio/1.4/legacy/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/1.4/legacy/hidl-utils.h b/radio/1.4/legacy/hidl-utils.h
new file mode 100644
index 0000000..be3386f
--- /dev/null
+++ b/radio/1.4/legacy/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/1.4/legacy/service.cpp b/radio/1.4/legacy/service.cpp
new file mode 100644
index 0000000..460abbd
--- /dev/null
+++ b/radio/1.4/legacy/service.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2024 The LineageOS Project
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#define LOG_TAG "android.hardware.radio@1.4-service.legacy"
+
+#include <android-base/logging.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "Radio.h"
+#include "hidl-utils.h"
+
+#include <map>
+
+using namespace android::hardware::radio;
+using namespace android::hardware::hidl_utils;
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+using android::hardware::radio::implementation::Radio;
+
+using android::OK;
+using android::sp;
+using android::status_t;
+
+#define MAX_SLOT_ID 4
+
+int main() {
+    // Note: Starts from slot 1
+    std::map<int, sp<V1_4::IRadio>> slotIdToRadio;
+
+    for (int slotId = 1; slotId <= MAX_SLOT_ID; slotId++) {
+        sp<V1_0::IRadio> realRadio = V1_0::IRadio::getService("slot" + std::to_string(slotId));
+        if (realRadio == nullptr) {
+            LOG(INFO) << "Cannot get radio service for slot " << slotId;
+
+            if (slotId == 1) {
+                LOG(ERROR) << "Cannot get radio service for slot 1.";
+                return 1;
+            }
+
+            break;
+        }
+
+        slotIdToRadio[slotId] = new Radio(realRadio);
+        linkDeathToDeath(realRadio);
+    }
+
+    configureRpcThreadpool(1, true);
+
+    for (auto const& [slotId, radio] : slotIdToRadio) {
+        status_t status = radio->registerAsService("slot" + std::to_string(slotId));
+        if (status != OK) {
+            LOG(ERROR) << "Cannot register Radio HAL service for slot " << slotId;
+            return 1;
+        }
+    }
+
+    LOG(INFO) << "Radio HAL service ready.";
+
+    joinRpcThreadpool();
+
+    LOG(INFO) << "Radio HAL service failed to join thread pool.";
+    return 1;
+}
diff --git a/radio/config/1.1-wrapper/RadioConfig.cpp b/radio/config/1.1-wrapper/RadioConfig.cpp
index 582712e..a4682b3 100644
--- a/radio/config/1.1-wrapper/RadioConfig.cpp
+++ b/radio/config/1.1-wrapper/RadioConfig.cpp
@@ -144,15 +144,10 @@
         radioError = RadioError::INVALID_ARGUMENTS;
     } else {
         for (uint8_t i = 0; i < radios.size(); i++) {
-            auto radio = radios[i];
-            if (radio == nullptr) {
-                LOG(ERROR) << __func__ << ": radios[" << std::to_string(i) << "] is null";
-                radioError = RadioError::INTERNAL_ERR;
-                continue;
-            }
-
-            radio->setDataAllowed(-1, i == modemId);
+            if (i != modemId) radios[i]->setDataAllowed(-1, false);
         }
+
+        radios[modemId]->setDataAllowed(-1, true);
     }
 
     auto radioConfigResponseV1_1 = mRadioConfigResponseV1_1;