diff options
-rwxr-xr-x | device.mk | 3 | ||||
-rw-r--r-- | ril/libsecril-shim/Android.mk | 18 | ||||
-rw-r--r-- | ril/libsecril-shim/secril-shim.c | 118 | ||||
-rw-r--r-- | ril/libsecril-shim/secril-shim.h | 27 |
4 files changed, 165 insertions, 1 deletions
@@ -44,7 +44,8 @@ PRODUCT_PACKAGES += \ # RIL PRODUCT_PACKAGES += \ libsecril-client \ - libsecril-compat + libsecril-compat \ + libsecril-shim # Charging mode PRODUCT_PACKAGES += \ diff --git a/ril/libsecril-shim/Android.mk b/ril/libsecril-shim/Android.mk new file mode 100644 index 0000000..91519f2 --- /dev/null +++ b/ril/libsecril-shim/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + secril-shim.c + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libril \ + libcutils + +LOCAL_CFLAGS := -Wall -Werror + +LOCAL_MODULE := libsecril-shim + +include $(BUILD_SHARED_LIBRARY) diff --git a/ril/libsecril-shim/secril-shim.c b/ril/libsecril-shim/secril-shim.c new file mode 100644 index 0000000..abc580e --- /dev/null +++ b/ril/libsecril-shim/secril-shim.c @@ -0,0 +1,118 @@ +#include "secril-shim.h" + +/* A copy of the original RIL function table. */ +static const RIL_RadioFunctions *origRilFunctions; + +/* A copy of the ril environment passed to RIL_Init. */ +static const struct RIL_Env *rilEnv; + +/* The tuna variant we're running on. */ +static int tunaVariant = VARIANT_INIT; + + +static void onRequestShim(int request, void *data, size_t datalen, RIL_Token t) +{ + switch (request) { + /* Necessary; RILJ may fake this for us if we reply not supported, but we can just implement it. */ + case RIL_REQUEST_GET_RADIO_CAPABILITY: + ; /* lol C standard */ + int raf = RAF_UNKNOWN; + if (tunaVariant == VARIANT_MAGURO) { + raf = RAF_GSM | RAF_GPRS | RAF_EDGE | RAF_HSUPA | RAF_HSDPA | RAF_HSPA | RAF_HSPAP | RAF_UMTS; + } else if (tunaVariant == VARIANT_TORO || tunaVariant == VARIANT_TOROPLUS) { + raf = RAF_LTE | RAF_IS95A | RAF_IS95B | RAF_1xRTT | RAF_EVDO_0 | RAF_EVDO_A | RAF_EVDO_B | RAF_EHRPD; + } + if (__predict_true(raf != RAF_UNKNOWN)) { + RIL_RadioCapability rc[1] = + { + { /* rc[0] */ + RIL_RADIO_CAPABILITY_VERSION, /* version */ + 0, /* session */ + RC_PHASE_CONFIGURED, /* phase */ + raf, /* rat */ + { /* logicalModemUuid */ + 0, + }, + RC_STATUS_SUCCESS /* status */ + } + }; + RLOGW("%s: got request %s: replied with our implementation!\n", __func__, requestToString(request)); + rilEnv->OnRequestComplete(t, RIL_E_SUCCESS, rc, sizeof(rc)); + return; + } + /* else fallthrough to RIL_E_REQUEST_NOT_SUPPORTED */ + + /* Necessary; otherwise we seem to lock up. */ + case RIL_REQUEST_SIM_OPEN_CHANNEL: + + /* Might not be necessary, but we don't support it as far as I know. */ + case RIL_REQUEST_ALLOW_DATA: + + /* LCE is new (Android 6.0+). RILJ probably won't care how we + * reply to this, but better safe than sorry in my opinion. + * According to hardware/ril, we should be replying to the + * LCE commands with RIL_E_LCE_NOT_SUPPORTED, but RILJ does + * not recognize that as a valid respone. LOL! */ + case RIL_REQUEST_START_LCE: + case RIL_REQUEST_STOP_LCE: + case RIL_REQUEST_PULL_LCEDATA: + RLOGW("%s: got request %s: replied with REQUEST_NOT_SUPPPORTED.\n", __func__, requestToString(request)); + rilEnv->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); + return; + } + + RLOGD("%s: got request %s: forwarded to RIL.\n", __func__, requestToString(request)); + origRilFunctions->onRequest(request, data, datalen, t); +} + +const RIL_RadioFunctions* RIL_Init(const struct RIL_Env *env, int argc, char **argv) +{ + RIL_RadioFunctions const* (*origRilInit)(const struct RIL_Env *env, int argc, char **argv); + static RIL_RadioFunctions shimmedFunctions; + void *origRil; + char propBuf[PROPERTY_VALUE_MAX]; + + if (__predict_true(tunaVariant == VARIANT_INIT)) { + property_get("ro.product.subdevice", propBuf, "unknown"); + if (!strcmp(propBuf, "maguro")) { + tunaVariant = VARIANT_MAGURO; + } else if (!strcmp(propBuf, "toro")) { + tunaVariant = VARIANT_TORO; + } else if (!strcmp(propBuf, "toroplus")) { + tunaVariant = VARIANT_TOROPLUS; + } else { + tunaVariant = VARIANT_UNKNOWN; + } + RLOGD("%s: got tuna variant: %i", __func__, tunaVariant); + } + + rilEnv = env; + + /* Open and Init the original RIL. */ + + origRil = dlopen(RIL_LIB_PATH, RTLD_LOCAL); + if (__predict_false(!origRil)) { + RLOGE("%s: failed to load '" RIL_LIB_PATH "': %s\n", __func__, dlerror()); + return NULL; + } + + origRilInit = dlsym(origRil, "RIL_Init"); + if (__predict_false(!origRilInit)) { + RLOGE("%s: couldn't find original RIL_Init!\n", __func__); + dlclose(origRil); + return NULL; + } + + origRilFunctions = origRilInit(env, argc, argv); + if (__predict_false(!origRilFunctions)) { + RLOGE("%s: the original RIL_Init derped.\n", __func__); + dlclose(origRil); + return NULL; + } + + /* Shim functions as needed. */ + shimmedFunctions = *origRilFunctions; + shimmedFunctions.onRequest = onRequestShim; + + return &shimmedFunctions; +} diff --git a/ril/libsecril-shim/secril-shim.h b/ril/libsecril-shim/secril-shim.h new file mode 100644 index 0000000..f64d053 --- /dev/null +++ b/ril/libsecril-shim/secril-shim.h @@ -0,0 +1,27 @@ +#ifndef __SECRIL_SHIM_H__ +#define __SECRIL_SHIM_H__ + +#define LOG_TAG "secril-shim" +#define RIL_SHLIB + +#include <cutils/properties.h> +#include <sys/cdefs.h> +#include <telephony/ril.h> +#include <utils/Log.h> +#include <dlfcn.h> +#include <stdlib.h> +#include <string.h> + +#define RIL_LIB_PATH "/vendor/lib/libsec-ril.so" + +enum variant_type { + VARIANT_INIT, + VARIANT_MAGURO, + VARIANT_TORO, + VARIANT_TOROPLUS, + VARIANT_UNKNOWN +}; + +extern const char * requestToString(int request); + +#endif /* __SECRIL_SHIM_H__ */ |