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.
18 * @fileoverview Mock Radio Interface Layer (RIL) used for testing
20 * The following routines are defined in c++:
22 * Print a string to android log
25 * Read a file to a string.
26 * String readFileToString(String fileName)
28 * Read a file to a Buffer.
29 * Buffer readFileToBuffer(String fileName)
31 * Send an response unsolicited response to the framework.
32 * sendRilUnsolicitedResponse(Number responseNum, Buffer responseProtobuf)
34 * Send a completion request to the framework.
35 * sendRilRequestComplete(Number rilErrCode, Number reqNum,
36 * String token, Buffer responseProtobuf)
38 * Send a complete request to the controller.
39 * sendCtrlRequestComplete(Number ctrlStatus, Number reqNum,
40 * String token, Buffer responseProtobuf)
42 * Include the javascript file.
45 * The following objects are defined in c++
47 * Buffer is defined in node_buffer and provides a wrapper
48 * for a buffer that can be shared between c++ and js.
53 * Schema is defined in protobuf_v8 and converts between
54 * a buffer and an object. A protobuf descriptor, ril.desc
55 * and ctrl.desc, is used to drive the conversation.
56 * Object Schema::parse(Buffer protobuf)
57 * Buffer Schema::serialize(object)
59 * Worker is a thread which receives messages to be handled.
60 * It is passed a function which is called once for each
61 * message as it arrives. Call the add method to queue up
62 * requests for the worker function to process.
63 * Object Worker(function (req))
71 include("ril_vars.js");
73 var NULL_RESPONSE_STRING = '*magic-null*';
75 // The state of the radio, needed by currentState()
76 var gRadioState = RADIOSTATE_UNAVAILABLE;
78 // The state of the screen
81 // The base band version
82 var gBaseBandVersion = 'mock-ril 0.1';
84 // define a global variable to access the global object
87 // Empty Protobuf, defined here so we don't have
88 // to recreate an empty Buffer frequently
89 var emptyProtobuf = new Buffer();
91 // Get the ril description file and create a schema
92 var packageNameAndSeperator = 'ril_proto.';
93 var rilSchema = new Schema(readFileToBuffer('ril.desc'));
94 var ctrlSchema = new Schema(readFileToBuffer('ctrl.desc'));
97 * Print properties of an object
99 function printProperties(obj, maxDepth, depth) {
100 if (typeof maxDepth == 'undefined') {
103 if (typeof depth == 'undefined') {
107 print('printProperties:');
109 for (var property in obj) {
111 if ((typeof obj[property] == 'object')
112 && (depth < maxDepth)) {
113 printProperties(obj[property], maxDepth, depth+1);
115 print(depth + ': ' + property + '=' + obj[property] +
116 ' type=' + typeof obj[property]);
124 // Test printProperties
126 var myObject = { 'field1' : '1', 'field2' : '2', 'hello' : [ 'hi', 'there' ] };
127 printProperties(myObject, 3);
131 * Include the components
134 include("simulated_radio.js");
135 include("simulated_icc.js");
136 include("ctrl_server.js");
139 * Construct a new request which is passed to the
140 * Worker handler method.
142 function Request(reqNum, token, protobuf, schema, schemaName) {
143 this.reqNum = reqNum;
146 this.data = schema[packageNameAndSeperator + schemaName].parse(protobuf);
148 // not a valid protobuf in the request
154 * Dispatch incoming requests from RIL to the appropriate component.
156 function onRilRequest(reqNum, token, requestProtobuf) {
158 //print('onRilRequest E: reqNum=' + reqNum + ' token=' + token);
161 * Validate parameters
163 rilErrCode = RIL_E_SUCCESS;
164 if (typeof reqNum != 'number') {
165 print('onRilRequest: reqNum is not a number');
166 rilErrCode = RIL_E_GENERIC_FAILURE;
168 if (typeof token != 'number') {
169 print('onRilRequest: token is not a number');
170 rilErrCode = RIL_E_GENERIC_FAILURE;
172 if (typeof requestProtobuf != 'object') {
173 print('onRilRequest: requestProtobuf is not an object');
174 rilErrCode = RIL_E_GENERIC_FAILURE;
176 if (rilErrCode != RIL_E_SUCCESS) {
177 sendRilRequestComplete(rilErrCode, reqNum, token);
178 return 'onRilRequest X: invalid parameter';
182 //print('onRilRequest: get entry from dispatchTable reqNum=' + reqNum);
183 entry = dispatchTable[reqNum];
184 if (typeof entry == 'undefined') {
185 throw ('entry = dispatchTable[' + reqNum + '] was undefined');
187 req = new Request(reqNum, token, requestProtobuf, rilSchema, entry.schemaName);
188 for(i = 0; i < entry.components.length; i++) {
189 entry.components[i].add(req);
193 print('onRilRequest: Unknown reqNum=' + reqNum + ' err=' + err);
194 sendRilRequestComplete(RIL_E_REQUEST_NOT_SUPPORTED, reqNum, token);
196 // print('onRilRequest X: reqNum=' + reqNum + ' token=' + token);
198 print('onRilRequest X: Exception err=' + err);
199 return('onRilRequest X: Exception err=' + err);
201 return 'onRilRequest X';
204 function onUnsolicitedTick(tick) {
205 print('onUnsolicitedTick EX tick=' + tick);
210 * Dispatch table for requests
212 * Each table entry is index by the RIL_REQUEST_xxxx
213 * and contains an array of components this request
214 * is to be sent to and the name of the schema
215 * that converts the incoming protobuf to the
216 * appropriate request data.
218 * DispatchTable[RIL_REQUEST_xxx].components = Array of components
219 * DisptachTable[RIL_REQUEST_xxx].Entry.schemaName = 'Name-of-schema';
221 var dispatchTable = new Array();
223 dispatchTable[RIL_REQUEST_GET_SIM_STATUS] = { // 1
224 'components' : [simulatedIccWorker],
225 'schemaName' : 'ReqGetSimStatus',
227 dispatchTable[RIL_REQUEST_ENTER_SIM_PIN] = { // 2
228 'components' : [simulatedIccWorker],
229 'schemaName' : 'ReqEnterSimPin',
231 dispatchTable[RIL_REQUEST_GET_CURRENT_CALLS] = { // 9
232 'components' : [simulatedRadioWorker],
234 dispatchTable[RIL_REQUEST_DIAL] = { // 10
235 'components' : [simulatedRadioWorker],
236 'schemaName' : 'ReqDial',
238 dispatchTable[RIL_REQUEST_GET_IMSI] = { // 11
239 'components' : [simulatedIccWorker],
241 dispatchTable[RIL_REQUEST_HANGUP] = { // 12
242 'components' : [simulatedRadioWorker],
243 'schemaName' : 'ReqHangUp',
245 dispatchTable[RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND] = { // 13
246 'components' : [simulatedRadioWorker],
248 dispatchTable[RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = { // 14
249 'components' : [simulatedRadioWorker],
251 dispatchTable[RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = { // 15
252 'components' : [simulatedRadioWorker],
254 dispatchTable[RIL_REQUEST_CONFERENCE] = { // 16
255 'components' : [simulatedRadioWorker],
257 dispatchTable[RIL_REQUEST_SIGNAL_STRENGTH] = { // 19
258 'components' : [simulatedRadioWorker],
260 dispatchTable[RIL_REQUEST_REGISTRATION_STATE] = { // 20
261 'components' : [simulatedRadioWorker],
263 dispatchTable[RIL_REQUEST_GPRS_REGISTRATION_STATE] = { // 21
264 'components' : [simulatedRadioWorker],
266 dispatchTable[RIL_REQUEST_OPERATOR] = { // 22
267 'components' : [simulatedIccWorker],
269 dispatchTable[RIL_REQUEST_GET_IMEI] = { // 38
270 'components' : [simulatedIccWorker],
272 dispatchTable[RIL_REQUEST_GET_IMEISV] = { // 39
273 'components' : [simulatedIccWorker],
275 dispatchTable[RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE] = { // 45
276 'components' : [simulatedRadioWorker],
278 dispatchTable[RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC] = { // 46
279 'components' : [simulatedRadioWorker],
281 dispatchTable[RIL_REQUEST_BASEBAND_VERSION] = { // 51
282 'components' : [simulatedRadioWorker],
284 dispatchTable[RIL_REQUEST_SEPARATE_CONNECTION] = { // 52
285 'components' : [simulatedRadioWorker],
286 'schemaName' : 'ReqSeparateConnection',
288 dispatchTable[RIL_REQUEST_SET_MUTE ] = { // 53
289 'components' : [simulatedRadioWorker],
290 'schemaName' : 'ReqSetMute',
292 dispatchTable[RIL_REQUEST_SCREEN_STATE] = { // 61
293 'components' : [simulatedRadioWorker],
294 'schemaName' : 'ReqScreenState',
298 * Start the mock rill after loading
300 function startMockRil() {
301 print("startMockRil E:");
302 setRadioState(RADIOSTATE_SIM_READY);
303 // send the signal strength after 5 seconds, wait until mock ril is started
304 simulatedRadioWorker.addDelayed({
305 'reqNum' : CMD_UNSOL_SIGNAL_STRENGTH}, 5000);
306 print("startMockRil X:");
313 include("mock_ril_tests.js");