From: James Ausmus Date: Thu, 23 Aug 2012 19:24:04 +0000 (-0700) Subject: Merge remote-tracking branch 'origin/master' into wheelsource X-Git-Tag: submit/release/20120910.223349~70 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=67200af744a5964cb541dab25f345acf90804ce0;hp=c498efb564c2ac425b8ba4ad2af2a670582c6607;p=profile%2Fivi%2Fautomotive-message-broker.git Merge remote-tracking branch 'origin/master' into wheelsource --- diff --git a/config b/config index 44830c7..bc39085 100644 --- a/config +++ b/config @@ -1,5 +1,5 @@ { "sources" : [ "../plugins/examplesourceplugin.so" ], - "sinks": [ "../plugins/examplesinkplugin.so", "../plugins/dbus/dbussinkplugin.so" ,"../plugins/tcpsink/websocketsinkplugin.so" ] + "sinks": [ "../plugins/examplesinkplugin.so", "../plugins/dbus/dbussinkplugin.so" ,"../plugins/websocketsink/websocketsinkplugin.so" ] } diff --git a/plugins/dbus/CMakeLists.txt b/plugins/dbus/CMakeLists.txt index a688c79..07464f3 100644 --- a/plugins/dbus/CMakeLists.txt +++ b/plugins/dbus/CMakeLists.txt @@ -3,8 +3,8 @@ include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs}) pkg_check_modules(gio REQUIRED gio-2.0) -set(dbussinkplugin_headers dbusplugin.h abstractproperty.h abstractdbusinterface.h dbusinterfacemanager.h accelerationproperty.h basicproperty.h) -set(dbussinkplugin_sources dbusplugin.cpp abstractproperty.cpp abstractdbusinterface.cpp dbusinterfacemanager.cpp accelerationproperty.cpp basicproperty.cpp) +set(dbussinkplugin_headers dbusplugin.h abstractproperty.h abstractdbusinterface.h dbusinterfacemanager.h accelerationproperty.h basicproperty.h properties.h) +set(dbussinkplugin_sources dbusplugin.cpp abstractproperty.cpp abstractdbusinterface.cpp dbusinterfacemanager.cpp accelerationproperty.cpp basicproperty.cpp properties.cpp) add_library(dbussinkplugin MODULE ${dbussinkplugin_sources}) set_target_properties(dbussinkplugin PROPERTIES PREFIX "") diff --git a/plugins/dbus/dbusplugin.h b/plugins/dbus/dbusplugin.h index abb7416..8007ec4 100644 --- a/plugins/dbus/dbusplugin.h +++ b/plugins/dbus/dbusplugin.h @@ -35,6 +35,12 @@ public: virtual std::string uuid(); protected: + template + void wantProperty(VehicleProperty::Property) + { + + } + PropertyDBusMap propertyDBusMap; }; diff --git a/plugins/dbus/properties.cpp b/plugins/dbus/properties.cpp new file mode 100644 index 0000000..e69de29 diff --git a/plugins/dbus/properties.h b/plugins/dbus/properties.h new file mode 100644 index 0000000..de7efed --- /dev/null +++ b/plugins/dbus/properties.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2012 Intel Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _PROPERTIES_H_H_H_ +#define _PROPERTIES_H_H_H_ + +#include "dbusplugin.h" +#include "abstractdbusinterface.h" + +class VehicleSpeedProperty: public AbstractDBusInterface, public DBusSink +{ +public: + AccelerationPropertyInterface(AbstractRoutingEngine* re, GDBusConnection* connection) + :AbstractDBusInterface("org.automotive.acceleration","/org/automotive/acceleration", connection), + DBusSink(re) + { + supportedChanged(re->supported()); + } + + void supportedChanged(PropertyList supportedProperties) + { + for(PropertyDBusMap itr = propertyDBusMap.begin(); itr != propertyDBusMap.end(); itr++) + { + if(ListPlusPlus(&supportedProperties).contains((*itr))) + { + routingEngine->subscribeToProperty((*itr), this); + + } + } + } +}; + +#endif diff --git a/plugins/websocketsink/CMakeLists.txt b/plugins/websocketsink/CMakeLists.txt index 2aac74c..eb1284b 100644 --- a/plugins/websocketsink/CMakeLists.txt +++ b/plugins/websocketsink/CMakeLists.txt @@ -1,6 +1,8 @@ - +include(CheckIncludeFiles) include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs}) +check_include_files(libwebsockets.h HAVE_WEBSOCKETS) + set(websocketsinkplugin_headers websocketsink.h websocketmanager.h) set(websocketsinkplugin_sources websocketsinkmanager.cpp websocketsink.cpp) add_library(websocketsinkplugin MODULE ${websocketsinkplugin_sources}) diff --git a/plugins/websocketsink/test/api.js b/plugins/websocketsink/test/api.js index b4e2a8e..48fb4f4 100644 --- a/plugins/websocketsink/test/api.js +++ b/plugins/websocketsink/test/api.js @@ -7,25 +7,85 @@ * */ -/* ------------------------ vehicle interface ----------------------------- */ +/***************************************************************************** +* Class name: Vehicle +* Description: +* A javascript implementation of the IVI vehicle API that communicates +* to the automotive message broker through a websocket +* Optional constructor arguments: +* sCB: success callback, called when socket is connected, argument is +* success message string +* eCB: error callback, called on socket close or error, argument is error +* message string +* url: the URL to use for the websocket, in the form "ws://host:port/script" +* protocol: the protocol to use for the websocket, default is "http-only" +* +* [Public Member functions] +* Function name: getSupportedEventTypes(type, writeable, successCB, errorCB) +* Description: +* Retrieves a list of vehicle events for the requested type +* Required arguments: +* type: target event or group to query (use empty string for all events) +* writeable: if true, return only writeable events, otherwise get all +* successCB: success callback, gets called with a string list of names +* for all the events and event groups that are children of the +* target. e.g. "vehicle_info" returns all events/groups with the +* vehicle_info prefix. If the target is an event group, it's +* omitted from the returned list +* errorCB: error callback, called with error message string +* +* Function name: get(type, successCB, errorCB) +* Description: +* Retrieves a list of event/value pairs for a target event or event group +* Required arguments: +* type: target event group to query (use empty string for all events) +* successCB: success callback, gets called with the event/value pair list +* for all event children of the target. The list is the in the +* form of data[n].name/data[n].value +* errorCB: error callback, called with error message string +* +* Function name: set(type, value, successCB, errorCB) +* Description: +* Sets a single event's value (triggers error if it's read-only) +* Required arguments: +* type: target event to set (an event group will trigger an error) +* successCB: success callback, gets called with the event/value pair +* that was successfully set in the form data.name/data.value +* errorCB: error callback, called with error message string +* +******************************************************************************/ -function Vehicle(socketUrl, sCB, eCB, calltimeout) +function Vehicle(sCB, eCB, url, protocol) { + /* store a copy of Vehicle this for reference in callbacks */ var self = this; + this.iSuccessCB = sCB; this.iErrorCB = eCB; - this.retries = 5; - this.connected = false; - this.transactionid = 0; - this.methodCalls = []; - this.methodIdx = 0; - this.timeouttime = (calltimeout == undefined)?5000:calltimeout; + /* variables for call management, supports up to 100 simultaneously */ + this.methodIdx = 0; + this.methodCalls = []; for(var i = 0; i < 100; i++) { this.methodCalls[i] = null; } + /* number of connection retries to attempt if the socket closes */ + this.retries = 5; + this.connected = false; + + /* timeout for method calls in milliseconds */ + this.timeouttime = 5000; + + /* default values for WebSocket */ + this.socketUrl = "ws://localhost:23000/vehicle"; + this.socketProtocol = "http-only"; + + /* override the websocket address if parameters are given */ + if(url != undefined) this.socketUrl = url; + if(protocol != undefined) this.socketProtocol = protocol; + this.VehicleMethodCall = function(id, name, successCB, errorCB) { var me = this; @@ -57,11 +117,17 @@ function Vehicle(socketUrl, sCB, eCB, calltimeout) function init() { if ("WebSocket" in window) { - self.socket = new WebSocket(socketUrl); + if(self.socketProtocol.length > 0) + { + self.socket = new WebSocket(self.socketUrl, self.socketProtocol); + } + else + { + self.socket = new WebSocket(self.socketUrl); + } self.socket.onopen = function() { self.connected = true; - this.send("client"); self.iSuccessCB((self.retries < 5)?"(RECONNECTED)":""); self.retries = 5; }; @@ -94,9 +160,22 @@ function Vehicle(socketUrl, sCB, eCB, calltimeout) init(); } +Vehicle.prototype.generateTransactionId = function() +{ + var i, val = []; + for(i = 0; i < 8; i++) + { + var num = Math.floor((Math.random()+1)*65536); + val[i] = num.toString(16).substring(1); + } + var uuid = val[0]+val[1]+"-"+ + val[2]+"-"+val[3]+"-"+val[4]+"-"+ + val[5]+val[6]+val[7]; + return uuid; +} + Vehicle.prototype.send = function(obj, successCB, errorCB) { - obj.transactionid = this.transactionid++; if(!this.connected) { if(errorCB != undefined) @@ -120,7 +199,7 @@ Vehicle.prototype.getSupportedEventTypes = function(type, writeable, successCB, "type" : "method", "name" : "getSupportedEventTypes", "writeable" : writeable, - "transactionid" : 0, + "transactionid" : this.generateTransactionId(), "data" : type }; this.send(obj, successCB, errorCB); @@ -131,7 +210,7 @@ Vehicle.prototype.get = function(type, successCB, errorCB) var obj = { "type" : "method", "name": "get", - "transactionid" : 0, + "transactionid" : this.generateTransactionId(), "data" : type }; this.send(obj, successCB, errorCB); @@ -142,7 +221,7 @@ Vehicle.prototype.set = function(type, value, successCB, errorCB) var obj = { "type" : "method", "name": "set", - "transactionid" : 0, + "transactionid" : this.generateTransactionId(), "data" : {"property" : type, "value" : value} }; this.send(obj, successCB, errorCB); diff --git a/plugins/websocketsink/test/servertest/client.html b/plugins/websocketsink/test/servertest/client.html new file mode 100644 index 0000000..9ef2ee3 --- /dev/null +++ b/plugins/websocketsink/test/servertest/client.html @@ -0,0 +1,17 @@ + + + + IVI API Tester + + + + + +
+
+
+
+ + + + diff --git a/plugins/websocketsink/test/server.html b/plugins/websocketsink/test/servertest/server.html similarity index 89% rename from plugins/websocketsink/test/server.html rename to plugins/websocketsink/test/servertest/server.html index 0e5d50c..43dc72a 100644 --- a/plugins/websocketsink/test/server.html +++ b/plugins/websocketsink/test/servertest/server.html @@ -12,7 +12,7 @@ word-wrap: break-word; } - + diff --git a/plugins/websocketsink/test/server.js b/plugins/websocketsink/test/servertest/server.js similarity index 97% rename from plugins/websocketsink/test/server.js rename to plugins/websocketsink/test/servertest/server.js index 54b5ee4..180c23f 100644 --- a/plugins/websocketsink/test/server.js +++ b/plugins/websocketsink/test/servertest/server.js @@ -59,7 +59,6 @@ function VehicleServer(socketUrl) self.socket.onopen = function() { PRINT.pass("Server READY"); - this.send("server"); }; self.socket.onclose = function() { @@ -173,5 +172,5 @@ VehicleServer.prototype.receive = function(msg) window.addEventListener('load', function () { "use strict"; PRINT.init("result"); - var server = new VehicleServer("ws://localhost:23000/vehicle"); + var server = new VehicleServer("ws://localhost:23023/vehicle?server"); }); diff --git a/plugins/websocketsink/test/test.js b/plugins/websocketsink/test/test.js index db4f8e2..ebeb4be 100644 --- a/plugins/websocketsink/test/test.js +++ b/plugins/websocketsink/test/test.js @@ -150,8 +150,7 @@ function error(msg) PRINT.fail(msg); } -function init() { +function init(url, protocol) { PRINT.init("result"); - window.vehicle = new Vehicle("ws://localhost:23000/vehicle", - start, error); + window.vehicle = new Vehicle(start, error, url, protocol); } diff --git a/plugins/websocketsink/websocketsink.cpp b/plugins/websocketsink/websocketsink.cpp index 587392a..c080ee6 100644 --- a/plugins/websocketsink/websocketsink.cpp +++ b/plugins/websocketsink/websocketsink.cpp @@ -31,13 +31,13 @@ -WebSocketSink::WebSocketSink(AbstractRoutingEngine* re) : AbstractSink(re) +WebSocketSink::WebSocketSink(AbstractRoutingEngine* re,libwebsocket *wsi,string uuid) : AbstractSink(re) { - + m_uuid = uuid; } string WebSocketSink::uuid() { - return "e43f6cad-60e3-4454-9638-01ffa9ab8c8f"; + return m_uuid; } void WebSocketSink::propertyChanged(VehicleProperty::Property property, boost::any value, string uuid) { diff --git a/plugins/websocketsink/websocketsink.h b/plugins/websocketsink/websocketsink.h index 6fb2cdc..e4c2d5e 100644 --- a/plugins/websocketsink/websocketsink.h +++ b/plugins/websocketsink/websocketsink.h @@ -22,16 +22,18 @@ #include #include #include "abstractsink.h" +#include class WebSocketSink : public AbstractSink { public: - WebSocketSink(AbstractRoutingEngine* re); + WebSocketSink(AbstractRoutingEngine* re,libwebsocket *wsi,string uuid); string uuid() ; void propertyChanged(VehicleProperty::Property property, boost::any value, string uuid); void supportedChanged(PropertyList supportedProperties); PropertyList subscriptions(); - +private: + string m_uuid; }; #endif // WEBSOCKETSINK_H diff --git a/plugins/websocketsink/websocketsinkmanager.cpp b/plugins/websocketsink/websocketsinkmanager.cpp index 0dc9912..9f6a992 100644 --- a/plugins/websocketsink/websocketsinkmanager.cpp +++ b/plugins/websocketsink/websocketsinkmanager.cpp @@ -18,6 +18,7 @@ #include "websocketsinkmanager.h" +#include "websocketsink.h" #include #include @@ -40,7 +41,7 @@ WebSocketSinkManager::WebSocketSinkManager(AbstractRoutingEngine* engine):Abstra protocollist[0] = { "http-only", websocket_callback, 0 }; protocollist[1] = { NULL, NULL, 0 }; - int port = 7681; + int port = 23000; const char *interface = "lo"; const char *ssl_cert_path = NULL; const char *ssl_key_path = NULL; @@ -49,20 +50,20 @@ WebSocketSinkManager::WebSocketSinkManager(AbstractRoutingEngine* engine):Abstra //Create a listening socket on port 23000 on localhost. context = libwebsocket_create_context(port, interface, protocollist,libwebsocket_internal_extensions,ssl_cert_path, ssl_key_path, -1, -1, options); } -void WebSocketSinkManager::addSink(libwebsocket* socket, VehicleProperty::Property property) +void WebSocketSinkManager::addSingleShotSink(libwebsocket* socket, VehicleProperty::Property property,string id) { AsyncPropertyRequest velocityRequest; - velocityRequest.property = VehicleProperty::VehicleSpeed; - velocityRequest.completed = [socket](AsyncPropertyReply* reply) { + velocityRequest.property = property; + velocityRequest.completed = [socket,id](AsyncPropertyReply* reply) { printf("Got property:%i\n",boost::any_cast(reply->value)); uint16_t velocity = boost::any_cast(reply->value); stringstream s; //TODO: Dirty hack hardcoded stuff, jsut to make it work. - s << "{\"type\":\"reply\",\"name\":\"Velocity\",\"arguments\":\"[\"" << velocity << "\"],\"transactionid\":\"aeff0345defaa03c132\"}"; + s << "{\"type\":\"methodReply\",\"name\":\"get\",\"data\":[{\"name\":\"running_status_speedometer\",\"value\":\"" << velocity << "\"}],\"transactionid\":\"" << id << "\"}"; string replystr = s.str(); - + printf("Reply: %s\n",replystr.c_str()); char *new_response = new char[LWS_SEND_BUFFER_PRE_PADDING + strlen(replystr.c_str()) + LWS_SEND_BUFFER_POST_PADDING]; new_response+=LWS_SEND_BUFFER_PRE_PADDING; @@ -76,6 +77,10 @@ void WebSocketSinkManager::addSink(libwebsocket* socket, VehicleProperty::Proper AsyncPropertyReply* reply = routingEngine->getPropertyAsync(velocityRequest); } +void WebSocketSinkManager::addSink(libwebsocket* socket, VehicleProperty::Property property,string uuid) +{ + WebSocketSink *sink = new WebSocketSink(m_engine,socket,uuid); +} extern "C" AbstractSinkManager * create(AbstractRoutingEngine* routingengine) { @@ -109,8 +114,8 @@ static int websocket_callback(struct libwebsocket_context *context,struct libweb } case LWS_CALLBACK_HTTP: { + //TODO: Verify that ALL requests get sent via LWS_CALLBACK_HTTP, so we can use that instead of LWS_CALLBACK_RECIEVE printf("requested URI: %s\n", (char*)in); - //This contains the JSON, but so does LWS_CALLBACK_RECEIVE... /*{ "type":"method", @@ -124,6 +129,7 @@ static int websocket_callback(struct libwebsocket_context *context,struct libweb if (!json_parser_load_from_data(parser,(char*)in,len,&error)) { printf("Error loading JSON\n"); + return 0; } JsonNode* node = json_parser_get_root(parser); @@ -150,6 +156,7 @@ static int websocket_callback(struct libwebsocket_context *context,struct libweb string type; string name; list arguments; + string data; //stringlist arguments string id; json_reader_read_member(reader,"type"); @@ -160,7 +167,7 @@ static int websocket_callback(struct libwebsocket_context *context,struct libweb name = json_reader_get_string_value(reader); json_reader_end_member(reader); - json_reader_read_member(reader,"Arguments"); + /*json_reader_read_member(reader,"Arguments"); g_assert(json_reader_is_array(reader)); for(int i=0; i < json_reader_count_elements(reader); i++) { @@ -170,30 +177,69 @@ static int websocket_callback(struct libwebsocket_context *context,struct libweb json_reader_end_element(reader); } json_reader_end_member(reader); - + */ + json_reader_read_member(reader,"data"); + printf("Data Type Name: %s\n",g_type_name(json_node_get_value_type(json_reader_get_value(reader)))); + data = json_reader_get_string_value(reader); + json_reader_end_member(reader); + //running_status_engine_speed json_reader_read_member(reader,"transactionid"); - id = json_reader_get_string_value(reader); + + //JsonNode *node = json_reader_get_value(reader); + //node-> + + //printf("Type Name: %s\n",gtype); + printf("Before\n"); + //GType gtype = json_reader_get_type(); + //json_reader_error_get_type(); + if (strcmp("gchararray",g_type_name(json_node_get_value_type(json_reader_get_value(reader)))) == 0) + { + //Type is a string + id = json_reader_get_string_value(reader); + } + else + { + stringstream strstr; + strstr << json_reader_get_int_value(reader); + id = strstr.str(); + } + //printf("After\n"); + //printf("New %s\n",id.c_str()); + //json_reader_get json_reader_end_member(reader); if (type == "method") { - if (name == "GetProperty") + if (name == "get") { - string arg = arguments.front(); - if (arg == "Velocity") + //GetProperty is going to be a singleshot sink. + //string arg = arguments.front(); + if (data== "running_status_speedometer") { printf("Found velocity\n"); //m_engine->subscribeToProperty(VehicleProperty::VehicleSpeed,this); - sinkManager->addSink(wsi,VehicleProperty::Property::VehicleSpeed); + sinkManager->addSingleShotSink(wsi,VehicleProperty::Property::VehicleSpeed,id); //libwebsocket_write(wsi, (unsigned char*)new_response, strlen(new_response), LWS_WRITE_TEXT); + } + else if (data == "running_status_engine_speed") + { + sinkManager->addSingleShotSink(wsi,VehicleProperty::Property::EngineSpeed,id); + } + //EngineSpeed + //AccelerationX } + else if (name == "Subscribe") + { + //Subscribe is a permanent sink, until unsubscription. + sinkManager->addSink(wsi,VehicleProperty::VehicleSpeed,id); + } } ///TODO: this will probably explode: diff --git a/plugins/websocketsink/websocketsinkmanager.h b/plugins/websocketsink/websocketsinkmanager.h index ae5f9ef..a8e6f97 100644 --- a/plugins/websocketsink/websocketsinkmanager.h +++ b/plugins/websocketsink/websocketsinkmanager.h @@ -28,7 +28,8 @@ class WebSocketSinkManager: public AbstractSinkManager { public: WebSocketSinkManager(AbstractRoutingEngine* engine); - void addSink(libwebsocket *socket,VehicleProperty::Property property); + void addSingleShotSink(libwebsocket* socket, VehicleProperty::Property property,string id); + void addSink(libwebsocket* socket, VehicleProperty::Property property,string uuid); private: AbstractRoutingEngine *m_engine; struct libwebsocket_protocols protocollist[2];