diff options
author | Kevron Rees <kevron.m.rees@intel.com> | 2015-01-06 18:04:43 -0800 |
---|---|---|
committer | Kevron Rees <kevron.m.rees@intel.com> | 2015-01-06 18:07:33 -0800 |
commit | 929bbf10db342c15f01437b14c648f3c38775ee7 (patch) | |
tree | d883285feff32e2ccf4d69704d26b1e725b6f48d | |
parent | 36f48c13d78f7ae0299862af9a3fc8f96a8f687b (diff) | |
download | automotive-message-broker-929bbf10db342c15f01437b14c648f3c38775ee7.tar.gz |
[websocket] - added protocol documentation
31 files changed, 837 insertions, 656 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index fe01e0a5..90ddc0b6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,22 +1,33 @@ -set(amb_examples configwheel databasesource dbusconfig exampleconfig - gpsnmea obdsourceconfig opencvluxconfig opencvdbusconfig qtmainloopconfig websocketsink2 websocketsource2 - testsourceconfig bluemonkey/bluemonkeyconfig) +set(amb_examples ${CMAKE_CURRENT_BINARY_DIR}/configwheel + ${CMAKE_CURRENT_BINARY_DIR}/databasesource + ${CMAKE_CURRENT_BINARY_DIR}/dbusconfig + ${CMAKE_CURRENT_BINARY_DIR}/exampleconfig + ${CMAKE_CURRENT_BINARY_DIR}/gpsnmea + ${CMAKE_CURRENT_BINARY_DIR}/obdsourceconfig + ${CMAKE_CURRENT_BINARY_DIR}/opencvluxconfig + ${CMAKE_CURRENT_BINARY_DIR}/opencvdbusconfig + ${CMAKE_CURRENT_BINARY_DIR}/qtmainloopconfig + ${CMAKE_CURRENT_BINARY_DIR}/websocketsink2 + ${CMAKE_CURRENT_BINARY_DIR}/websocketsource2 + ${CMAKE_CURRENT_BINARY_DIR}/testsourceconfig + ${CMAKE_CURRENT_BINARY_DIR}/bluemonkey/bluemonkeyconfig) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/configwheel.in.json ${CMAKE_CURRENT_SOURCE_DIR}/configwheel @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/databasesource.in.json ${CMAKE_CURRENT_SOURCE_DIR}/databasesource @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/databaselogging.in.json ${CMAKE_CURRENT_SOURCE_DIR}/databaselogging @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/dbusconfig.in.json ${CMAKE_CURRENT_SOURCE_DIR}/dbusconfig @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/exampleconfig.in.json ${CMAKE_CURRENT_SOURCE_DIR}/exampleconfig @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/gpsnmea.in.json ${CMAKE_CURRENT_SOURCE_DIR}/gpsnmea @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/obdsourceconfig.in.json ${CMAKE_CURRENT_SOURCE_DIR}/obdsourceconfig @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/opencvluxconfig.in.json ${CMAKE_CURRENT_SOURCE_DIR}/opencvluxconfig @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/opencvdbusconfig.in.json ${CMAKE_CURRENT_SOURCE_DIR}/opencvdbusconfig @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/qtmainloopconfig.in.json ${CMAKE_CURRENT_SOURCE_DIR}/qtmainloopconfig @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/websocketsink2.in.json ${CMAKE_CURRENT_SOURCE_DIR}/websocketsink2 @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/websocketsource2.in.json ${CMAKE_CURRENT_SOURCE_DIR}/websocketsource2 @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/testsourceconfig.in.json ${CMAKE_CURRENT_SOURCE_DIR}/testsourceconfig @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cangenconfig.in.json ${CMAKE_CURRENT_SOURCE_DIR}/cangenconfig @ONLY) -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/bluemonkey/bluemonkeyconfig.in.json ${CMAKE_CURRENT_SOURCE_DIR}/bluemonkey/bluemonkeyconfig @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/configwheel.in.json ${CMAKE_CURRENT_BINARY_DIR}/configwheel @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/databasesource.in.json ${CMAKE_CURRENT_BINARY_DIR}/databasesource @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/databaselogging.in.json ${CMAKE_CURRENT_BINARY_DIR}/databaselogging @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/dbusconfig.in.json ${CMAKE_CURRENT_BINARY_DIR}/dbusconfig @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/exampleconfig.in.json ${CMAKE_CURRENT_BINARY_DIR}/exampleconfig @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/gpsnmea.in.json ${CMAKE_CURRENT_BINARY_DIR}/gpsnmea @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/obdsourceconfig.in.json ${CMAKE_CURRENT_BINARY_DIR}/obdsourceconfig @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/opencvluxconfig.in.json ${CMAKE_CURRENT_BINARY_DIR}/opencvluxconfig @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/opencvdbusconfig.in.json ${CMAKE_CURRENT_BINARY_DIR}/opencvdbusconfig @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/qtmainloopconfig.in.json ${CMAKE_CURRENT_BINARY_DIR}/qtmainloopconfig @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/websocketsink2.in.json ${CMAKE_CURRENT_BINARY_DIR}/websocketsink2 @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/websocketsource2.in.json ${CMAKE_CURRENT_BINARY_DIR}/websocketsource2 @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/databasewebsocketsink.in.json ${CMAKE_CURRENT_BINARY_DIR}/databasewebsocketsink @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/testsourceconfig.in.json ${CMAKE_CURRENT_BINARY_DIR}/testsourceconfig @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/cangenconfig.in.json ${CMAKE_CURRENT_BINARY_DIR}/cangenconfig @ONLY) +configure_file (${CMAKE_CURRENT_SOURCE_DIR}/bluemonkey/bluemonkeyconfig.in.json ${CMAKE_CURRENT_BINARY_DIR}/bluemonkey/bluemonkeyconfig @ONLY) install (FILES ${amb_examples} DESTINATION /etc/ambd/examples) diff --git a/examples/bluemonkey/bluemonkeyconfig.in.json b/examples/bluemonkey/bluemonkeyconfig.in.json index 0ba2c813..ea92a3dc 100644 --- a/examples/bluemonkey/bluemonkeyconfig.in.json +++ b/examples/bluemonkey/bluemonkeyconfig.in.json @@ -1,21 +1,18 @@ { - "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so", - - "sources" : [ - { - "path" : "@PLUGIN_INSTALL_PATH@/bluemonkeyplugin.so", - "config" : "/etc/ambd/bluemonkey/config.js" - } - ], - - "sinks" : [ - - { - "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" - }, - { - "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" - } - ] + "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so", + "sources" : [ + { + "path" : "@PLUGIN_INSTALL_PATH@/bluemonkeyplugin.so", + "config" : "/etc/ambd/bluemonkey/config.js" + } + ], + "sinks" : [ + { + "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" + }, + { + "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" + } + ] } diff --git a/examples/cangenconfig.in.json b/examples/cangenconfig.in.json index 81add2cb..9886c7a9 100644 --- a/examples/cangenconfig.in.json +++ b/examples/cangenconfig.in.json @@ -1,11 +1,11 @@ { - "sources" : [ + "sources" : [ { "name" : "CANSimPlugin", "path":"@PLUGIN_INSTALL_PATH@/cansimplugin.so", "interfaces" : ["vcan0", "vcan1"] - }, - { + }, + { "name" : "CANGenPlugin", "path":"@PLUGIN_INSTALL_PATH@/cangenplugin.so" } diff --git a/examples/configwheel.in.json b/examples/configwheel.in.json index ebd9335e..2bef1ed2 100644 --- a/examples/configwheel.in.json +++ b/examples/configwheel.in.json @@ -1,16 +1,16 @@ { - "sources" : [ - { - "name" : "WheelSource", - "path" : "@PLUGIN_INSTALL_PATH@/wheelsourceplugin.so", - "device" : "/dev/input/js0" - } - ], - "sinks": [ - { - "name" : "DBusSink", - "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" - } - ] + "sources" : [ + { + "name" : "WheelSource", + "path" : "@PLUGIN_INSTALL_PATH@/wheelsourceplugin.so", + "device" : "/dev/input/js0" + } + ], + "sinks": [ + { + "name" : "DBusSink", + "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" + } + ] } diff --git a/examples/databasesource.in.json b/examples/databasesource.in.json index 69ab8cb9..cc21c85e 100644 --- a/examples/databasesource.in.json +++ b/examples/databasesource.in.json @@ -1,16 +1,16 @@ { - "sources" : [ - { - "name" : "Database Source", - "path" : "@PLUGIN_INSTALL_PATH@/databasesinkplugin.so", - "playbackOnLoad" : "true", - "databaseFile" : "/tmp/storage" - } - ], - "sinks": [ - { - "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" - } - ] + "sources" : [ + { + "name" : "Database Source", + "path" : "@PLUGIN_INSTALL_PATH@/databasesinkplugin.so", + "playbackOnLoad" : "true", + "databaseFile" : "/tmp/storage" + } + ], + "sinks": [ + { + "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" + } + ] } diff --git a/examples/databasewebsocketsink.in.json b/examples/databasewebsocketsink.in.json new file mode 100644 index 00000000..54b8bf76 --- /dev/null +++ b/examples/databasewebsocketsink.in.json @@ -0,0 +1,29 @@ +{ + "sources" : [ + { + "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so" + }, + { + "name" : "Database", + "path" : "@PLUGIN_INSTALL_PATH@/databasesinkplugin.so", + "databaseFile" : "../tests/generated.db", + "bufferLength" : "1", + "properties" : "{ 'properties' : ['VehicleSpeed','EngineSpeed'] }", + "startOnLoad" : "true", + "playbackOnLoad" : "false", + "playbackMultiplier" : "1", + "frequency" : "1" + } + ], + "sinks": [ + { + "name" : "WebSocketSink", + "path" : "@PLUGIN_INSTALL_PATH@/websocketsink.so", + "interface" : "lo", + "ssl" : "false", + "port" : "23000", + "binaryProtocol" : "false", + "useExtensions" : "true" + } + ] +} diff --git a/examples/dbusconfig.in.json b/examples/dbusconfig.in.json index 22ebc564..d554f4f5 100644 --- a/examples/dbusconfig.in.json +++ b/examples/dbusconfig.in.json @@ -1,18 +1,18 @@ { - "sources" : [ - { - "name" : "ExampleSouce", - "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so", - "delay" : "6" - } - ], - "sinks": [ - { - "name" : "DBusSink", - "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so", - "frequency" : "30" - } + "sources" : [ + { + "name" : "ExampleSouce", + "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so", + "delay" : "6" + } + ], + "sinks": [ + { + "name" : "DBusSink", + "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so", + "frequency" : "30" + } - ] + ] } diff --git a/examples/exampleconfig.in.json b/examples/exampleconfig.in.json index f6c3520a..fef96698 100644 --- a/examples/exampleconfig.in.json +++ b/examples/exampleconfig.in.json @@ -1,16 +1,16 @@ { - "sources" : [ - { - "name" : "ExampleSouce", - "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so", - "delay" : "1" - } - ], - "sinks": [ - { - "name" : "ExampleSink", - "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" - } - ] + "sources" : [ + { + "name" : "ExampleSouce", + "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so", + "delay" : "1" + } + ], + "sinks": [ + { + "name" : "ExampleSink", + "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" + } + ] } diff --git a/examples/gpsnmea.in.json b/examples/gpsnmea.in.json index 95f5602a..de4a93ab 100644 --- a/examples/gpsnmea.in.json +++ b/examples/gpsnmea.in.json @@ -1,16 +1,16 @@ { - "sources" : [ - { - "name" : "gps nmea plugin", - "path" : "@PLUGIN_INSTALL_PATH@/gpsnmea.so", - "test" : "true", - "device" : "/dev/ttyACM0" - } - ], - "sinks": [ - { - "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" - } - ] + "sources" : [ + { + "name" : "gps nmea plugin", + "path" : "@PLUGIN_INSTALL_PATH@/gpsnmea.so", + "test" : "true", + "device" : "/dev/ttyACM0" + } + ], + "sinks": [ + { + "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" + } + ] } diff --git a/examples/obdsourceconfig.in.json b/examples/obdsourceconfig.in.json index 57f4aa2a..1c28ebfe 100644 --- a/examples/obdsourceconfig.in.json +++ b/examples/obdsourceconfig.in.json @@ -1,18 +1,18 @@ { - "sources" : [ - { - "name" : "OBD2Source", - "path" : "@PLUGIN_INSTALL_PATH@/obd2sourceplugin.so", - "device" : "/dev/pts/5", - "baud" : "115200", - "bluetoothAdapter" : "" - } - ], - "sinks": [ - { - "name" : "ExampleSink", - "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" - } - ] + "sources" : [ + { + "name" : "OBD2Source", + "path" : "@PLUGIN_INSTALL_PATH@/obd2sourceplugin.so", + "device" : "/dev/pts/5", + "baud" : "115200", + "bluetoothAdapter" : "" + } + ], + "sinks": [ + { + "name" : "ExampleSink", + "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" + } + ] } diff --git a/examples/opencvdbusconfig.in.json b/examples/opencvdbusconfig.in.json index 7634c755..c1e4642c 100644 --- a/examples/opencvdbusconfig.in.json +++ b/examples/opencvdbusconfig.in.json @@ -1,30 +1,30 @@ { - "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so", - "sources" : [ - { - "name" : "OpenCV LUX", - "path" : "@PLUGIN_INSTALL_PATH@/opencvluxplugin.so", - "threaded" : "true", - "opencl" : "true", - "fps" : "30", - "pixelLowerBound" : "18", - "pixelUpperBound" : "255", - "device" : "0", - "codec" : "h264", - "logging" : "false", - "logfile" : "/tmp/video.avi", - "ddd" : "true", - "faceCascade" : "/usr/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml", - "eyeCascade" : "/usr/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml" - }, - { - "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so" - } - ], - "sinks": [ - { - "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so", - }, - ] + "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so", + "sources" : [ + { + "name" : "OpenCV LUX", + "path" : "@PLUGIN_INSTALL_PATH@/opencvluxplugin.so", + "threaded" : "true", + "opencl" : "true", + "fps" : "30", + "pixelLowerBound" : "18", + "pixelUpperBound" : "255", + "device" : "0", + "codec" : "h264", + "logging" : "false", + "logfile" : "/tmp/video.avi", + "ddd" : "true", + "faceCascade" : "/usr/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml", + "eyeCascade" : "/usr/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml" + }, + { + "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so" + } + ], + "sinks": [ + { + "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so", + }, + ] } diff --git a/examples/opencvluxconfig.in.json b/examples/opencvluxconfig.in.json index b6860614..7ca298a0 100644 --- a/examples/opencvluxconfig.in.json +++ b/examples/opencvluxconfig.in.json @@ -1,24 +1,24 @@ { - "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so", - "sources" : [ - { - "name" : "OpenCV Lux plugin", - "path" : "@PLUGIN_INSTALL_PATH@/opencvluxplugin.so", - "threaded" : "true", - "kinect" : "false", - "opencl" : "false", - "cuda" : "true", - "pixelLowerBound" : "0", - "pixelUpperBound" : "255", - "fps" : "30", - "device" : "0" - } - ], - "sinks": [ - { - "name" : "Example sink", - "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" - } - ] + "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so", + "sources" : [ + { + "name" : "OpenCV Lux plugin", + "path" : "@PLUGIN_INSTALL_PATH@/opencvluxplugin.so", + "threaded" : "true", + "kinect" : "false", + "opencl" : "false", + "cuda" : "true", + "pixelLowerBound" : "0", + "pixelUpperBound" : "255", + "fps" : "30", + "device" : "0" + } + ], + "sinks": [ + { + "name" : "Example sink", + "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" + } + ] } diff --git a/examples/qtmainloopconfig.in.json b/examples/qtmainloopconfig.in.json index 99a01542..fb959265 100644 --- a/examples/qtmainloopconfig.in.json +++ b/examples/qtmainloopconfig.in.json @@ -1,18 +1,18 @@ { - "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so", - "sources" : [ - { - "name" : "ExampleSouce", - "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so" - } - ], - "sinks": [ - { - "name" : "Example sink", - "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so", - "interface" : "lo", - "port" : "23000" - } - ] + "mainloop" : "@PLUGIN_INSTALL_PATH@/qtmainloopplugin.so", + "sources" : [ + { + "name" : "ExampleSouce", + "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so" + } + ], + "sinks": [ + { + "name" : "Example sink", + "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so", + "interface" : "lo", + "port" : "23000" + } + ] } diff --git a/examples/testsourceconfig.in.json b/examples/testsourceconfig.in.json index 01029c0d..6af6118e 100644 --- a/examples/testsourceconfig.in.json +++ b/examples/testsourceconfig.in.json @@ -1,15 +1,15 @@ { - "sources" : [ - { - "name" : "TestPlugin", - "path" : "@PLUGIN_INSTALL_PATH@/testplugin.so" - } - ], - "sinks": [ - { - "name" : "ExampleSink", - "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" - } - ] + "sources" : [ + { + "name" : "TestPlugin", + "path" : "@PLUGIN_INSTALL_PATH@/testplugin.so" + } + ], + "sinks": [ + { + "name" : "ExampleSink", + "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" + } + ] } diff --git a/examples/websocketsink2.in.json b/examples/websocketsink2.in.json index b326dbba..f74ab5d7 100644 --- a/examples/websocketsink2.in.json +++ b/examples/websocketsink2.in.json @@ -1,21 +1,21 @@ { - "sources" : [ - { - "name" : "ExampleSouce", - "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so", - "delay" : "10000" - } - ], - "sinks": [ - { - "name" : "WebSocketSink", - "path" : "@PLUGIN_INSTALL_PATH@/websocketsink.so", - "interface" : "eth1", - "ssl" : "false", - "port" : "23000", - "binaryProtocol" : "false", - "useExtensions" : "true" - } - ] + "sources" : [ + { + "name" : "ExampleSouce", + "path" : "@PLUGIN_INSTALL_PATH@/examplesourceplugin.so", + "delay" : "10000" + } + ], + "sinks": [ + { + "name" : "WebSocketSink", + "path" : "@PLUGIN_INSTALL_PATH@/websocketsink.so", + "interface" : "eth1", + "ssl" : "false", + "port" : "23000", + "binaryProtocol" : "false", + "useExtensions" : "true" + } + ] } diff --git a/examples/websocketsource2.in.json b/examples/websocketsource2.in.json index 053b1ab8..e072f58d 100644 --- a/examples/websocketsource2.in.json +++ b/examples/websocketsource2.in.json @@ -1,24 +1,24 @@ { - "sources" : [ - { - "name" : "WebsocketSource", - "path" : "@PLUGIN_INSTALL_PATH@/websocketsource.so", - "port" : "23000", - "ssl" : "false", - "ip" : "127.0.0.1", - "binaryProtocol" : "false", - "useExtensions" : "true" - } - ], - "sinks": [ - { - "name" : "DBusSink", - "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" - }, - { - "name" : "ExampleSink", - "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" - } - ] + "sources" : [ + { + "name" : "WebsocketSource", + "path" : "@PLUGIN_INSTALL_PATH@/websocketsource.so", + "port" : "23000", + "ssl" : "false", + "ip" : "127.0.0.1", + "binaryProtocol" : "false", + "useExtensions" : "true" + } + ], + "sinks": [ + { + "name" : "DBusSink", + "path" : "@PLUGIN_INSTALL_PATH@/dbussinkplugin.so" + }, + { + "name" : "ExampleSink", + "path" : "@PLUGIN_INSTALL_PATH@/examplesinkplugin.so" + } + ] } diff --git a/lib/abstractroutingengine.h b/lib/abstractroutingengine.h index 43df132f..cce0140e 100644 --- a/lib/abstractroutingengine.h +++ b/lib/abstractroutingengine.h @@ -157,6 +157,29 @@ public: return "PermissionDenied"; else if(err == ZoneNotSupported) return "ZoneNotSupported"; + + DebugOut(DebugOut::Warning) << "Could not translate error: " << err << endl; + return ""; + } + + /*! + * \brief strToError returns Error representing the string + */ + static Error strToError(std::string err) + { + if(err == "NoError") + return NoError; + else if(err == "Timeout") + return Timeout; + else if(err == "InvalidOperation") + return InvalidOperation; + else if(err == "PermissionDenied") + return PermissionDenied; + else if(err == "ZoneNotSupported") + return ZoneNotSupported; + + DebugOut(DebugOut::Warning) << "Could not translate error string: " << err << endl; + return NoError; } /*! diff --git a/lib/vehicleproperty.cpp b/lib/vehicleproperty.cpp index 35b58cc6..b0365907 100644 --- a/lib/vehicleproperty.cpp +++ b/lib/vehicleproperty.cpp @@ -538,20 +538,24 @@ AbstractPropertyType* VehicleProperty::getPropertyTypeForPropertyNameValue(Vehic if(registeredPropertyFactoryMap.count(name) > 0) { VehicleProperty::PropertyTypeFactoryCallback cb = registeredPropertyFactoryMap[name]; - if ( cb != NULL ) + if ( cb != nullptr ) { AbstractPropertyType* type = cb(); - if(type == NULL) + if(type == nullptr) + { throw std::runtime_error("Cannot return NULL in a PropertyTypeFactory"); + } if(value != "" ) + { type->fromString(value); + } return type; } } - DebugOut(DebugOut::Error)<<"Property not found"<<endl; + DebugOut(DebugOut::Warning) << "Property not found: " << name << endl; return nullptr; } diff --git a/plugins/testplugin/testplugin.cpp b/plugins/testplugin/testplugin.cpp index 5fa32c56..35679a93 100644 --- a/plugins/testplugin/testplugin.cpp +++ b/plugins/testplugin/testplugin.cpp @@ -45,7 +45,7 @@ void testBooleanToStringFromString() boolean.fromString(boolean.toString()); std::string isTrue2 = boolean.toString(); - g_assert(isTrue == isTrue2); + TEST(isTrue == isTrue2); } bool beginsWith(std::string a, std::string b) diff --git a/plugins/websocket/CMakeLists.txt b/plugins/websocket/CMakeLists.txt index a8a0fafa..4da95b28 100644 --- a/plugins/websocket/CMakeLists.txt +++ b/plugins/websocket/CMakeLists.txt @@ -38,12 +38,26 @@ target_link_libraries(websocketsource amb ${websockets_LIBRARIES} -L${CMAKE_CURR configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test/vehicle.js ${CMAKE_CURRENT_SOURCE_DIR}/test/vehicle.js) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test/test.js ${CMAKE_CURRENT_SOURCE_DIR}/test/test.js) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test/events.js ${CMAKE_CURRENT_SOURCE_DIR}/test/events.js) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/protocol ${CMAKE_CURRENT_SOURCE_DIR}/protocol) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test/index.html ${CMAKE_CURRENT_SOURCE_DIR}/test/index.html) install(TARGETS websocketsource LIBRARY DESTINATION ${PLUGIN_INSTALL_PATH}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/README ${CMAKE_CURRENT_BINARY_DIR}/websocket.README @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/protocol.idl ${CMAKE_CURRENT_BINARY_DIR}/docs/protocol.idl @ONLY) install (FILES ${CMAKE_CURRENT_BINARY_DIR}/websocket.README DESTINATION ${DOC_INSTALL_DIR}/plugins) +if(enable_docs) + find_package(Doxygen) + if(DOXYGEN_FOUND) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + add_custom_target(websocket_docs ALL ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating Websocket protocol documentation with Doxygen" VERBATIM) + + install (DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION ${DOC_INSTALL_DIR}/plugins/websocket COMPONENT Docs) + install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test DESTINATION ${DOC_INSTALL_DIR}/plugins/websocket COMPONENT Docs) + endif(DOXYGEN_FOUND) + +endif(enable_docs) + endif(websocket_plugin) diff --git a/plugins/websocket/Doxyfile.in b/plugins/websocket/Doxyfile.in new file mode 100644 index 00000000..ee0e2735 --- /dev/null +++ b/plugins/websocket/Doxyfile.in @@ -0,0 +1,4 @@ +PROJECT_NAME = @PROJECT_NAME@ +PROJECT_NUMBER = @PROJECT_VERSION@ +GENERATE_LATEX = NO +INPUT = @CMAKE_CURRENT_BINARY_DIR@/docs/ diff --git a/plugins/websocket/protocol b/plugins/websocket/protocol deleted file mode 100644 index 0a4eec93..00000000 --- a/plugins/websocket/protocol +++ /dev/null @@ -1,40 +0,0 @@ -Example protocol messages - -Property changed event: -{"type":"valuechanged","name":"VehicleSpeed","data":{"value": "217","zone": 0, 'type' : 'UInt16', "timestamp":"1354521964.60253","sequence":"0"}, "transactionid":"d293f670-f0b3-11e1-aff1-0800200c9a66", } - -Get property request: -{"type":"method","name":"get","data": { "property" : "VehicleSpeed", "zone" : 0 }, "transactionid":"d293f670-f0b3-11e1-aff1-0800200c9a66"} - -Get property reply: -{"type":"methodReply","name":"get","data":{"property":"VehicleSpeed","value":"17", "timestamp" : "1354521964.24962", "sequence": "0" },"transactionid":"d293f670-f0b3-11e1-aff1-0800200c9a66"} - -Get supported request: -{"type":"method","name":"getSupported","transactionid":"d293f670-f0b3-11e1-aff1-0800200c9a66"} - -Get supported reply: -{"type":"methodReply","name":"getSupported","data":[{'name' :'EngineSpeed', 'zone' : 0, 'type' : 'UInt16'}, "{'name' :'VehicleSpeed', 'zone' : 0, 'type' : 'UInt16'}],"transactionid":"d293f670-f0b3-11e1-aff1-0800200c9a66"} - -Supported Changed -{"type":"methodReply","name":"supportedChanged","data":[{'name' :'EngineSpeed', 'zone' : 0, 'type' : 'UInt16'}, "{'name' :'VehicleSpeed', 'zone' : 0, 'type' : 'UInt16'}],"transactionid":"d293f670-f0b3-11e1-aff1-0800200c9a66"} - -Subscribe to data: -{"type":"method","name":"subscribe","property":"EngineSpeed","transactionid":"d293f670-f0b3-11e1-aff1-0800200c9a66"} - -Subscribe to data reply: -{"type":"methodReply","name":"subscribe","property":"EngineSpeed","transactionid":"d293f670-f0b3-11e1-aff1-0800200c9a66"} - -Unsubscribe to data: -{"type":"method", "name":"unsubscribe", "property":"EngineSpeed", "transactionid":"d293f670-f0b3-11e1-aff1-0800200c9a66"} - -Get History request: -{"type" : "method", "name" : "getRange", "data" : ["VehicleSpeed"], "timeBegin" : 1368825008.35948, "timeEnd" : 1368825018.35948, "sequenceBegin" : -1, "sequenceEnd" : -1, "transactionid" : "b07589ba-417c-4604-80c6-01c0dcbd524d"} - -Get History reply: -{"data" : [{"name" : "EngineSpeed", "sequence":-1, "timestamp" : 143706.443, "value" : "13789"}], "name" : "getRanged", "transactionid" : "fe4a803e-d587-4fa0-bd5a-9cf689097d88", "type" : "methodReply"} - -Set property request: -{ "type" : "method", "name" : "set", "data" : { "property" : "MachineGunTurretStatus", "value" : "true", "zone" : 0 }, "transactionid" : "4123123123" } - -Set property reply: -{ "type" : "methodReply", "name" : "set", "data" : { "property" : "MachineGunTurretStatus", "value" : "true", "zone" : 0, "success" : true }, "transactionid" : "4123123123" } diff --git a/plugins/websocket/protocol.idl b/plugins/websocket/protocol.idl new file mode 100644 index 00000000..cb24cf1e --- /dev/null +++ b/plugins/websocket/protocol.idl @@ -0,0 +1,440 @@ +/*! + * \mainpage Websocket Plugin Protocol Documentation + * \version @PROJECT_VERSION@ + * + * <a href="../../../html/index.html">Back to AMB Documentation Main</a> + * \section intro Introduction + * This document describes the AMB Websocket protocol. The messages are passed either as JSON or in binary format. The binary format is + * defined by the <a href="http://doc.qt.io/qt-5/qjsondocument.html#toBinaryData">Qt project</a>. The JSON format is described in protocol.idl. + * + * For information about the using the plugin with AMB, see <a href="../../websocket.README">the plugin documentation</a> + * + * \section example Example javascript + * The following is an example of using the websocket protocol in html5. For a more complete example, see the <a href="../test/index.html">html test</a>. + * \code + * socket = new WebSocket('ws://localhost:23000/'); + * socket.onmessage = function (msg) + * { + * // we got a reply! + * console.log(msg); + * }; + * + * socket.onopen = function() { + * var obj = { + * "type" : "method", + * "name" : "getSupported", + * "transactionid" : 'ReallyUniqueId1', + * } + * socket.send(JSON.stringify(obj)); + * }; + * \endcode + */ + +/*! + * \file protocol.idl + * \brief this document describes the websocket protocol + * + */ + +enum MessageType { + "method", + "methodReply", + "valuechanged" +} + + +interface BaseMessage { + + /*! + * \brief transactionid, id for this transaction. For messages with responses, the transaction id is used to match the request with the response. + */ + attribute DOMString transactionid; +} + +enum PropertyType { + "UInt16", + "UInt32", + "Int16", + "Int32", + "String", + "Double", + "Boolean" +} + +/*! + * \brief Property represents an AMB property + */ +interface Property { + + /*! + * \brief property - AMB Property name + */ + attribute DOMString? property; + + /*! + * \brief value, value of the property + */ + attribute DOMString? value; + + /*! + * \brief zone, zone which this property is in + */ + attribute unsigned short zone; + + /*! + * \brief type - type of value + */ + attribute PropertyType? type; + + /*! + * \brief timestamp + */ + attribute unsigned double? timestamp; + + /*! + * \brief sequence + */ + attribute unsigned long? sequence; +} + +/*! + * \brief ValueChanged is a message which is generated when a subscribed Property changes. + * Subscribe will cause this message to be generated. Unsubscribe stops this message. + * \see Subscribe + * \see Unsubscribe + * The following is an example message for this interface: + * \code + * {"type" : "valuechanged", "name" : "VehicleSpeed", "data" : {"value" : "217", "zone" : 0, 'type' : 'UInt16', "timestamp" : "1354521964.60253", "sequence" : "0"}, "transactionid" : "d293f670-f0b3-11e1-aff1-0800200c9a66" } + * \endcode + */ +interface ValueChanged : BaseMessage { + + /*! + * \brief message type + */ + const MessageType type = "valuechanged"; + + /*! + * \brief name of this message. + * This represents the property name which changed in this message + */ + attribute DOMString name; + + /*! + * \brief data represents the value for the property indicated by 'name' + */ + attribute Property data; +} + +/*! + * \brief GetPropertyRequest - request the value of a property + * The following is an example of this message: + * \code + * {"type" : "method", "name" : "get", "data" : { "property" : "VehicleSpeed", "zone" : 0 }, "transactionid" : "d293f670-f0b3-11e1-aff1-0800200c9a66"} + * \endcode + */ +interface GetPropertyRequest : BaseMessage { + + /*! + * \brief message type + */ + const MessageType type = "method"; + + /*! + * \brief name of this message. + * This represents the property name which changed in this message + */ + const DOMString name = "get"; + + /*! + * \brief data represents property to get + * Property attributes type, timestamp, value, and sequence are ignored. + */ + attribute Property data; +} + +/*! + * \brief GetPropertyReply - response to GetPropertyRequest + * The following is an example of this message: + * \code + * {"type" : "methodReply", "name" : "get", "data" : {"property" : "VehicleSpeed", "value" : "17", "timestamp" : "1354521964.24962", "sequence" : "0" }, "transactionid" : "d293f670-f0b3-11e1-aff1-0800200c9a66"} + * \endcode + */ +interface GetPropertyReply : BaseMessage { + + /*! + * \brief message type + */ + const MessageType type = "methodReply"; + + /*! + * \brief name of this methodReply. + */ + const DOMString name = "get"; + + /*! + * \brief data represents the requested property value + */ + attribute Property data; +} + +/*! + * \brief GetSupportedRequest - request supported properties + * The following is an example of this message: + * \code + * {"type" : "method", "name" : "getSupported", "transactionid" : "d293f670-f0b3-11e1-aff1-0800200c9a66"} + * \endcode + */ +interface GetSupportedRequest : BaseMessage { + /*! + * \brief message type + */ + const MessageType type = "method"; + + /*! + * \brief name of this method. + */ + const DOMString name = "getSupported"; +} + +/*! + * \brief GetSupportedReply- reply for supported properties + * The following is an example of this message: + * \code + * {"type" : "methodReply", "name" : "getSupported", "data" : [{'property' :'EngineSpeed', 'zone' : 0, 'type' : 'UInt16'}, "{'property' :'VehicleSpeed', 'zone' : 0, 'type' : 'UInt16'}], "transactionid" : "d293f670-f0b3-11e1-aff1-0800200c9a66"} + * \endcode + */ +interface GetSupportedReply : BaseMessage { + /*! + * \brief message type + */ + const MessageType type = "methodReply"; + + /*! + * \brief name of this methodReply. + */ + const DOMString name = "getSupported"; + + /*! + * \brief data - array of properties supported by the system + */ + attribute Property[] data; +} + +/*! + * \brief SupportedChanged - message occures when the system's supported properties changes + * NOTE: this message is not being generated in 0.13 + * The following is an example of this message: + * \code + * {"type" : "methodReply", "name" : "supportedChanged", "data" : [{'property' :'EngineSpeed', 'zone' : 0, 'type' : 'UInt16'}, "{'property' :'VehicleSpeed', 'zone' : 0, 'type' : 'UInt16'}], "transactionid" : "d293f670-f0b3-11e1-aff1-0800200c9a66"} + * \endcode + */ +interface SupportedChanged : BaseMessage { + /*! + * \brief message type + */ + const MessageType type = "methodReply"; + + /*! + * \brief name of this methodReply. + */ + const DOMString name = "getSupported"; + + /*! + * \brief data - array of properties supported by the system + */ + attribute Property[] data; +} + +/*! + * \brief Subscribe - subscribe request + * The following is an example of this message: + * \code + * {"type" : "method", "name" : "subscribe", "property" : "EngineSpeed", "transactionid" : "d293f670-f0b3-11e1-aff1-0800200c9a66"} + * \endcode + */ +interface Subscribe : BaseMessage { + + /*! + * \brief message type + */ + const MessageType type = "method"; + + /*! + * \brief name of the method. + */ + const DOMString name = "subscribe"; + + /*! + * \brief property to subscribe to + */ + attribute DOMString property; +} + +/*! + * \brief Unsubscribe - unsubscribe request + * The following is an example of this message: + * \code + * {"type" : "method", "name" : "unsubscribe", "property" : "EngineSpeed", "transactionid" : "d293f670-f0b3-11e1-aff1-0800200c9a66"} + * \endcode + */ +interface Unsubscribe : BaseMessage { + + /*! + * \brief message type + */ + const MessageType type = "method"; + + /*! + * \brief name of the method. + */ + const DOMString name = "subscribe"; + + /*! + * \brief property to subscribe to + */ + attribute DOMString property; +} + +/*! + * \brief GetRangedRequest - request a range of logged properties + * The following is an example of this message: + * \code + * {"type" : "method", "name" : "getRange", "data" : ["VehicleSpeed", "EngineSpeed"], "timeBegin" : "1368825008.35948", + * "timeEnd" : "1368825018.35948", "sequenceBegin" : "-1", "sequenceEnd" : "-1", "transactionid" : "b07589ba-417c-4604-80c6-01c0dcbd524d"} + * \endcode + */ +interface GetRangedRequest : BaseMessage { + + /*! + * \brief message type + */ + const MessageType type = "method"; + + /*! + * \brief name of the method. + */ + const DOMString name = "getRange"; + + /*! + * \brief data - properties to request + */ + attribute DOMString[] data; + + /*! + * \brief zone, zone which this property is in + */ + attribute unsigned short? zone; + + /*! + * \brief timeBegin in seconds since Unix Epoc + */ + attribute unsigned double? timeBegin; + + /*! + * \brief timeEnd in seconds since Unix Epoc + */ + attribute unsigned double? timeEnd; + + /*! + * \brief sequenceBegin + */ + attribute unsigned long? sequenceBegin; + + /*! + * \brief sequenceEnd + */ + attribute unsigned long? sequenceEnd; +} + +/*! + * \brief GetRangedReply - reply for GetRangedRequest + * The following is an example of this message: + * \code + * {"type" : "methodReply", "name" : "getRanged", "data" : [{'property' :'EngineSpeed', 'zone' : 0, 'type' : 'UInt16'}, "{'property' :'VehicleSpeed', 'zone' : 0, 'type' : 'UInt16'}], "transactionid" : "d293f670-f0b3-11e1-aff1-0800200c9a66"} + * \endcode + */ +interface GetRangedReply : BaseMessage { + /*! + * \brief message type + */ + const MessageType type = "methodReply"; + + /*! + * \brief name of this methodReply. + */ + const DOMString name = "getRanged"; + + /*! + * \brief data - array of properties supported by the system + */ + attribute Property[] data; +} + +/*! + * \brief SetPropertyRequest - request to set a property + * The following is an example of this message: + * \code + * { "type" : "method", "name" : "set", "data" : { "property" : "MachineGunTurretStatus", "value" : "true", "zone" : 0 }, "transactionid" : "4123123123" } + * \endcode + */ +interface SetPropertyRequest : BaseMessage { + + /*! + * \brief message type + */ + const MessageType type = "method"; + + /*! + * \brief name of this methodReply. + */ + const DOMString name = "set"; + + /*! + * \brief data represents the new property value + */ + attribute Property data; +} + +enum Error { + "NoError", + "Timeout", + "InvalidOperation", + "PermissionDenied", + "ZoneNotSupported" +} + +/*! + * \brief SetPropertyReply - reply for SetPropertyRequest + * The following is an example of this message: + * \code + * { "type" : "methodReply", "name" : "set", "data" : { "property" : "MachineGunTurretStatus", "value" : "true", "zone" : 0}, "success" : true, "error" : "NoError", "transactionid" : "4123123123" } + * \endcode + */ +interface SetPropertyReply : BaseMessage { + + /*! + * \brief message type + */ + const MessageType type = "methodReply"; + + /*! + * \brief name of this methodReply. + */ + const DOMString name = "set"; + + /*! + * \brief data represents the new property value + */ + attribute Property data; + + /*! + * \brief success - true if the set operation was successful + */ + attribute boolean success; + + /*! + * \brief error - error code + */ + attribute Error error; +} diff --git a/plugins/websocket/test/servertest/client.html b/plugins/websocket/test/servertest/client.html deleted file mode 100644 index 9ef2ee3b..00000000 --- a/plugins/websocket/test/servertest/client.html +++ /dev/null @@ -1,17 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <title>IVI API Tester</title> - <meta charset="utf-8"> - <link rel="stylesheet" href="../style.css"/> - <script src="../api.js"></script> -</head> -<body onload='init("ws://localhost:23023/vehicle?client", "")'> - <div id="result"> - </div> - <div id="tester"> - </div> - <script src="../events.js"></script> - <script src="../test.js"></script> -</body> -</html> diff --git a/plugins/websocket/test/servertest/server.html b/plugins/websocket/test/servertest/server.html deleted file mode 100644 index 43dc72ab..00000000 --- a/plugins/websocket/test/servertest/server.html +++ /dev/null @@ -1,22 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <title>IVI API Server Test</title> - <meta charset="utf-8"> - <style> -#result { - position: absolute; - height: 99%; - width: 99%; - overflow-y: auto; - word-wrap: break-word; -} - </style> - <script src="../events.js"></script> - <script src="server.js"></script> -</head> -<body> - <div id="result"> - </div> -</body> -</html> diff --git a/plugins/websocket/test/servertest/server.js b/plugins/websocket/test/servertest/server.js deleted file mode 100644 index 3fcda404..00000000 --- a/plugins/websocket/test/servertest/server.js +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) 2012, Intel Corporation. - * - * This program is licensed under the terms and conditions of the - * Apache License, version 2.0. The full text of the Apache License is at - * http://www.apache.org/licenses/LICENSE-2.0 - * - */ - -/* --------------------------- utility code ------------------------------- */ - -var PRINT = { - logElement : null, - init : function(log_id) { - this.logElement = document.getElementById(log_id); - }, - - scrollToBottom : function() { - this.logElement.scrollTop = this.logElement.scrollHeight; - }, - - incoming : function(msg) { - this.logElement.innerHTML += "<div style='color: blue'> REQUEST: " + msg + "</div>"; - this.scrollToBottom(); - }, - - outgoing : function(msg) { - this.logElement.innerHTML += "<div style='color: purple'> RESPONSE: " + msg + "</div>"; - this.scrollToBottom(); - }, - - pass : function(msg) { - this.logElement.innerHTML += "<div style='color: green'> SUCCESS: " + msg + "</div>"; - this.scrollToBottom(); - }, - - fail : function(msg) { - this.logElement.innerHTML += "<div style='color: red'> FAIL: " + msg + "</div>"; - this.scrollToBottom(); - }, - - log : function(msg) { - this.logElement.innerHTML += "<div class='LogClass'> " + msg + "</div>"; - this.scrollToBottom(); - }, -} - -/* ----------------------------- test code --------------------------------- */ - -function VehicleServer(socketUrl) -{ - var self = this; - this.vehicleEventType = new VehicleEventType(); - this.subscriptions = []; - - this.Signal = function(name) - { - var me = this; - this.users = 0; - this.name = name; - this.start = function() { - if(me.users <= 0) - { - var interval = Math.floor(Math.random()*5000) + 1000; - me.timer = setInterval(function() { - var value = parseInt(self.vehicleEventType.getValue(me.name)) + 1; - self.vehicleEventType.setValue(me.name, value); - var obj = { - "type" : "valuechanged", - "name": me.name, - "data" : value - }; - self.socket.send(JSON.stringify(obj)); - }, interval); - } - me.users = 1; - } - this.stop = function() { - me.users--; - if((me.users <= 0)&&(me.timer != undefined)) - { - clearInterval(me.timer); - } - } - } - - function init() { - if ("WebSocket" in window) - { - var list = self.vehicleEventType.getValueEventList(); - for(var i = 0; i < list.length; i++) - { - self.subscriptions[i] = new self.Signal(list[i]); - } - - self.socket = new WebSocket(socketUrl); - self.socket.onopen = function() - { - PRINT.pass("Server READY"); - }; - self.socket.onclose = function() - { - PRINT.fail("Server CLOSED"); - }; - self.socket.onerror = function(e) - { - PRINT.fail("Server ERROR: "+e.data); - }; - self.socket.onmessage = function (e) - { - self.receive(e.data); - }; - } - else - { - PRINT.fail("This browser doesn't appear to support websockets!"); - } - } - init(); -} - -VehicleServer.prototype.subscribe = function(list) -{ - for(var i = 0; i < this.subscriptions.length; i++) - { - if(list.indexOf(this.subscriptions[i].name) >= 0) - { - this.subscriptions[i].start(); - } - } -} - -VehicleServer.prototype.unsubscribe = function(list) -{ - for(var i = 0; i < this.subscriptions.length; i++) - { - if(list.indexOf(this.subscriptions[i].name) >= 0) - { - this.subscriptions[i].stop(); - } - } -} - -VehicleServer.prototype.receive = function(msg) -{ - var event = JSON.parse(msg); - /* accept only methods with transaction ids */ - if((event == undefined)||(event.transactionid == undefined)|| - (event.type != "method")) - { - return; - } - - var obj; - PRINT.incoming(msg); - if(event.name === "getSupportedEventTypes") - { - var data; - if(event.writeable) - { - data = this.vehicleEventType.getValueEventList(event.data); - } - else - { - data = this.vehicleEventType.getSupportedEventList(event.data); - } - obj = { - "type" : "methodReply", - "name": event.name, - "transactionid" : event.transactionid, - "data" : data - }; - } - else if(event.name === "get") - { - var names = this.vehicleEventType.getValuesEventList(event.data); - if(names.length > 0) - { - obj = { - "type" : "methodReply", - "name": event.name, - "transactionid" : event.transactionid, - "data" : [] - }; - for(i in names) - { - var value = this.vehicleEventType.getValue(names[i]); - obj.data.push({"name" : names[i], "value" : value}); - } - } - else - { - obj = { - "type" : "methodReply", - "name": event.name, - "transactionid" : event.transactionid, - "error" : event.data + " is not a valid event" - }; - } - } - else if(event.name === "set") - { - var bad = []; - var good = []; - for(var i = 0; i < event.data.length; i++) - { - if((event.data[i].value != undefined) && - this.vehicleEventType.isValueEvent(event.data[i].property)) - { - this.vehicleEventType.setValue(event.data[i].property, parseInt(event.data[i].value)); - good[good.length] = event.data[i].property; - } - else - { - bad[bad.length] = event.data[i].property; - } - } - - obj = { - "type" : "methodReply", - "name": event.name, - "transactionid" : event.transactionid - }; - - if(bad.length > 0) - { - obj.error = "Failed to set:"; - for(var i = 0; i < bad.length; i++) - { - obj.error += " "+bad[i]; - } - } - - if(good.length > 0) - { - obj.data = "Successfully set:"; - for(var i = 0; i < good.length; i++) - { - obj.data += " "+good[i]; - } - } - } - else if(event.name === "subscribe") - { - var names = this.vehicleEventType.getValuesEventList(event.data); - if(names.length > 0) - { - obj = { - "type" : "methodReply", - "name": event.name, - "transactionid" : event.transactionid, - "data" : names - }; - for(i in names) - { - this.subscribe(names[i]); - } - } - else - { - obj = { - "type" : "methodReply", - "name": event.name, - "transactionid" : event.transactionid, - "error" : "no valid events provided" - }; - } - } - else if(event.name === "unsubscribe") - { - var names = this.vehicleEventType.getValuesEventList(event.data); - if(names.length > 0) - { - obj = { - "type" : "methodReply", - "name": event.name, - "transactionid" : event.transactionid, - "data" : names - }; - for(i in names) - { - this.unsubscribe(names[i]); - } - } - else - { - obj = { - "type" : "methodReply", - "name": event.name, - "transactionid" : event.transactionid, - "error" : "no valid events provided" - }; - } - } - else - { - obj = { - "type" : "methodReply", - "name": event.name, - "transactionid" : event.transactionid, - "error" : event.name + " is not a valid method" - }; - } - PRINT.outgoing(JSON.stringify(obj)); - this.socket.send(JSON.stringify(obj)); -} - -window.addEventListener('load', function () { - "use strict"; - PRINT.init("result"); - var server = new VehicleServer("ws://localhost:23023/vehicle?server"); -}); diff --git a/plugins/websocket/websocketsinkmanager.cpp b/plugins/websocket/websocketsinkmanager.cpp index b82c6b66..5975c65f 100644 --- a/plugins/websocket/websocketsinkmanager.cpp +++ b/plugins/websocket/websocketsinkmanager.cpp @@ -203,8 +203,10 @@ void WebSocketSinkManager::addSingleShotRangedSink(libwebsocket* socket, Propert { QVariantMap obj; obj["name"] = value->name.c_str(); + obj["property"] = value->name.c_str(); obj["value"] = value->toString().c_str(); obj["timestamp"] = value->timestamp; + obj["zone"] = value->zone; obj["sequence"] = value->sequence; list.append(obj); @@ -244,27 +246,33 @@ void WebSocketSinkManager::removeSink(libwebsocket* socket,VehicleProperty::Prop lwsWriteVariant(socket, reply); } } -void WebSocketSinkManager::setValue(libwebsocket* socket,VehicleProperty::Property property,string value,Zone::Type zone,string uuid) +void WebSocketSinkManager::setValue(libwebsocket* socket, VehicleProperty::Property property, string value,Zone::Type zone, string uuid) { - AbstractPropertyType* type = VehicleProperty::getPropertyTypeForPropertyNameValue(property,value); + AbstractPropertyType* type = VehicleProperty::getPropertyTypeForPropertyNameValue(property, value); AsyncSetPropertyRequest request; request.property = property; + request.value = type; request.zoneFilter = zone; request.completed = [&](AsyncPropertyReply* reply) { QVariantMap data; - data["property"] = property.c_str(); - data["zone"] = zone; - data["source"] = reply->value->sourceUuid.c_str(); - data["success"] = reply->success; + if(reply->value) + { + data["property"] = property.c_str(); + data["zone"] = zone; + data["source"] = reply->value->sourceUuid.c_str(); + data["value"] = reply->value->toString().c_str(); + } QVariantMap replyvar; replyvar["type"]="methodReply"; replyvar["name"]="set"; replyvar["data"]= data; replyvar["transactionid"]=uuid.c_str(); + replyvar["success"] = reply->success; + replyvar["error"] = AsyncPropertyReply::errorToStr(reply->error).c_str(); lwsWriteVariant(socket, replyvar); @@ -502,7 +510,7 @@ static int websocket_callback(struct libwebsocket_context *context,struct libweb { zone = data["zone"].toInt(); } - sinkManager->setValue(wsi,data["property"].toString().toStdString(), data["value"].toString().toStdString(), zone, id); + sinkManager->setValue(wsi, data["property"].toString().toStdString(), data["value"].toString().toStdString(), zone, id); } else if (name == "subscribe") { @@ -537,6 +545,7 @@ static int websocket_callback(struct libwebsocket_context *context,struct libweb QVariantMap map; map["zone"] = zone; map["name"] = i.c_str(); + map["property"] = i.c_str(); map["type"] = basicType.c_str(); map["source"] = source.c_str(); diff --git a/plugins/websocket/websocketsinkmanager.h b/plugins/websocket/websocketsinkmanager.h index 1d1594e8..1b2fba64 100644 --- a/plugins/websocket/websocketsinkmanager.h +++ b/plugins/websocket/websocketsinkmanager.h @@ -45,7 +45,7 @@ public: void init(); std::map<std::string, list<WebSocketSink*> > m_sinkMap; void setConfiguration(map<string, string> config); - void setValue(libwebsocket* socket,VehicleProperty::Property property,string value, Zone::Type zone, string uuid); + void setValue(libwebsocket* socket,VehicleProperty::Property property, string value, Zone::Type zone, string uuid); PropertyList getSupportedProperties(); AbstractRoutingEngine * router() { return routingEngine; } diff --git a/plugins/websocket/websocketsource.cpp b/plugins/websocket/websocketsource.cpp index 97a6496f..f4b2ff9e 100644 --- a/plugins/websocket/websocketsource.cpp +++ b/plugins/websocket/websocketsource.cpp @@ -377,7 +377,7 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket { doc = QJsonDocument::fromJson(d); DebugOut(7)<<d.data()<<endl; - } + } if(doc.isNull()) { @@ -391,8 +391,6 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket string name = call["name"].toString().toStdString(); string id = call["transactionid"].toString().toStdString(); - list<pair<string,string> > pairdata; - if(type == "multiframe") { manager->expectedMessageFrames = call["frames"].toInt(); @@ -464,7 +462,7 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket { QVariantMap d = p.toMap(); Zone::Type zone = d["zone"].toInt(); - std::string name = d["name"].toString().toStdString(); + std::string name = d["property"].toString().toStdString(); std::string proptype = d["type"].toString().toStdString(); std::string source = d["source"].toString().toStdString(); @@ -484,7 +482,7 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket { QVariantMap obj = d.toMap(); - std::string name = obj["name"].toString().toStdString(); + std::string name = obj["property"].toString().toStdString(); std::string value = obj["value"].toString().toStdString(); double timestamp = obj["timestamp"].toDouble(); int sequence = obj["sequence"].toInt(); @@ -516,7 +514,7 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket else if (name == "get") { - DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Got \"GET\" event:" << pairdata.size()<<endl; + DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Got \"GET\" reply" << endl; if (source->uuidReplyMap.find(id) != source->uuidReplyMap.end()) { QVariantMap obj = call["data"].toMap(); @@ -527,14 +525,15 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket int sequence = obj["sequence"].toInt(); Zone::Type zone = obj["zone"].toInt(); - AbstractPropertyType* v = VehicleProperty::getPropertyTypeForPropertyNameValue(property, value); + auto v = amb::make_unique(VehicleProperty::getPropertyTypeForPropertyNameValue(property, value)); + v->timestamp = timestamp; v->sequence = sequence; v->zone = zone; if (source->uuidReplyMap.find(id) != source->uuidReplyMap.end() && source->uuidReplyMap[id]->error != AsyncPropertyReply::Timeout) { - source->uuidReplyMap[id]->value = v; + source->uuidReplyMap[id]->value = v.get(); source->uuidReplyMap[id]->success = true; source->uuidReplyMap[id]->completed(source->uuidReplyMap[id]); source->uuidReplyMap.erase(id); @@ -544,15 +543,56 @@ static int callback_http_only(libwebsocket_context *context, struct libwebsocket { DebugOut() << "get methodReply has been recieved, without a request being in!. This is likely due to a request coming in after the timeout has elapsed.\n"; } - - delete v; } else { DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "GET Method Reply INVALID! Multiple properties detected, only single are supported!!!" << "\n"; } - //data will contain a property/value map. + + } + else if (name == "set") + { + DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Got \"SET\" event" << endl; + std::string id = call["transactionid"].toString().toStdString(); + + if(source->setReplyMap.find(id) != source->setReplyMap.end() && source->setReplyMap[id]->error != AsyncPropertyReply::Timeout) + { + AsyncPropertyReply* reply = source->setReplyMap[id]; + + reply->success = call["success"].toBool(); + reply->error = AsyncPropertyReply::strToError(call["error"].toString().toStdString()); + + QVariantMap obj = call["data"].toMap(); + + std::string property = obj["property"].toString().toStdString(); + std::string value = obj["value"].toString().toStdString(); + + double timestamp = obj["timestamp"].toDouble(); + int sequence = obj["sequence"].toInt(); + Zone::Type zone = obj["zone"].toInt(); + + auto v = amb::make_unique(VehicleProperty::getPropertyTypeForPropertyNameValue(property, value)); + + if(v) + { + v->timestamp = timestamp; + v->sequence = sequence; + v->zone = zone; + } + else + { + throw std::runtime_error("property may not be registered."); + } + + reply->value = v.get(); + reply->completed(reply); + source->setReplyMap.erase(id); + } + } + else + { + DebugOut(DebugOut::Warning) << "Unhandled methodReply: " << name << endl; } } @@ -720,23 +760,23 @@ AsyncPropertyReply * WebSocketSource::setProperty( AsyncSetPropertyRequest reque { AsyncPropertyReply* reply = new AsyncPropertyReply(request); + std::string uuid = amb::createUuid(); + QVariantMap data; data["property"] = request.property.c_str(); data["value"] = request.value->toString().c_str(); data["zone"] = request.zoneFilter; - QVariantMap replyvar; replyvar["type"] = "method"; replyvar["name"] = "set"; replyvar["data"] = data; - replyvar["transactionid"] = amb::createUuid().c_str(); + replyvar["transactionid"] = uuid.c_str(); lwsWriteVariant(clientsocket, replyvar); - ///TODO: we should actually wait for a response before we simply complete the call - reply->success = true; - reply->completed(reply); + setReplyMap[uuid] = reply; + return reply; } diff --git a/plugins/websocket/websocketsource.h b/plugins/websocket/websocketsource.h index c19a6e86..4af23ba2 100644 --- a/plugins/websocket/websocketsource.h +++ b/plugins/websocket/websocketsource.h @@ -52,9 +52,10 @@ public: void supportedChanged(const PropertyList &) {} void setConfiguration(std::map<std::string, std::string> config); - std::map<std::string,AsyncPropertyReply*> uuidReplyMap; + std::map<std::string, AsyncPropertyReply*> uuidReplyMap; std::map<std::string,double> uuidTimeoutMap; std::map<std::string, AsyncRangePropertyReply*> uuidRangedReplyMap; + std::map<std::string, AsyncPropertyReply*> setReplyMap; int partialMessageIndex; QByteArray incompleteMessage; diff --git a/tools/ambctl.py b/tools/ambctl.py index cfa92d2f..581f1062 100644 --- a/tools/ambctl.py +++ b/tools/ambctl.py @@ -165,7 +165,7 @@ def processCommand(command, commandArgs, noMain=True): if property == realValue: print propertyName + " = ", property else: - print "Error setting property" + print "Error setting property. Expected value: ", realValue, " Received: ", property return 1 elif command == "getHistory": if len(commandArgs) == 0: |