2 * Copyright (c) 2013, Intel Corporation.
4 * This program is licensed under the terms and conditions of the
5 * Apache License, version 2.0. The full text of the Apache License is at
6 * http://www.apache.org/licenses/LICENSE-2.0
10 /* Dummy backend for faking websocket daemon */
11 var dummyBackend = false;
13 var ERROR_SETTINGSD_DISCONNECTED = 'Settings daemon is not connected';
15 var WS_REQUEST_TYPE = {
16 CONNMAN_MANAGER: "connman::manager",
17 CONNMAN_TECHNOLOGY: "connman::technology",
18 CONNMAN_SERVICE: "connman::service",
19 BLUETOOTH: "bluetooth",
28 BLUETOOTH: "bluetooth",
35 /* web socket module to connect to the settings daemon */
36 var wsAPI = (function() {
37 /* number of connection retries to attempt if the socket closes */
39 this.connected = false;
40 this.event_callbacks = $.Callbacks();
42 /* default values for WebSocket */
43 this.socketUrl = 'ws://localhost:16000/';
44 this.socketProtocol = 'http-only';
46 this.timeouttime = 15000;
48 this.methodCalls = [];
49 for (var i = 0; i < 100; i++) {
50 this.methodCalls[i] = null;
53 this.MethodCall = function(id, name, success_cb, error_cb) {
55 this.successCB = success_cb;
56 this.errorCB = error_cb;
57 this.transactionid = id;
60 this.start = function() {
61 me.timeout = setTimeout(function() {
62 if (me.errorCB !== undefined) {
63 me.errorCB('\"' + me.name + '\" method timed out after ' + self.timeouttime + ' ms');
68 this.finish = function() {
69 if (me.timeout !== undefined) {
70 clearTimeout(me.timeout);
76 this.EventObject = function(type, id, name, value) {
84 function connect(url, protocol, sucess_cb, error_cb) {
85 self.socketUrl = typeof url !== 'undefined' ? url : self.socketUrl;
86 self.socketProtocol = typeof protocol !== 'undefined' ? protocol : self.socketProtocol;
87 self.successCB = sucess_cb;
88 self.errorCB = error_cb;
90 if ('WebSocket' in window) {
91 if (self.socketProtocol.length > 0) {
92 self.socket = new WebSocket(self.socketUrl, self.socketProtocol);
94 self.socket = new WebSocket(self);
96 console.log('Connecting to websocket: ' + self.socketUrl);
98 self.socket.onopen = function() {
99 self.connected = true;
100 console.log('websocket opened');
104 self.socket.onclose = function(code, reason, remote) {
105 self.connected = false;
106 console.log('websocket closed - ' + reason);
109 /* fake the connection for dummy backend */
110 self.connected = true;
115 self.errorCB(reason);
118 self.socket.onerror = function(e) {
120 /* ignore websocket error */
125 self.errorCB('websocket error: ' + e.data);
127 self.errorCB('websocket error: unknown');
131 self.socket.onmessage = function(e) {
135 console.log('Websockets not supported');
139 function reconnect() {
140 if (this.connected) return;
142 setTimeout(function() {
143 connect(self.socketUrl, self.socketProtocol, self.successCB, self.errorCB);
147 function send(msg, success_cb, error_cb) {
148 if (!this.connected) {
149 if (error_cb !== undefined) {
150 error_cb(ERROR_SETTINGSD_DISCONNECTED);
154 var i = this.methodIdx;
155 this.methodIdx = (this.methodIdx + 1) % 100;
156 this.methodCalls[i] = new this.MethodCall(msg.transactionid, msg.name, success_cb, error_cb);
157 this.methodCalls[i].start();
159 var jsonMsg = JSON.stringify(msg);
160 console.log('Sending json msg: ' + jsonMsg);
162 /* fake with dummy data */
163 dummyBackendSend(msg);
165 this.socket.send(jsonMsg);
169 function fireEvent(type, id, name, value) {
170 var event = new this.EventObject(type, id, name, value);
171 console.log('Firing ' + type + ' event id=' + id + ', name=' + name + ', value=' + value);
172 event_callbacks.fire(event);
175 function receive(msg) {
179 console.log("Received json msg: " + msg);
180 response = JSON.parse(msg);
182 console.error('Garbage message: ' + msg);
186 if ((response === undefined) || (response.type === undefined)) {
187 console.error('Badly formed message: ' + msg);
188 } else if (response.type === 'event' && response.value !== undefined) {
189 if (response.value.interface_name === 'net.connman.Manager' || response.value.interface_name === 'net.connman.Service' || response.value.interface_name === 'net.connman.Technology') {
190 if (response.value.signal_name === undefined || response.value.parameters === undefined) {
191 console.error('Badly formed event: ' + msg);
194 if (response.value.signal_name === 'ServiceChanged' && response.value.parameters.length !== 2) {
195 console.error('Badly formed event parameters: ' + msg);
199 if (response.value.object_path === '/' || response.value.object_path.indexOf('/net/connman/technology/') >= 0) {
200 fireEvent(WS_EVENT_TYPE.CONNMAN, response.value.object_path, response.value.signal_name, response.value.parameters);
202 console.error('Unrecognized event object_path, skipping');
205 console.error('Unrecognized event, skipping');
207 } else if (response.transactionid === undefined) {
208 console.error('Badly formed response: ' + msg);
210 var calls = this.methodCalls;
211 for (var i = 0; i < calls.length; i++) {
213 if (call && (!call.done) && (call.transactionid === response.transactionid)) {
215 if (response.result !== 'succeeded' && response.reason !== undefined && call.errorCB !== undefined) {
216 call.errorCB(response.reason);
217 } else if (call.successCB !== undefined) {
218 if (response.value !== undefined) {
219 call.successCB(response.value);
230 function generateTransactionId() {
232 for (i = 0; i < 8; i++) {
233 var num = Math.floor((Math.random() + 1) * 65536);
234 val[i] = num.toString(16).substring(1);
236 var uuid = val[0] + val[1] + '-' + val[2] + '-' + val[3] + '-' + val[4] + '-' + val[5] + val[6] + val[7];
240 function sendRequest(request_type, request_name, request_args, success_cb, error_cb) {
242 'type': request_type,
243 'transactionid': generateTransactionId(),
244 'name': request_name,
245 'value': request_args
248 send(msg, success_cb, error_cb);
251 function subscribeEvents(callback) {
252 event_callbacks.add(callback);
255 function unsubscribeEvents(callback) {
256 event_callbacks.remove(callback);
259 /* this is dummy data for testing purposes */
260 function dummyBackendSend(msg) {
262 console.log('Sending to dummy server');
264 var calls = this.methodCalls;
267 for (var i = 0; i < calls.length; i++) {
269 if (call && (!call.done) && (call.transactionid === msg.transactionid)) {
271 if (msg.error !== undefined) {
273 call.errorCB(msg.error);
276 if (msg.value !== undefined && call.successCB !== undefined) {
278 case WS_REQUEST_TYPE.CONNMAN_MANAGER:
279 case WS_REQUEST_TYPE.CONNMAN_TECHNOLOGY:
280 if (msg.name === 'get_technologies') {
283 ["/net/connman/technology/ethernet",
291 ["/net/connman/technology/wifi",
299 ["/net/connman/technology/bluetooth",
310 replyMsg = JSON.stringify(results);
311 call.successCB(results);
313 } else if (msg.name === 'enable' && msg.value[1] === true) {
315 fireEvent(WS_EVENT_TYPE.CONNMAN, msg.value[0], 'PropertyChanged', ["Powered", true]);
317 } else if (msg.name === 'enable' && msg.value[1] === false) {
319 fireEvent(WS_EVENT_TYPE.CONNMAN, msg.value[0], 'PropertyChanged', ["Powered", false]);
321 } else if (msg.name === 'get_services' || msg.name === 'scan') {
324 ["/net/connman/service/ethernet_0010f32f5a70_cable",
330 "Domains": ["ftrdhcpuser.net"],
331 "Domains.Configuration": [],
333 "Address": "10:20:F3:2F:5E:23",
340 "Address": "192.168.1.20",
341 "Gateway": "192.168.1.1",
343 "Netmask": "255.255.255.0"
345 "IPv4.Configuration": {
349 "IPv6.Configuration": {
351 "Privacy": "disabled"
355 "Nameservers": ["192.168.1.1", "184.11.12.13"],
356 "Nameservers.Configuration": [],
361 "Proxy.Configuration": {},
362 "Timeservers": ["192.168.1.1", "pool.ntp.org"],
363 "Timeservers.Configuration": []
365 ["/net/connman/service/wifi_c8f733acdf96_3558364737_managed_psk",
373 "AutoConnect": false,
374 "Name": "Access Point 1",
375 "BSSID": "11:5d:49:88:3d:20",
378 "EncryptionMode": "none",
381 "Interface": "wlp1s0",
382 "Address": "B2:D3:55:66:44:22",
386 "Address": "192.168.1.20",
387 "Gateway": "192.168.1.1",
389 "Netmask": "255.255.255.0"
391 "IPv4.Configuration": {
395 "IPv6.Configuration": {
397 "Privacy": "disabled"
400 "Nameservers.Configuration": [],
402 "Timeservers.Configuration": [],
404 "Domains.Configuration": [],
406 "Proxy.Configuration": {},
409 ["/net/connman/service/wifi_c8f733acdf96_446f75636865626167_managed_psk",
417 "AutoConnect": false,
418 "Name": "Access Point 2",
419 "BSSID": "21:ef:30:b9:ad:86",
422 "EncryptionMode": "aes",
425 "Interface": "wlp1s0",
426 "Address": "E8:F2:33:AC:DF:96",
430 "IPv4.Configuration": {
434 "IPv6.Configuration": {
436 "Privacy": "disabled"
439 "Nameservers.Configuration": [],
441 "Timeservers.Configuration": [],
443 "Domains.Configuration": [],
445 "Proxy.Configuration": {},
448 ["/net/connman/service/wifi_c8f733acdf96_536563757265446f75636865626167_managed_psk",
456 "AutoConnect": false,
457 "Name": "Access Point 3",
458 "BSSID": "25:ad:44:b7:e3:66",
461 "EncryptionMode": "aes",
464 "Interface": "wlp1s0",
465 "Address": "A9:28:44:AD:FF:26",
469 "IPv4.Configuration": {
473 "IPv6.Configuration": {
475 "Privacy": "disabled"
478 "Nameservers.Configuration": [],
480 "Timeservers.Configuration": [],
482 "Domains.Configuration": [],
484 "Proxy.Configuration": {},
490 replyMsg = JSON.stringify(results);
491 /* simulate scan behavior */
492 setTimeout(function() {
493 call.successCB(results);
497 case WS_REQUEST_TYPE.CONNMAN_SERVICE:
498 if (msg.name === 'connect') {
499 if (msg.value[0] === '/net/connman/service/wifi_c8f733acdf96_3558364737_managed_psk' && msg.value[1].Passphrase !== '123') {
500 call.errorCB('Invalid passphrase');
501 } else if (msg.value[0] === '/net/connman/service/wifi_c8f733acdf96_446f75636865626167_managed_psk' && msg.value[1].Passphrase !== '123') {
502 call.errorCB('Invalid passphrase');
505 setTimeout(function() {
506 fireEvent(WS_EVENT_TYPE.CONNMAN, msg.value[0], 'PropertyChanged', ["Connected", true]);
510 } else if (msg.name === 'disconnect') {
512 setTimeout(function() {
513 fireEvent(WS_EVENT_TYPE.CONNMAN, msg.value[0], 'PropertyChanged', ["Connected", false]);
518 call.errorCB('Unsupported request: ' + msg.name + ', ' + msg.value);
523 case WS_REQUEST_TYPE.DATETIME:
524 if (msg.name === 'is_time_updates_auto' && msg.value !== undefined) {
525 /* default to manual */
526 call.successCB(false);
528 } else if (msg.name === 'is_timezone_updates_auto' && msg.value !== undefined) {
529 /* default to manual */
530 call.successCB(false);
532 } else if (msg.name === 'time' && msg.value !== undefined) {
535 } else if (msg.name === 'timezone' && msg.value !== undefined) {
538 } else if (msg.name === 'time_updates' && msg.value !== undefined) {
541 } else if (msg.name === 'timezone_updates' && msg.value !== undefined) {
546 call.errorCB('Unsupported request: ' + msg.name + ', ' + msg.value);
551 case WS_REQUEST_TYPE.DISPLAY:
552 case WS_REQUEST_TYPE.SOUND:
553 case WS_REQUEST_TYPE.LOCALE:
555 call.errorCB('Request not implemented');
560 call.errorCB('Invalid request type: ' + msg.type);
573 reconnect: reconnect,
574 sendRequest: sendRequest,
575 subscribeEvents: subscribeEvents,
576 unsubscribeEvents: unsubscribeEvents