2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <telephony/ril.h>
23 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <cutils/sockets.h>
37 #include "ctrl_server.h"
39 #include "experiments.h"
40 #include "js_support.h"
41 #include "node_buffer.h"
42 #include "node_object_wrap.h"
43 #include "node_util.h"
44 #include "protobuf_v8.h"
46 #include "responses.h"
50 #include "worker_v8.h"
55 // Needed so we can call it prior to calling startMockRil
56 extern void RIL_register(const RIL_RadioFunctions *callbacks);
59 //#define MOCK_RIL_DEBUG
62 #define DBG(...) LOGD(__VA_ARGS__)
71 #define MOCK_RIL_VER_STRING "Android Mock-ril 0.1"
74 * Forward declarations
76 static void onRequest (int request, void *data, size_t datalen, RIL_Token t);
77 static RIL_RadioState currentState();
78 static int onSupports (int requestCode);
79 static void onCancel (RIL_Token t);
80 static const char *getVersion();
82 static void testOnRequestComplete(RIL_Token t, RIL_Errno e,
83 void *response, size_t responselen);
84 static void testRequestTimedCallback(RIL_TimedCallback callback,
85 void *param, const struct timeval *relativeTime);
86 static void testOnUnsolicitedResponse(int unsolResponse, const void *data,
90 * The environment from rild with the completion routine
92 const struct RIL_Env *s_rilenv;
95 * Expose our routines to rild
97 static const RIL_RadioFunctions s_callbacks = {
109 static const RIL_Env testEnv = {
110 testOnRequestComplete,
111 testOnUnsolicitedResponse,
112 testRequestTimedCallback
116 * The request worker queue to handle requests
118 static RilRequestWorkerQueue *s_requestWorkerQueue;
121 * Call from RIL to us to make a RIL_REQUEST
123 * Must be completed with a call to RIL_onRequestComplete()
125 * RIL_onRequestComplete() may be called from any thread, before or after
126 * this function returns.
128 * Will always be called from the same thread, so returning here implies
129 * that the radio is ready to process another command (whether or not
130 * the previous command has c1mpleted).
132 static void onRequest (int request, void *data, size_t datalen, RIL_Token t)
134 DBG("onRequest: request=%d data=%p datalen=%d token=%p",
135 request, data, datalen, t);
136 s_requestWorkerQueue->AddRequest(request, data, datalen, t);
140 * Synchronous call from the RIL to us to return current radio state.
141 * RADIO_STATE_UNAVAILABLE should be the initial state.
143 static RIL_RadioState currentState()
145 DBG("currentState: gRadioState=%d", gRadioState);
150 * Call from RIL to us to find out whether a specific request code
151 * is supported by this implementation.
153 * Return 1 for "supported" and 0 for "unsupported"
157 onSupports (int requestCode)
159 DBG("onSupports: nothing supported at the moment, return 0");
163 static void onCancel (RIL_Token t)
165 DBG("onCancel: ignorning");
168 static const char * getVersion(void)
170 DBG("getVersion: return '%s'", MOCK_RIL_VER_STRING);
171 return MOCK_RIL_VER_STRING;
175 * "t" is parameter passed in on previous call to RIL_Notification
178 * If "e" != SUCCESS, then response can be null/is ignored
180 * "response" is owned by caller, and should not be modified or
183 * RIL_onRequestComplete will return as soon as possible
185 void testOnRequestComplete(RIL_Token t, RIL_Errno e,
186 void *response, size_t responselen) {
187 DBG("testOnRequestComplete E: token=%p rilErrCode=%d data=%p datalen=%d",
188 t, e, response, responselen);
189 DBG("testOnRequestComplete X:");
193 * "unsolResponse" is one of RIL_UNSOL_RESPONSE_*
194 * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_*
196 * "data" is owned by caller, and should not be modified or freed by callee
198 void testOnUnsolicitedResponse(int unsolResponse, const void *data,
200 DBG("testOnUnsolicitedResponse ignoring");
204 * Call user-specifed "callback" function on on the same thread that
205 * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies
206 * a relative time value at which the callback is invoked. If relativeTime is
207 * NULL or points to a 0-filled structure, the callback will be invoked as
210 void testRequestTimedCallback(RIL_TimedCallback callback,
211 void *param, const struct timeval *relativeTime) {
212 DBG("testRequestTimedCallback ignoring");
216 class UnsolicitedThread : public WorkerThread {
218 v8::Handle<v8::Context> context_;
221 UnsolicitedThread(v8::Handle<v8::Context> context) :
225 int OnUnsolicitedTick(int tick) {
226 v8::HandleScope handle_scope;
228 // Get handle to onUnslicitedTick.
229 v8::Handle<v8::String> name = v8::String::New("onUnsolicitedTick");
230 v8::Handle<v8::Value> functionValue = context_->Global()->Get(name);
231 v8::Handle<v8::Function> onUnsolicitedTick =
232 v8::Handle<v8::Function>::Cast(functionValue);
234 // Create the argument array
235 v8::Handle<v8::Value> v8TickValue = v8::Number::New(tick);
236 v8::Handle<v8::Value> argv[1] = { v8TickValue };
238 v8::Handle<v8::Value> resultValue =
239 onUnsolicitedTick->Call(context_->Global(), 1, argv);
240 int result = int(resultValue->NumberValue());
244 void * Worker(void *param)
246 LOGD("UnsolicitedThread::Worker E param=%p", param);
250 for (int i = 0; isRunning(); i++) {
251 // Get access and setup scope
252 v8::HandleScope handle_scope;
253 v8::Context::Scope context_scope(context_);
256 int sleepTime = OnUnsolicitedTick(i);
259 v8::Unlocker unlocker;
264 LOGD("UnsolicitedThread::Worker X param=%p", param);
271 void startMockRil(v8::Handle<v8::Context> context) {
272 v8::HandleScope handle_scope;
274 // Get handle to startMockRil and call it.
275 v8::Handle<v8::String> name = v8::String::New("startMockRil");
276 v8::Handle<v8::Value> functionValue = context->Global()->Get(name);
277 v8::Handle<v8::Function> start =
278 v8::Handle<v8::Function>::Cast(functionValue);
280 start->Call(context->Global(), 0, NULL);
284 const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc,
289 LOGD("RIL_Init E: ----------------");
292 v8::V8::Initialize();
294 // We're going to use multiple threads need to start locked
297 // Initialize modules
301 // Make a context and setup a scope
302 v8::Persistent<v8::Context> context = makeJsContext();
303 v8::Context::Scope context_scope(context);
304 v8::TryCatch try_catch;
305 try_catch.SetVerbose(true);
307 // Initialize modules needing context
308 ctrlServerInit(context);
313 LOGD("RIL_Init run tests #####################");
314 testJsSupport(context);
315 testRequests(context);
316 experiments(context);
318 testWorkerV8(context);
320 LOGD("RIL_Init tests completed ###############");
323 // load/run mock_ril.js
325 int status = ReadFile("/sdcard/data/mock_ril.js", &buffer);
327 runJs(context, &try_catch, "mock_ril.js", buffer);
328 if (try_catch.HasCaught()) {
329 // TODO: Change to event this is fatal
330 LOGE("FATAL ERROR: Unable to run mock_ril.js");
335 requestsInit(context, &s_requestWorkerQueue);
336 responsesInit(context);
338 // Register our call backs so when we startMockRil
339 // and it wants to send unsolicited messages the
340 // mock ril is registered
341 RIL_register(&s_callbacks);
343 // Start the mock ril
344 startMockRil(context);
347 UnsolicitedThread *ut = new UnsolicitedThread(context);
351 LOGD("RIL_Init X: ----------------");