2 * Copyright (c) 2012, 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 /*****************************************************************************
13 * A javascript implementation of the IVI vehicle API that communicates
14 * to the automotive message broker through a websocket
15 * Optional constructor arguments:
16 * sCB: success callback, called when socket is connected, argument is
17 * success message string
18 * eCB: error callback, called on socket close or error, argument is error
20 * url: the URL to use for the websocket, in the form "ws://host:port/script"
21 * protocol: the protocol to use for the websocket, default is "http-only"
23 * [Public Member functions]
24 * Function name: getSupportedEventTypes(type, writeable, successCB, errorCB)
26 * Retrieves a list of vehicle events for the requested type
28 * type: target event or group to query (use empty string for all events)
29 * writeable: if true, return only writeable events, otherwise get all
30 * successCB: success callback, gets called with a string list of names
31 * for all the events and event groups that are children of the
32 * target. e.g. "vehicle_info" returns all events/groups with the
33 * vehicle_info prefix. If the target is an event group, it's
34 * omitted from the returned list
35 * errorCB: error callback, called with error message string
37 * Function name: get(type, successCB, errorCB)
39 * Retrieves a list of event/value pairs for a target event or event group
41 * type: target event group to query (use empty string for all events)
42 * successCB: success callback, gets called with the event/value pair list
43 * for all event children of the target. The list is the in the
44 * form of data[n].name/data[n].value
45 * errorCB: error callback, called with error message string
47 * Function name: set(type, value, successCB, errorCB)
49 * Sets a single event's value (triggers error if it's read-only)
51 * type: target event to set (an event group will trigger an error)
52 * successCB: success callback, gets called with the event/value pair
53 * that was successfully set in the form data.name/data.value
54 * errorCB: error callback, called with error message string
56 ******************************************************************************/
58 function Vehicle(sCB, eCB, url, protocol)
60 /* store a copy of Vehicle this for reference in callbacks */
63 this.iSuccessCB = sCB;
66 /* variables for call management, supports up to 100 simultaneously */
68 this.methodCalls = [];
69 for(var i = 0; i < 100; i++)
71 this.methodCalls[i] = null;
74 /* number of connection retries to attempt if the socket closes */
76 this.connected = false;
78 /* timeout for method calls in milliseconds */
79 this.timeouttime = 5000;
81 /* default values for WebSocket */
82 this.socketUrl = "ws://localhost:23000/vehicle";
83 this.socketProtocol = "http-only";
85 /* override the websocket address if parameters are given */
86 if(url != undefined) this.socketUrl = url;
87 if(protocol != undefined) this.socketProtocol = protocol;
89 this.VehicleMethodCall = function(id, name, successCB, errorCB)
92 this.successCB = successCB;
93 this.errorCB = errorCB;
94 this.transactionid = id;
97 this.start = function()
99 me.timeout = setTimeout(function(){
100 if(me.errorCB != undefined)
102 me.errorCB("\""+me.name+"\" method timed out after "+self.timeouttime+"ms");
105 }, self.timeouttime);
107 this.finish = function()
109 if(me.timeout != undefined)
111 clearTimeout(me.timeout);
118 if ("WebSocket" in window)
120 if(self.socketProtocol.length > 0)
122 self.socket = new WebSocket(self.socketUrl, self.socketProtocol);
126 self.socket = new WebSocket(self.socketUrl);
128 self.socket.onopen = function()
130 self.connected = true;
131 self.iSuccessCB((self.retries < 5)?"(RECONNECTED)":"");
134 self.socket.onclose = function()
136 self.connected = false;
137 self.iErrorCB("socket closed "+((self.retries > 0)?"retrying in 5 seconds ...":""));
140 setTimeout(function(){
146 self.socket.onerror = function(e)
148 self.iErrorCB(e.data);
150 self.socket.onmessage = function (e)
152 self.receive(e.data);
157 console.log("This browser doesn't appear to support websockets!");
163 Vehicle.prototype.generateTransactionId = function()
166 for(i = 0; i < 8; i++)
168 var num = Math.floor((Math.random()+1)*65536);
169 val[i] = num.toString(16).substring(1);
171 var uuid = val[0]+val[1]+"-"+
172 val[2]+"-"+val[3]+"-"+val[4]+"-"+
173 val[5]+val[6]+val[7];
177 Vehicle.prototype.send = function(obj, successCB, errorCB)
181 if(errorCB != undefined)
183 errorCB("\""+obj.name+"\" method failed because socket is closed");
187 var i = this.methodIdx;
188 this.methodIdx = (this.methodIdx + 1)%100;
189 this.methodCalls[i] = new this.VehicleMethodCall(obj.transactionid,
190 obj.name, successCB, errorCB);
191 this.socket.send(JSON.stringify(obj));
192 this.methodCalls[i].start();
196 Vehicle.prototype.getSupportedEventTypes = function(type, writeable, successCB, errorCB)
200 "name" : "getSupportedEventTypes",
201 "writeable" : writeable,
202 "transactionid" : this.generateTransactionId(),
205 this.send(obj, successCB, errorCB);
208 Vehicle.prototype.get = function(type, successCB, errorCB)
213 "transactionid" : this.generateTransactionId(),
216 this.send(obj, successCB, errorCB);
219 Vehicle.prototype.set = function(type, value, successCB, errorCB)
224 "transactionid" : this.generateTransactionId(),
225 "data" : {"property" : type, "value" : value}
227 this.send(obj, successCB, errorCB);
230 Vehicle.prototype.receive = function(msg)
235 event = JSON.parse(msg);
238 self.iErrorCB("GARBAGE MESSAGE: "+msg);
242 if((event == undefined)||(event.type == undefined)||
243 (event.name == undefined)||(event.transactionid == undefined))
245 self.iErrorCB("BADLY FORMED MESSAGE: "+msg);
250 if(event.type === "methodReply")
252 var calls = this.methodCalls;
253 for(var i = 0; i < calls.length; i++)
256 if(call&&(!call.done)&&(call.transactionid === event.transactionid))
259 if(event.error != undefined)
261 call.errorCB(event.error);
265 call.successCB(event.data);