summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevron Rees <kevron.m.rees@intel.com>2015-01-06 18:04:43 -0800
committerKevron Rees <kevron.m.rees@intel.com>2015-01-06 18:07:33 -0800
commit929bbf10db342c15f01437b14c648f3c38775ee7 (patch)
treed883285feff32e2ccf4d69704d26b1e725b6f48d
parent36f48c13d78f7ae0299862af9a3fc8f96a8f687b (diff)
downloadautomotive-message-broker-929bbf10db342c15f01437b14c648f3c38775ee7.tar.gz
[websocket] - added protocol documentation
-rw-r--r--examples/CMakeLists.txt47
-rw-r--r--examples/bluemonkey/bluemonkeyconfig.in.json33
-rw-r--r--examples/cangenconfig.in.json6
-rw-r--r--examples/configwheel.in.json26
-rw-r--r--examples/databasesource.in.json26
-rw-r--r--examples/databasewebsocketsink.in.json29
-rw-r--r--examples/dbusconfig.in.json28
-rw-r--r--examples/exampleconfig.in.json26
-rw-r--r--examples/gpsnmea.in.json26
-rw-r--r--examples/obdsourceconfig.in.json30
-rw-r--r--examples/opencvdbusconfig.in.json54
-rw-r--r--examples/opencvluxconfig.in.json42
-rw-r--r--examples/qtmainloopconfig.in.json30
-rw-r--r--examples/testsourceconfig.in.json24
-rw-r--r--examples/websocketsink2.in.json36
-rw-r--r--examples/websocketsource2.in.json42
-rw-r--r--lib/abstractroutingengine.h23
-rw-r--r--lib/vehicleproperty.cpp10
-rw-r--r--plugins/testplugin/testplugin.cpp2
-rw-r--r--plugins/websocket/CMakeLists.txt16
-rw-r--r--plugins/websocket/Doxyfile.in4
-rw-r--r--plugins/websocket/protocol40
-rw-r--r--plugins/websocket/protocol.idl440
-rw-r--r--plugins/websocket/test/servertest/client.html17
-rw-r--r--plugins/websocket/test/servertest/server.html22
-rw-r--r--plugins/websocket/test/servertest/server.js312
-rw-r--r--plugins/websocket/websocketsinkmanager.cpp23
-rw-r--r--plugins/websocket/websocketsinkmanager.h2
-rw-r--r--plugins/websocket/websocketsource.cpp72
-rw-r--r--plugins/websocket/websocketsource.h3
-rw-r--r--tools/ambctl.py2
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: