1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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;
}
|