aboutsummaryrefslogtreecommitdiffstats
path: root/rilsrc/libsecril-shim/secril-shim.c
diff options
context:
space:
mode:
Diffstat (limited to 'rilsrc/libsecril-shim/secril-shim.c')
-rw-r--r--rilsrc/libsecril-shim/secril-shim.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/rilsrc/libsecril-shim/secril-shim.c b/rilsrc/libsecril-shim/secril-shim.c
new file mode 100644
index 0000000..50723e3
--- /dev/null
+++ b/rilsrc/libsecril-shim/secril-shim.c
@@ -0,0 +1,99 @@
+#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;
+
+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 */
+ RIL_RadioCapability rc[1] =
+ {
+ { /* rc[0] */
+ RIL_RADIO_CAPABILITY_VERSION, /* version */
+ 0, /* session */
+ RC_PHASE_CONFIGURED, /* phase */
+ RAF_GSM | RAF_GPRS | RAF_EDGE | RAF_HSUPA | RAF_HSDPA | RAF_HSPA | RAF_HSPAP | RAF_UMTS, /* 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;
+
+ /* The following requests were introduced post-4.3. */
+ case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC:
+ case RIL_REQUEST_SIM_OPEN_CHANNEL: /* !!! */
+ case RIL_REQUEST_SIM_CLOSE_CHANNEL:
+ case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
+ case RIL_REQUEST_NV_READ_ITEM:
+ case RIL_REQUEST_NV_WRITE_ITEM:
+ case RIL_REQUEST_NV_WRITE_CDMA_PRL:
+ case RIL_REQUEST_NV_RESET_CONFIG:
+ case RIL_REQUEST_SET_UICC_SUBSCRIPTION:
+ case RIL_REQUEST_ALLOW_DATA:
+ case RIL_REQUEST_GET_HARDWARE_CONFIG:
+ case RIL_REQUEST_SIM_AUTHENTICATION:
+ case RIL_REQUEST_GET_DC_RT_INFO:
+ case RIL_REQUEST_SET_DC_RT_INFO_RATE:
+ case RIL_REQUEST_SET_DATA_PROFILE:
+ case RIL_REQUEST_SHUTDOWN: /* TODO: Is there something we can do for RIL_REQUEST_SHUTDOWN ? */
+ case RIL_REQUEST_SET_RADIO_CAPABILITY:
+ 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;
+
+ rilEnv = env;
+
+ /* Open and Init the original RIL. */
+
+ origRil = dlopen(RIL_LIB_PATH, RTLD_LOCAL);
+ if (CC_UNLIKELY(!origRil)) {
+ RLOGE("%s: failed to load '" RIL_LIB_PATH "': %s\n", __func__, dlerror());
+ return NULL;
+ }
+
+ origRilInit = dlsym(origRil, "RIL_Init");
+ if (CC_UNLIKELY(!origRilInit)) {
+ RLOGE("%s: couldn't find original RIL_Init!\n", __func__);
+ goto fail_after_dlopen;
+ }
+
+ origRilFunctions = origRilInit(env, argc, argv);
+ if (CC_UNLIKELY(!origRilFunctions)) {
+ RLOGE("%s: the original RIL_Init derped.\n", __func__);
+ goto fail_after_dlopen;
+ }
+
+ /* Shim functions as needed. */
+ shimmedFunctions = *origRilFunctions;
+ shimmedFunctions.onRequest = onRequestShim;
+
+ return &shimmedFunctions;
+
+fail_after_dlopen:
+ dlclose(origRil);
+ return NULL;
+}