OSDN Git Service

Port Mock Ril from master branch to GB. DO NOT MERGE
[android-x86/hardware-ril.git] / mock-ril / src / js / mock_ril.js
1 /**
2  * Copyright (C) 2010 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /**
18  * @fileoverview Mock Radio Interface Layer (RIL) used for testing
19  *
20  * The following routines are defined in c++:
21  *
22  * Print a string to android log
23  *   print(string)
24  *
25  * Read a file to a string.
26  *   String readFileToString(String fileName)
27  *
28  * Read a file to a Buffer.
29  *   Buffer readFileToBuffer(String fileName)
30  *
31  * Send an response unsolicited response to the framework.
32  *   sendRilUnsolicitedResponse(Number responseNum, Buffer responseProtobuf)
33  *
34  * Send a completion request to the framework.
35  *   sendRilRequestComplete(Number rilErrCode, Number reqNum,
36  *                              String token, Buffer responseProtobuf)
37  *
38  * Send a complete request to the controller.
39  *   sendCtrlRequestComplete(Number ctrlStatus, Number reqNum,
40  *                              String token, Buffer responseProtobuf)
41  *
42  * Include the javascript file.
43  *   include(string)
44  *
45  * The following objects are defined in c++
46  *
47  * Buffer is defined in node_buffer and provides a wrapper
48  * for a buffer that can be shared between c++ and js.
49  *   Buffer(length)
50  *     Buffer::length()
51  *     Buffer::data()
52  *
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)
58  *
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))
64  *      Worker::add(req);
65  */
66
67 /**
68  * Globals
69  */
70
71 include("ril_vars.js");
72
73 var NULL_RESPONSE_STRING = '*magic-null*';
74
75 // The state of the radio, needed by currentState()
76 var gRadioState = RADIOSTATE_UNAVAILABLE;
77
78 // The state of the screen
79 var gScreenState = 0;
80
81 // The base band version
82 var gBaseBandVersion = 'mock-ril 0.1';
83
84 // define a global variable to access the global object
85 var globals = this;
86
87 // Empty Protobuf, defined here so we don't have
88 // to recreate an empty Buffer frequently
89 var emptyProtobuf = new Buffer();
90
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'));
95
96 /**
97  * Print properties of an object
98  */
99 function printProperties(obj, maxDepth, depth) {
100     if (typeof maxDepth == 'undefined') {
101         maxDepth = 1;
102     }
103     if (typeof depth == 'undefined') {
104         depth = 1;
105     }
106     if (depth == 1) {
107         print('printProperties:');
108     }
109     for (var property in obj) {
110         try {
111             if ((typeof obj[property] == 'object')
112                     && (depth < maxDepth)) {
113                 printProperties(obj[property], maxDepth, depth+1);
114             } else {
115                 print(depth + ': ' + property + '=' + obj[property] +
116                         ' type=' + typeof obj[property]);
117             }
118         } catch (err) {
119             print('err=' + err)
120         }
121     }
122 }
123
124 // Test printProperties
125 if (false) {
126     var myObject = { 'field1' : '1', 'field2' : '2', 'hello' : [ 'hi', 'there' ] };
127     printProperties(myObject, 3);
128 }
129
130 /**
131  * Include the components
132  */
133
134 include("simulated_radio.js");
135 include("simulated_icc.js");
136 include("ctrl_server.js");
137
138 /**
139  * Construct a new request which is passed to the
140  * Worker handler method.
141  */
142 function Request(reqNum, token, protobuf, schema, schemaName) {
143     this.reqNum = reqNum;
144     this.token = token;
145     try {
146         this.data = schema[packageNameAndSeperator + schemaName].parse(protobuf);
147     } catch (err) {
148         // not a valid protobuf in the request
149         this.data = null;
150     }
151 }
152
153 /**
154  * Dispatch incoming requests from RIL to the appropriate component.
155  */
156 function onRilRequest(reqNum, token, requestProtobuf) {
157     try {
158         //print('onRilRequest E: reqNum=' + reqNum + ' token=' + token);
159
160         /**
161          * Validate parameters
162          */
163         rilErrCode = RIL_E_SUCCESS;
164         if (typeof reqNum != 'number') {
165             print('onRilRequest: reqNum is not a number');
166             rilErrCode = RIL_E_GENERIC_FAILURE;
167         }
168         if (typeof token != 'number') {
169             print('onRilRequest: token is not a number');
170             rilErrCode = RIL_E_GENERIC_FAILURE;
171         }
172         if (typeof requestProtobuf != 'object') {
173             print('onRilRequest: requestProtobuf is not an object');
174             rilErrCode = RIL_E_GENERIC_FAILURE;
175         }
176         if (rilErrCode != RIL_E_SUCCESS) {
177             sendRilRequestComplete(rilErrCode, reqNum, token);
178             return 'onRilRequest X: invalid parameter';
179         }
180
181         try {
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');
186             } else {
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);
190                 }
191             }
192         } catch (err) {
193             print('onRilRequest: Unknown reqNum=' + reqNum + ' err=' + err);
194             sendRilRequestComplete(RIL_E_REQUEST_NOT_SUPPORTED, reqNum, token);
195         }
196         // print('onRilRequest X: reqNum=' + reqNum + ' token=' + token);
197     } catch (err) {
198         print('onRilRequest X: Exception err=' + err);
199         return('onRilRequest X: Exception err=' + err);
200     }
201     return 'onRilRequest X';
202 }
203
204 function onUnsolicitedTick(tick) {
205     print('onUnsolicitedTick EX tick=' + tick);
206     return 3;
207 }
208
209 /**
210  * Dispatch table for requests
211  *
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.
217  *
218  * DispatchTable[RIL_REQUEST_xxx].components = Array of components
219  * DisptachTable[RIL_REQUEST_xxx].Entry.schemaName = 'Name-of-schema';
220  */
221 var dispatchTable = new Array();
222
223 dispatchTable[RIL_REQUEST_GET_SIM_STATUS] = { // 1
224     'components' : [simulatedIccWorker],
225     'schemaName' : 'ReqGetSimStatus',
226 };
227 dispatchTable[RIL_REQUEST_ENTER_SIM_PIN] = { // 2
228     'components' : [simulatedIccWorker],
229     'schemaName' : 'ReqEnterSimPin',
230 };
231 dispatchTable[RIL_REQUEST_GET_CURRENT_CALLS] = { // 9
232     'components' : [simulatedRadioWorker],
233 };
234 dispatchTable[RIL_REQUEST_DIAL] = { // 10
235     'components' : [simulatedRadioWorker],
236     'schemaName' : 'ReqDial',
237 };
238 dispatchTable[RIL_REQUEST_GET_IMSI] = { // 11
239     'components' : [simulatedIccWorker],
240 };
241 dispatchTable[RIL_REQUEST_HANGUP] = { // 12
242     'components' : [simulatedRadioWorker],
243     'schemaName' : 'ReqHangUp',
244 };
245 dispatchTable[RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND] =  { // 13
246     'components' : [simulatedRadioWorker],
247 };
248 dispatchTable[RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = { // 14
249     'components' : [simulatedRadioWorker],
250 };
251 dispatchTable[RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = { // 15
252     'components' : [simulatedRadioWorker],
253 };
254 dispatchTable[RIL_REQUEST_CONFERENCE] = { // 16
255     'components' : [simulatedRadioWorker],
256 };
257 dispatchTable[RIL_REQUEST_SIGNAL_STRENGTH]  = { // 19
258     'components' : [simulatedRadioWorker],
259 };
260 dispatchTable[RIL_REQUEST_REGISTRATION_STATE] = { // 20
261     'components' : [simulatedRadioWorker],
262 };
263 dispatchTable[RIL_REQUEST_GPRS_REGISTRATION_STATE] = { // 21
264     'components' : [simulatedRadioWorker],
265 };
266 dispatchTable[RIL_REQUEST_OPERATOR] = { // 22
267     'components' : [simulatedIccWorker],
268 };
269 dispatchTable[RIL_REQUEST_GET_IMEI] = { // 38
270     'components' : [simulatedIccWorker],
271 };
272 dispatchTable[RIL_REQUEST_GET_IMEISV] = { // 39
273     'components' : [simulatedIccWorker],
274 };
275 dispatchTable[RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE] = { // 45
276     'components' : [simulatedRadioWorker],
277 };
278 dispatchTable[RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC] = { // 46
279     'components' : [simulatedRadioWorker],
280 };
281 dispatchTable[RIL_REQUEST_BASEBAND_VERSION] = { // 51
282     'components' : [simulatedRadioWorker],
283 };
284 dispatchTable[RIL_REQUEST_SEPARATE_CONNECTION] = { // 52
285     'components' : [simulatedRadioWorker],
286     'schemaName' : 'ReqSeparateConnection',
287 };
288 dispatchTable[RIL_REQUEST_SET_MUTE ] = { // 53
289     'components' : [simulatedRadioWorker],
290     'schemaName' : 'ReqSetMute',
291 };
292 dispatchTable[RIL_REQUEST_SCREEN_STATE] = { // 61
293     'components' : [simulatedRadioWorker],
294     'schemaName' : 'ReqScreenState',
295 };
296
297 /**
298  * Start the mock rill after loading
299  */
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:");
307 }
308
309 /**
310  * Optional tests
311  */
312 if (false) {
313     include("mock_ril_tests.js");
314 }