Updated package changelog.
authorShibata Makoto <shibata@mac.tec.toyota.co.jp>
Fri, 26 Apr 2013 11:48:04 +0000 (20:48 +0900)
committerShibata Makoto <shibata@mac.tec.toyota.co.jp>
Fri, 26 Apr 2013 11:48:55 +0000 (20:48 +0900)
Change-Id: I0c2fbe210babc5364e174d256528ac169bb72cb5
Signed-off-by: Shibata Makoto <shibata@mac.tec.toyota.co.jp>
40 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
README [new file with mode: 0644]
packaging/ico-vic-amb-plugin.changes [new file with mode: 0644]
packaging/ico-vic-amb-plugin.spec [new file with mode: 0644]
src/AMBformat.conf [new file with mode: 0644]
src/CMakeLists.txt [new file with mode: 0644]
src/ambinterface.cc [new file with mode: 0644]
src/ambinterface.h [new file with mode: 0644]
src/config.cc [new file with mode: 0644]
src/config.h [new file with mode: 0644]
src/controlwebsocket.cc [new file with mode: 0644]
src/controlwebsocket.h [new file with mode: 0644]
src/convert.cc [new file with mode: 0644]
src/convert.h [new file with mode: 0644]
src/datamessage.cc [new file with mode: 0644]
src/datamessage.h [new file with mode: 0644]
src/eventmessage.cc [new file with mode: 0644]
src/eventmessage.h [new file with mode: 0644]
src/messageformat.h [new file with mode: 0644]
src/mwinterface.cc [new file with mode: 0644]
src/mwinterface.h [new file with mode: 0644]
src/standardmessage.cc [new file with mode: 0644]
src/standardmessage.h [new file with mode: 0644]
src/viccommunicator.cc [new file with mode: 0644]
src/viccommunicator.h [new file with mode: 0644]
tests/CMakeLists.txt [new file with mode: 0644]
tests/configamb.cc [new file with mode: 0644]
tests/configamb.h [new file with mode: 0644]
tests/controlwebsocketclient.cc [new file with mode: 0644]
tests/controlwebsocketclient.h [new file with mode: 0644]
tests/controlwebsocketclientapp.cc [new file with mode: 0644]
tests/controlwebsocketclientapp.h [new file with mode: 0644]
tests/mwscenario.cc [new file with mode: 0644]
tests/scenarioengine.cc [new file with mode: 0644]
tests/scenarioengine.h [new file with mode: 0644]
tests/standardjsonmessage.cc [new file with mode: 0644]
tests/standardjsonmessage.h [new file with mode: 0644]
tests/startTestSuite.sh [new file with mode: 0755]
tests/websocketscenario.cc [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7847620
--- /dev/null
@@ -0,0 +1,54 @@
+project(ico-vic-amb-plugin)
+cmake_minimum_required(VERSION 2.8)
+
+set(CMAKE_BUILD_TYPE, Debug)
+
+include(FindPkgConfig)
+
+set(PROJECT_NAME "ico-vic-amb-plugin")
+set(PROJECT_VERSION "0.1.0")
+
+set (DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/automotive-message-broker/${PROJECT_NAME}" CACHE PATH "The directory the docs will be installed to")
+set (CONF_INSTALL_DIR "/etc/ambd" CACHE PATH "The directory the config will be installed to")
+
+add_definitions(-DPROJECT_VERSION="${PROJECT_VERSION}")
+add_definitions(-DPROJECT_NAME="${PROJECT_NAME}")
+
+set (LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
+set (LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/${CMAKE_LIBRARY_ARCHITECTURE}" CACHE STRING "Directory where lib will install")
+
+include (CMakeForceCompiler)
+option(ENABLE_ICECC "Enable icecc checking, for distributed compilation" OFF)
+
+if (ENABLE_ICECC)
+   find_program(ICECC icecc)
+    if (ICECC)
+        message(STATUS "icecc will be used for distributed compiling")
+        cmake_force_cxx_compiler(${ICECC} icecc)
+    else(ICECC)
+        message(STATUS "Not using icecc")
+    endif(ICECC)
+endif(ENABLE_ICECC)
+
+find_package(Boost REQUIRED)
+
+pkg_check_modules(glib REQUIRED glib-2.0 gobject-2.0)
+pkg_check_modules(gio REQUIRED gio-2.0)
+pkg_check_modules(json REQUIRED json-glib-1.0)
+pkg_check_modules(ambd REQUIRED automotive-message-broker)
+
+add_definitions(-std=c++0x)
+
+set(include_dirs ${libtool_INCLUDE_DIR} ${glib_INCLUDE_DIRS} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${json_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/lib /usr/include/amb)
+set(link_libraries -lamb ${libtool_LIBRARY} ${glib_LIBRARIES} ${json_LIBRARIES} -L${CMAKE_CURRENT_BINARY_DIR}/lib)
+
+set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${PROJECT_VERSION})
+add_custom_target(dist COMMAND git archive --prefix=${ARCHIVE_NAME}/ HEAD | bzip2 > ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.bz2 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+
+add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+
+set(ico-vic-amb-plugin_docs README)
+install (FILES ${ico-vic-amb-plugin_docs} DESTINATION ${DOC_INSTALL_DIR})
+
+add_subdirectory(src)
+add_subdirectory(tests)
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..e0b6a56
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,18 @@
+/**
+* Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+* 
+*/
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..2186cab
--- /dev/null
+++ b/README
@@ -0,0 +1,32 @@
+README
+
+===How to use ico-vic-amb-plugin.===
+==Necessary files.==
+ /etc/ambd/config (Configuration file of ambd)
+ /etc/ambd/AMBformat.conf (Configuration file of ico-vic-amb-plugin.)
+
+==Change==
+ /etc/ambd/config
+    Configuration file is written JSON format.
+    In order to use ico-vic-amb-plugin, it is necessary to rewrite value of "sources".
+
+    =Default
+    "sources" : [
+        {
+            "name" : "ExampleSource",
+            "path" : "/usr/lib/automotive-message-broker/examplesourceplugin.so"
+        }
+    ],
+
+    =Using ico-vic-amb-plugin
+    "sources" : [
+        {
+            "name" : "VehicleSource",
+            "path" : "/usr/lib/automotive-message-broker/vehicleplugin.so",
+            "configfile" : "/etc/ambd/AMBformat.conf"
+        }
+    ],
+
+
+ /etc/ambd/AMBformat.conf
+    Nothing.
diff --git a/packaging/ico-vic-amb-plugin.changes b/packaging/ico-vic-amb-plugin.changes
new file mode 100644 (file)
index 0000000..cfb1ef3
--- /dev/null
@@ -0,0 +1,3 @@
+* Fri Apr 26 2013 Shibata Makoto <shibata@mac.tec.toyota.co.jp> 2e12f9a
+- Import initial.
+
diff --git a/packaging/ico-vic-amb-plugin.spec b/packaging/ico-vic-amb-plugin.spec
new file mode 100644 (file)
index 0000000..2b1e6b6
--- /dev/null
@@ -0,0 +1,42 @@
+Name:       ico-vic-amb-plugin
+Summary:    Automotive Message Broker is a vehicle network abstraction system.
+Version:    0.1.1
+Release:    1
+Group:      System Environment/Daemons
+License:    LGPL v2.1
+URL:        ""
+Source0:    %{name}-%{version}.tar.bz2
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+Requires:      json-glib
+BuildRequires:  cmake
+BuildRequires:  boost-devel
+BuildRequires:  json-glib-devel
+BuildRequires:  automotive-message-broker-devel >= 0.6.9
+BuildRequires:  libwebsockets-devel
+
+%description 
+Collection of plugins for automotive-message-broker
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+%cmake
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+mkdir -p %{buildroot}/%{_sysconfdir}/ambd
+cp src/AMBformat.conf %{buildroot}/%{_sysconfdir}/ambd/
+
+%files
+%defattr(-,root,root,-)
+%{_libdir}/automotive-message-broker/*.so
+%{_sysconfdir}/ambd/AMBformat.conf
+%{_docdir}/automotive-message-broker/%{name}/README
diff --git a/src/AMBformat.conf b/src/AMBformat.conf
new file mode 100644 (file)
index 0000000..8bc741f
--- /dev/null
@@ -0,0 +1,973 @@
+{
+       "Config":
+       [
+               {
+                       "Section":"Common",
+                       "VehicleInfoDefine":
+                       [
+                               {
+                                       "KeyEventType":"VELOCITY",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"VehicleSpeed",
+                                                       "Type":"int",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"VehicleSpeed"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.vehicleSpeed",
+                    "DBusObject":"/org/automotive/runningstatus/vehicleSpeed"
+                               },
+                               {
+                                       "KeyEventType":"ENGINE_SPEED",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"EngineSpeed",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"EngineSpeed"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.engineSpeed",
+                    "DBusObject":"/org/automotive/runningstatus/engineSpeed"
+                },
+                               {
+                                       "KeyEventType":"SHIFT",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"TransmissionShiftPosition",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"ShiftPosition"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"TransmissionGearPostion",
+                                                       "Type":"int",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"GearPosition"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"TransmissionMode",
+                                                       "Type":"int",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Mode"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.transmission",
+                    "DBusObject":"/org/automotive/runningstatus/transmission"
+                },
+                               {
+                                       "KeyEventType":"ACCPEDAL_OPEN",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"ThrottlePosition",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"BRAKE_SIGNAL",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"WheelBrake",
+                            "Type":"bool",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"BRAKE_PRESSURE",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"WheelBrakePressure",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"WheelBrakePressure"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.WheelBrakePressure",
+                    "DBusObject":"/org/automotive/custom/WheelBrakePressure"
+                },
+                               {
+                                       "KeyEventType":"STEERING",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"SteeringWheelAngle",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"TURN_SIGNAL",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"TurnSignal",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"CLUTCH",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"ClutchStatus",
+                            "Type":"bool",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"OIL",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"EngineOilPressure",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"EngineOilLevel",
+                                                       "Type":"int",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"EngineOilLevel"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.EngineOilLevel",
+                    "DBusObject":"/org/automotive/custom/EngineOilLevel"
+                },
+                               {
+                                       "KeyEventType":"WARTER_TEMP",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"EngineCoolantTemperature",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefinde"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"MACHINEGUNTURRET",
+                                       "Status":
+                                       [
+                                               {
+                        "AMBPropertyName":"MachineGunTurretStatus",
+                        "Type":"bool",
+                        "AccessControl":"R",
+                        "Default":"0",
+                        "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"ACCELERATION",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"AccelerationX",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"X"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"AccelerataionY",
+                                                       "Type":"int",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Y"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"AccelerationZ",
+                                                       "Type":"int",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Z"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.acceleration",
+                    "DBusObject":"/org/automotive/runningstatus/acceleration"
+                },
+                               {
+                                       "KeyEventType":"MASSAIRFLOW",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"MassAirFlow",
+                            "Type":"uint16_t",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"BUTTON",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"ButtonEvent",
+                            "Type":"char",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"OUTSIDE",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"AirIntakeTemperature",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"BATTERY",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"ButteryVoltage",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"INSIDE",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"InteriorTemperature",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                },
+                               {
+                                       "KeyEventType":"ENGINEOIL",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"EngineOilTemperature",
+                            "Type":"int",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Temperature"
+                                               },
+                                               {
+                            "AMBPropertyName":"EngineOilRemaining",
+                            "Type":"uint16_t",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"Remaining"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.engineOil",
+                    "DBusObject":"/org/automotive/runningstatus/engineOil"
+                },
+                               {
+                                       "KeyEventType":"TIREPRESSURE",
+                                       "Status":
+                                       [
+                                               {
+                            "AMBPropertyName":"TirePressureLeftFront",
+                            "Type":"double",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"LeftFront"
+                                               },
+                                               {
+                            "AMBPropertyName":"TirePressureRightFront",
+                            "Type":"double",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"RightFront"
+                                               },
+                                               {
+                            "AMBPropertyName":"TirePressureLeftRear",
+                            "Type":"double",
+                            "AccessControl":"R",
+                            "Default":"0",
+                            "DBusProperty":"LeftRear"
+                                               },
+                                               {
+                        "AMBPropertyName":"TirePressureRightRear",
+                        "Type":"double",
+                        "AccessControl":"R",
+                        "Default":"0",
+                        "DBusProperty":"RightRear"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.tirePressure",
+                    "DBusObject":"/org/automotive/maintainance/tirePressure"
+                },
+                               {
+                                       "KeyEventType":"TIRETEMPERATURE",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"TireTemperatureLeftFront",
+                                                       "Type":"double",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"LeftFront"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"TireTemperatureRightFront",
+                                                       "Type":"double",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"RightFront"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"TireTemperatureLeftRear",
+                                                       "Type":"double",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"LeftRear"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"TireTemperatureRightRear",
+                                                       "Type":"double",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"RightRear"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.tireTemperature",
+                    "DBusObject":"/org/automotive/maintainance/tireTemperature"
+                               },
+                               {
+                                       "KeyEventType":"POWERMODE",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"VehiclePowerMode",
+                                                       "Type":"char",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"VehiclePowerMode"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.vehiclePowerMode",
+                    "DBusObject":"/org/automotive/runningstatus/vehiclePowerMode"
+                               },
+                               {
+                                       "KeyEventType":"TRIPMETER",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"TripMeterA",
+                                                       "Type":"uint16_t",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"A"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"TripMeterB",
+                                                       "Type":"uint16_t",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"B"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"TripMeterC",
+                                                       "Type":"uint16_t",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"C"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.tripMeter",
+                    "DBusObject":"/org/automotive/runningstatus/tripMeter"
+                               },
+                               {
+                                       "KeyEventType":"CRUISECONTROL",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"CruiseControlActive",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"CruiseControlSpeed",
+                                                       "Type":"uint16_t",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                               },
+                               {
+                                       "KeyEventType":"LIGHTSTATUS",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"LightHead",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"LightLeftTurn",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"LightRightTurn",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"LightParking",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"ParkingLightStatus"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"LightFog",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"LightHazard",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"LightBrake",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"LightHighBeam",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.ParkingLightStatus",
+                    "DBusObject":"/org/automotive/custom/ParkingLightStatus"
+                               },
+                               {
+                                       "KeyEventType":"INTERIORLIGHT",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"InteriorLightDriver",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"InteriorLightCenter",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"InteriorLightPassenger",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                               },
+                               {
+                                       "KeyEventType":"ENGINELOAD",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"EngineLoad",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                               },
+                               {
+                                       "KeyEventType":"HORN",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"Horn",
+                                                       "Type":"bool",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Undefined"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"Undefined",
+                    "DBusObject":"Undefined"
+                               },
+                               {
+                                       "KeyEventType":"FUEL_LEVEL",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"FuelLevel",
+                                                       "Type":"int",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Level"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.fuel",
+                    "DBusObject":"/org/automotive/runningstatus/fuel"
+                               },
+                               {
+                                       "KeyEventType":"FUEL",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"FuelConsumption",
+                                                       "Type":"uint16_t",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"InstantConsumption"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"FuelRange",
+                                                       "Type":"uint16_t",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Range"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"FuelEconomy",
+                                                       "Type":"uint16_t",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"InstantEconomy"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"FuelAverageEconomy",
+                                                       "Type":"uint16_t",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"AverageEconomy"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"FuelType",
+                                                       "Type":"char",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"FuelType"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"FuelPositionSide",
+                                                       "Type":"char",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"FuelPositionSide"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.fuel",
+                    "DBusObject":"/org/automotive/runningstatus/fuel"
+                               },
+                               {
+                                       "KeyEventType":"EXTERIORBRIGHTNESS",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"ExteriorBrightness",
+                                                       "Type":"uint16_t",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"ExteriorBrightness"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.exteriorBrightness",
+                    "DBusObject":"/org/automotive/environment/exteriorBrightness"
+                               },
+                               {
+                                       "KeyEventType":"LOCATION",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"Latitude",
+                                                       "Type":"double",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Latitude"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"Longitude",
+                                                       "Type":"double",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Longitude"
+                                               },
+                                               {
+                                                       "AMBPropertyName":"Altitude",
+                                                       "Type":"double",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Altitude"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.Latitude",
+                    "DBusObject":"/org/automotive/custom/Latitude"
+                               },
+                               {
+                                       "KeyEventType":"DIRECTION",
+                                       "Status":
+                                       [
+                                               {
+                                                       "AMBPropertyName":"Direction",
+                                                       "Type":"int",
+                                                       "AccessControl":"R",
+                                                       "Default":"0",
+                                                       "DBusProperty":"Direction"
+                                               }
+                                       ],
+                                       "sense":
+                                       [
+                                       ],
+                                       "event_mask":
+                                       [
+                                       ],
+                                       "Priority":1,
+                                       "DBusInterface":"org.automotive.Direction",
+                    "DBusObject":"/org/automotive/custom/Direction"
+                               }
+                       ],
+            "DefaultInfoPort":
+            {
+                "DataPort":25010,
+                "CtrlPort":25011
+            },
+            "CustomizeInfoPort":
+            {
+                "DataPort":25020,
+                "CtrlPort":25021
+            }
+               },
+               {
+                       "Section":"CarSim",
+                       "VehicleInfoList":
+                       [
+                               "VELOCITY",
+                               "LOCATION",
+                               "SHIFT"
+                       ]
+               }
+       ]
+}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9e2026f
--- /dev/null
@@ -0,0 +1,14 @@
+include(CheckIncludeFiles)
+
+include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} /usr/include/amb /usr/include/dbus-1.0)
+set(CMAKE_CXX_FLAGS "-g -Wall")
+set(vehicleplugin_headers config.h convert.h standardmessage.h datamessage.h eventmessage.h messageformat.h controlwebsocket.h mwinterface.h viccommunicator.h ambinterface.h)
+set(vehicleplugin_sources config.cc convert.cc standardmessage.cc eventmessage.cc datamessage.cc mwinterface.cc controlwebsocket.cc viccommunicator.cc ambinterface.cc)
+add_library(vehicleplugin MODULE ${vehicleplugin_sources})
+set_target_properties(vehicleplugin PROPERTIES PREFIX "")
+target_link_libraries(vehicleplugin amb websockets -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries})
+
+install(TARGETS vehicleplugin LIBRARY DESTINATION lib/automotive-message-broker)
+
+set(ico-vic-amb-plugin-conf_docs AMBformat.conf)
+install (FILES ${ico-vic-amb-plugin-conf_docs} DESTINATION ${CONF_INSTALL_DIR})
diff --git a/src/ambinterface.cc b/src/ambinterface.cc
new file mode 100644 (file)
index 0000000..9ff7ffa
--- /dev/null
@@ -0,0 +1,388 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+
+#include <memory>
+#include <sstream>
+
+#include "debugout.h"
+
+#include "ambinterface.h"
+#include "config.h"
+#include "convert.h"
+#include "mwinterface.h"
+#include "viccommunicator.h"
+
+extern "C" AbstractSource *
+create(AbstractRoutingEngine* routingengine, map<string, string> config)
+{
+    AMBIF *ambif = new AMBIF(routingengine, config);
+    Config *conf = new Config();
+    conf->readConfig(config["configfile"]);
+    VICCommunicator *communicator = new VICCommunicator();
+    MWIF *mwif = new MWIF();
+    Converter *converter = new Converter();
+    if (!ambif->initialize(communicator, conf)) {
+        DebugOut() << "Failed to initialize AMBIF\n";
+        delete ambif;
+        delete conf;
+        delete communicator;
+        delete converter;
+        return NULL;
+    }
+    if (!communicator->initialize(ambif, mwif, converter)) {
+        DebugOut() << "Failed to initialize VICCommunicator\n";
+        delete ambif;
+        delete conf;
+        delete communicator;
+        delete converter;
+        return NULL;
+    }
+    if (!mwif->initialize(communicator, conf)) {
+        DebugOut() << "Failed to initialize MWIF\n";
+        delete ambif;
+        delete conf;
+        delete communicator;
+        delete converter;
+        return NULL;
+    }
+    if (!converter->initialize(conf)) {
+        DebugOut() << "Failed to initialize Converter\n";
+        delete ambif;
+        delete conf;
+        delete communicator;
+        delete converter;
+        return NULL;
+    }
+    return ambif;
+}
+
+AMBIF::AMBIF(AbstractRoutingEngine *engine,
+             std::map<std::string, std::string> config) :
+        AbstractSource(engine, config)
+{
+}
+
+AMBIF::~AMBIF()
+{
+    propertylist.clear();
+    vehicleinfoArray.clear();
+    pthread_mutex_destroy(&mutex);
+}
+
+void
+AMBIF::getPropertyAsync(AsyncPropertyReply *reply)
+{
+    reply->success = false;
+    DebugOut() << "AMBIF " << "Get Request property : " << reply->property
+               << std::endl;
+    lock();
+    AMBVehicleInfo *vehicleinfo = find(reply->property);
+    DebugOut() << "AMBIF " << "Find Data : " << reply->property << std::endl;
+    if (vehicleinfo != NULL) {
+        reply->value = vehicleinfo->value;
+        reply->success = true;
+        reply->completed(reply);
+    }
+    unLock();
+}
+
+AsyncPropertyReply *
+AMBIF::setProperty(AsyncSetPropertyRequest request)
+{
+    DebugOut() << "AMBIF" << "Set Request propety : " << request.property
+               << std::endl;
+    lock();
+    AMBVehicleInfo *vehicleinfo = find(request.property);
+    if (vehicleinfo == NULL) {
+        unLock();
+        return NULL;
+    }
+    AsyncPropertyReply *reply = new AsyncPropertyReply(request);
+    reply->success = true;
+    DebugOut(10) << "AMBIF" << "Update Value!" << std::endl;
+    delete vehicleinfo->value;
+    vehicleinfo->value = request.value->copy();
+    reply->value = vehicleinfo->value;
+    communicator->setMWVehicleInfo(vehicleinfo);
+    DebugOut() << "AMBIF setProperty " << "Set Value(" << request.property
+               << "," << reply->value->toString() << ")" << std::endl;
+    reply->completed(reply);
+    routingEngine->updateProperty(vehicleinfo->name, vehicleinfo->value,
+                                  uuid());
+    unLock();
+    return reply;
+}
+
+PropertyList
+AMBIF::supported()
+{
+    return propertylist;
+}
+
+int
+AMBIF::supportedOperations()
+{
+    return Get | Set;
+}
+
+string
+AMBIF::uuid()
+{
+    return "f68f8b9a-fafb-4284-8ced-b45b5d720185";
+}
+
+void
+AMBIF::propertyChanged(VehicleProperty::Property property,
+                       AbstractPropertyType *value, std::string uuid)
+{
+    AMBVehicleInfo *vehicleinfo = find(property);
+    lock();
+    if (vehicleinfo != NULL) {
+        delete vehicleinfo->value;
+        vehicleinfo->value = value->copy();
+    }
+    unLock();
+}
+
+void
+AMBIF::setConfiguratin(std::map<std::string, std::string> config)
+{
+}
+
+bool
+AMBIF::initialize(VICCommunicator *comm, Config *conf)
+{
+    DebugOut() << "AMBIF Initialize\n";
+    communicator = comm;
+    mutex = PTHREAD_MUTEX_INITIALIZER;
+
+    vector<VehicleInfoDefine> table;
+    table = conf->getVehicleInfoConfig();
+    for (auto itr = table.begin(); itr != table.end(); itr++) {
+        for (auto itr2 = (*itr).status.begin(); itr2 != (*itr).status.end();
+             itr2++) {
+            AMBVehicleInfo vi;
+            vi.isCustom = false;
+            vi.name = (*itr2).ambPropertyName;
+            vi.value = VehicleProperty::getPropertyTypeForPropertyNameValue(
+                    vi.name, (*itr2).defaultvalue);
+            if (vi.value == nullptr) {
+                if (!registVehicleInfo(vi.name, (*itr2).type,
+                                       (*itr2).defaultvalue)) {
+                    DebugOut() << "AMBIF Initialize Couldn't regist property[" 
+                               << vi.name << "]\n";
+                    continue;
+                }
+                vi.value = VehicleProperty::getPropertyTypeForPropertyNameValue(
+                        vi.name, (*itr2).defaultvalue);
+                vi.isCustom = true;
+            }
+            vehicleinfoArray.push_back(vi);
+            propertylist.push_back(vi.name);
+            DebugOut() << "AMBIF Initialize regist propertyname = " 
+                       << vi.name << "\n";
+        }
+    }
+    routingEngine->setSupported(supported(), this);
+    return true;
+}
+
+AMBVehicleInfo *
+AMBIF::getPropertyRequest(std::string propertyname)
+{
+    DebugOut() << "AMBIF getPropertyRequest(" << propertyname << ")\n";
+    AsyncPropertyRequest request;
+    request.property = propertyname;
+    request.completed = [](AsyncPropertyReply *reply) {
+        if (reply->success) {
+            DebugOut() << "AMBIF getPropertyRequest completed success!!.\n";
+        }
+        else {
+            DebugOut() << "AMBIF getPropertyRequest completed false!!.\n";
+        }
+    };
+
+    AsyncPropertyReply *reply = routingEngine->getPropertyAsync(request);
+    lock();
+    AMBVehicleInfo *vehicleinfo = find(propertyname);
+    if (vehicleinfo == NULL) {
+        delete reply;
+        unLock();
+        return NULL;
+    }
+    if (vehicleinfo->value != reply->value && reply->success) {
+        delete vehicleinfo->value;
+        vehicleinfo->value = reply->value->copy();
+    }
+    delete reply;
+    unLock();
+    DebugOut() << "AMBIF getPropertyRequest after call "
+               << vehicleinfo->value->toString() << std::endl;
+    return vehicleinfo;
+}
+
+void
+AMBIF::setPropertyRequest(AMBVehicleInfo *vehicleinfo)
+{
+    AsyncSetPropertyRequest request;
+    request.property = vehicleinfo->name;
+    request.value = vehicleinfo->value;
+    request.completed = [](AsyncPropertyReply *reply) {
+        if (reply->success) {
+            DebugOut()<<"AMBIF" << reply->property << ":" << reply->value->toString() << std::endl;
+        }
+        else {
+            DebugOut()<<"AMBIF" << reply->property << " isn't registered." << std::endl;
+        }
+    };
+    AsyncPropertyReply *reply = routingEngine->setProperty(request);
+    if (reply != NULL) {
+        delete reply;
+    }
+}
+
+void
+AMBIF::updateProperty(AMBVehicleInfo *vehicleinfo)
+{
+    routingEngine->updateProperty(vehicleinfo->name, vehicleinfo->value,
+                                  uuid());
+    AMBVehicleInfo *ambvehicleinfo = find(vehicleinfo->name);
+    lock();
+    if (ambvehicleinfo != NULL) {
+        delete ambvehicleinfo->value;
+        ambvehicleinfo->value = vehicleinfo->value->copy();
+    }
+    unLock();
+}
+
+void
+AMBIF::lock()
+{
+    pthread_mutex_lock(&mutex);
+}
+
+void
+AMBIF::unLock()
+{
+    pthread_mutex_unlock(&mutex);
+}
+
+void
+AMBIF::requestUpdate(AMBVehicleInfo *vehicleinfo)
+{
+    DebugOut() << "AMBIF requestUpdate request property name is "
+               << vehicleinfo->name << "\n";
+    if (find(vehicleinfo->name) != NULL) {
+        updateProperty(vehicleinfo);
+    }
+    else {
+        setPropertyRequest(vehicleinfo);
+    }
+}
+
+bool
+AMBIF::registVehicleInfo(std::string propertyName,
+                         VehicleInfoDefine::Status::DataType type, string value)
+{
+    DebugOut() << "AMBIF registVehicleInfo(" << propertyName 
+               << ")\n";
+    VehicleProperty::PropertyTypeFactoryCallback factory;
+    switch (type) {
+    case VehicleInfoDefine::Status::INT:
+    {
+        factory = [value]() {
+            return new BasicPropertyType<int>(value);
+        };
+        break;
+    }
+    case VehicleInfoDefine::Status::DOUBLE:
+    {
+        factory = [value]() {
+            return new BasicPropertyType<double>(value);
+        };
+        break;
+    }
+    case VehicleInfoDefine::Status::CHAR:
+    {
+        factory = [value]() {
+            return new BasicPropertyType<char>(value);
+        };
+        break;
+    }
+    case VehicleInfoDefine::Status::INT16:
+    {
+        factory = [value]() {
+            return new BasicPropertyType<int16_t>(value);
+        };
+        break;
+    }
+    case VehicleInfoDefine::Status::UINT16:
+    {
+        factory = [value]() {
+            return new BasicPropertyType<uint16_t>(value);
+        };
+        break;
+    }
+    case VehicleInfoDefine::Status::UINT32:
+    {
+        factory = [value]() {
+            return new BasicPropertyType<uint32_t>(value);
+        };
+        break;
+    }
+    case VehicleInfoDefine::Status::INT64:
+    {
+        factory = [value]() {
+            return new BasicPropertyType<int64_t>(value);
+        };
+        break;
+    }
+    case VehicleInfoDefine::Status::UINT64:
+    {
+        factory = [value]() {
+            return new BasicPropertyType<uint64_t>(value);
+        };
+        break;
+    }
+    case VehicleInfoDefine::Status::BOOL:
+    {
+        factory = [value]() {
+            return new BasicPropertyType<bool>(value);
+        };
+        break;
+    }
+    default:
+    {
+        return false;
+    }
+    }
+    return VehicleProperty::registerProperty(propertyName, factory);
+}
+
+AMBVehicleInfo *
+AMBIF::find(std::string propertyName)
+{
+    for (auto itr = vehicleinfoArray.begin(); itr != vehicleinfoArray.end();
+         itr++) {
+        if ((*itr).name == propertyName) {
+            return &(*itr);
+        }
+    }
+    return NULL;
+}
diff --git a/src/ambinterface.h b/src/ambinterface.h
new file mode 100644 (file)
index 0000000..56206f3
--- /dev/null
@@ -0,0 +1,212 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef AMBINTERFACE_H
+#define AMBINTERFACE_H
+
+#include <pthread.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "abstractsource.h"
+#include "config.h"
+
+/**
+ * Vehicle information of AMB.
+ */
+struct AMBVehicleInfo {
+    std::string name;
+    AbstractPropertyType *value;
+    bool isCustom;
+};
+
+class Config;
+class VICCommunicator;
+
+/**
+ * Interface of AMB-Core and Plugin.
+ */
+class AMBIF : public AbstractSource {
+public:
+    /**
+     * Constructor.
+     * 
+     * @param engine Instance of AMB-Core.
+     * @param config Information in a configuration file of AMB.
+     */
+    AMBIF(AbstractRoutingEngine *engine,
+          std::map<std::string, std::string> config);
+    /**
+     * Destructor.
+     */
+    ~AMBIF();
+
+    /**
+     * AMBIF class receives a request for acquisition of information from AMB-Core.
+     * Vehicle Information stored in the hold, plugin will return the data.
+     * 
+     * @param reply Variable for storing the vehiclle information to be returnd to AMB-Core.
+     */
+    void
+    getPropertyAsync(AsyncPropertyReply *reply);
+    /**
+     * AMBIF class receives a request for a change in the vehicle information from AMB-Core.
+     * Changes to vehicle information received from its own information.
+     *
+     * @param request Vehicle information that has been requested change.
+     * @return Vehicle information after the change.
+     */
+    AsyncPropertyReply *
+    setProperty(AsyncSetPropertyRequest request);
+    /**
+     * AMBIF class receives a request for acquisition of vehicle information list from AMB-Core.
+     *
+     * @return Vehicle information list held by the plugin.
+     */
+    PropertyList
+    supported();
+    /**
+     * AMBIF class receives from AMB-Core a request for obtaining the operation list.
+     * AMBIF class supports the operations(Get/Set)
+     *
+     * @return Operation
+     */
+    int
+    supportedOperations();
+
+    /**
+     * AMBIF class will issue a UUID.
+     *
+     * @return UUID
+     */
+    string
+    uuid();
+    /**
+     * AMBIF class is received the vehicle information that other plugin updated.
+     *
+     * @param property the name of Vehicle information of AMB.
+     * @param value the value of Vehicle information of AMB.
+     * @param uuid UUID of the source plugin.
+     */
+    void
+    propertyChanged(VehicleProperty::Property property,
+                    AbstractPropertyType *value, std::string uuid);
+    /**
+     * AMBIF class reads the configuration file AMB.
+     *
+     * @param config Information in a configuration file of AMB.
+     */
+    void
+    setConfiguratin(std::map<std::string, std::string> config);
+
+    /**
+     * Initialization.
+     *
+     * @param comm Instance of VICCommunicator.
+     * @param conf Instance of Config.
+     * @return Success : true Failure : false
+     */
+    bool
+    initialize(VICCommunicator *comm, Config *conf);
+    /**
+     * AMBIF class is required to get the vehicle information to AMB-Core.
+     *
+     * @param propertyname The name of vehicle information of AMB.
+     * @return The value of vehicle information of AMB.
+     */
+    AMBVehicleInfo *
+    getPropertyRequest(std::string propertyname);
+    /**
+     * AMBIF class ask AMB-Core to change the vehicle information.
+     * This request is used for vehicle information that is managed by other plugin.
+     *
+     * @param vehicleinfo Vehicle information of AMB.(name and value)
+     */
+    void
+    setPropertyRequest(AMBVehicleInfo *vehicleinfo);
+    /**
+     * AMBIF class notify a change in the vehicle information to the AMB-Core.
+     * This instruction is subject to only the vehicle information that is managed by the plugin.
+     *
+     * @param vehicleinfo Vehicle information of AMB.(name and value)
+     */
+    void
+    updateProperty(AMBVehicleInfo *vehicleinfo);
+    /**
+     * AMBIF class locks the vehicle information changes.
+     */
+    void
+    lock();
+    /**
+     * AMBIF class releases the lock status of the vehicle information changes.
+     */
+    void
+    unLock();
+    /**
+     * This function is an interface with other objects in the Plugin.
+     * This interface issues a request to change the information.
+     * 
+     * @param vehicleinfo Vehicle information of AMB.
+     */
+    void
+    requestUpdate(AMBVehicleInfo *vehicleinfo);
+
+    /**
+     * Unused virtual function.
+     */
+    void
+    getRangePropertyAsync(AsyncRangePropertyReply *reply)
+    {
+    }
+    /**
+     * Unused virtual function.
+     */
+    void
+    subscribeToPropertyChanges(VehicleProperty::Property property)
+    {
+    }
+    /**
+     * Unused virtual function.
+     */
+    void
+    unsubscribeToPropertyChanges(VehicleProperty::Property property)
+    {
+    }
+    /**
+     * Unused virtual function.
+     */
+    void
+    supportedChanged(PropertyList)
+    {
+    }
+private:
+    bool
+    registVehicleInfo(std::string propertyName,
+                      VehicleInfoDefine::Status::DataType type,
+                      std::string value);
+    AMBVehicleInfo *
+    find(std::string propertyName);
+
+    PropertyList propertylist;
+    vector<AMBVehicleInfo> vehicleinfoArray;
+    VICCommunicator *communicator;
+    pthread_mutex_t mutex;
+};
+#endif // #ifndef AMBINTERFACE_H
diff --git a/src/config.cc b/src/config.cc
new file mode 100644 (file)
index 0000000..95dcd8f
--- /dev/null
@@ -0,0 +1,269 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include <fstream>
+#include <iostream>
+#include <stdexcept>
+
+#include <json-glib/json-glib.h>
+
+#include "debugout.h"
+#include "nullptr.h"
+
+#include "config.h"
+
+using std::string;
+using std::vector;
+
+Config::Config()
+{
+}
+
+Config::~Config()
+{
+    vehicleinfoList.clear();
+}
+
+bool
+Config::readConfig(std::string confpath)
+{
+    std::ifstream in(confpath, std::ios::in);
+    std::string output;
+    std::string line;
+    while (in.good()) {
+        getline(in, line);
+        output.append(line);
+    }
+    return parseJson(output);
+}
+
+vector<VehicleInfoDefine>
+Config::getVehicleInfoConfig()
+{
+    return vehicleinfoList;
+}
+
+PortInfo
+Config::getPort()
+{
+    return portinfo;
+}
+
+bool
+Config::parseJson(string config)
+{
+    /* ToDo */
+    /* json_reader_read_member's error check. */
+    bool ret = false;
+    JsonParser *parser = json_parser_new();
+    GError *error = nullptr;
+    if (!json_parser_load_from_data(parser, config.c_str(), config.length(),
+                                    &error)) {
+        cerr << "Failed to load config[" << error->message << "]." << endl;
+        DebugOut() << "Failed to load config[" << error->message << "]." << endl;
+        return ret;
+    }
+
+    JsonNode *node = json_parser_get_root(parser);
+    if (node == nullptr) {
+        cerr << "Unable to get JSON root object." << endl;
+        DebugOut() << "Unable to get JSON root object." << endl;
+        return ret;
+    }
+
+    JsonReader *reader = json_reader_new(node);
+    if (reader == nullptr) {
+        cerr << "Unable to create JSON reader." << endl;
+        DebugOut() << "Unable to create JSON reader." << endl;
+        return ret;
+    }
+
+    json_reader_read_member(reader, "Config");
+    const GError *configReadError = json_reader_get_error(reader);
+    if (configReadError != nullptr) {
+        cerr << "Error getting sources member[" 
+             << configReadError->message << "]." << endl;
+        DebugOut() << "Error getting sources member[" 
+                   << configReadError->message << "]." << endl;
+        return ret;
+    }
+    g_assert(json_reader_is_array(reader));
+
+    int sectionNum = json_reader_count_elements(reader);
+    string section = "";
+    for (int i = 0; i < sectionNum; i++) {
+        json_reader_read_element(reader, i);
+        json_reader_read_member(reader, "Section");
+        section = std::string(json_reader_get_string_value(reader));
+        json_reader_end_member(reader);
+
+        if (section == "Common") {
+            json_reader_read_member(reader, "VehicleInfoDefine");
+            int elementNum = json_reader_count_elements(reader);
+
+            bool fcontinue = true;
+            int statusNum = 0;
+            for (int i = 0; i < elementNum; i++) {
+                fcontinue = true;
+                VehicleInfoDefine vid;
+                json_reader_read_element(reader, i);
+                json_reader_read_member(reader, "KeyEventType");
+                strcpy(vid.KeyEventType, json_reader_get_string_value(reader));
+                json_reader_end_member(reader);
+
+                for (auto itr = vehicleinfoList.begin();
+                        itr != vehicleinfoList.end(); itr++) {
+                    if (strcmp(vid.KeyEventType, (*itr).KeyEventType) == 0) {
+                        json_reader_end_element(reader);
+                        fcontinue = false;
+                        break;
+                    }
+                }
+                if (!fcontinue) {
+                    continue;
+                }
+
+                json_reader_read_member(reader, "Priority");
+                vid.priority = json_reader_get_int_value(reader);
+                json_reader_end_member(reader);
+
+                json_reader_read_member(reader, "DBusInterface");
+                vid.dbusInterface = json_reader_get_string_value(reader);
+                json_reader_end_member(reader);
+
+                json_reader_read_member(reader, "DBusObject");
+                vid.dbusObject = json_reader_get_string_value(reader);
+                json_reader_end_member(reader);
+
+                json_reader_read_member(reader, "Status");
+                statusNum = json_reader_count_elements(reader);
+
+                for (int j = 0; j < statusNum; j++) {
+                    VehicleInfoDefine::Status status;
+                    json_reader_read_element(reader, j);
+                    json_reader_read_member(reader, "AMBPropertyName");
+                    status.ambPropertyName = json_reader_get_string_value(
+                            reader);
+                    json_reader_end_member(reader);
+
+                    json_reader_read_member(reader, "Type");
+                    status.type = getType(
+                            const_cast<char*>(json_reader_get_string_value(
+                                    reader)),
+                            &status.typesize);
+                    json_reader_end_member(reader);
+
+                    json_reader_read_member(reader, "Default");
+                    status.defaultvalue = std::string(
+                            json_reader_get_string_value(reader));
+                    json_reader_end_member(reader);
+
+                    json_reader_read_member(reader, "AccessControl");
+                    status.accessControl = std::string(
+                            json_reader_get_string_value(reader));
+                    json_reader_end_member(reader);
+
+                    json_reader_read_member(reader, "DBusProperty");
+                    status.dbusPropertyName = std::string(
+                            json_reader_get_string_value(reader));
+                    json_reader_end_member(reader);
+
+                    json_reader_end_member(reader);
+                    json_reader_end_element(reader);
+
+                    json_reader_read_member(reader, "Status");
+                    vid.status.push_back(status);
+                }
+                vehicleinfoList.push_back(vid);
+
+                json_reader_end_member(reader);
+                json_reader_end_element(reader);
+
+            }
+            json_reader_end_member(reader);
+            ret = true;
+            json_reader_read_member(reader, "DefaultInfoPort");
+            json_reader_read_member(reader, "DataPort");
+            portinfo.standard.dataPort = json_reader_get_int_value(reader);
+            json_reader_end_member(reader);
+            json_reader_read_member(reader, "CtrlPort");
+            portinfo.standard.controlPort = json_reader_get_int_value(reader);
+            json_reader_end_member(reader);
+            json_reader_end_member(reader);
+            json_reader_read_member(reader, "CustomizeInfoPort");
+            json_reader_read_member(reader, "DataPort");
+            portinfo.custom.dataPort = json_reader_get_int_value(reader);
+            json_reader_end_member(reader);
+            json_reader_read_member(reader, "CtrlPort");
+            portinfo.custom.controlPort = json_reader_get_int_value(reader);
+            json_reader_end_member(reader);
+            json_reader_end_member(reader);
+        }
+
+        json_reader_end_element(reader);
+    }
+
+    json_reader_end_member(reader);
+    g_object_unref(reader);
+    g_object_unref(parser);
+    return ret;
+}
+
+VehicleInfoDefine::Status::DataType
+Config::getType(char *type, int *size)
+{
+    if (strcmp(type, "int") == 0) {
+        *size = sizeof(int);
+        return VehicleInfoDefine::Status::INT;
+    }
+    else if (strcmp(type, "double") == 0) {
+        *size = sizeof(double);
+        return VehicleInfoDefine::Status::DOUBLE;
+    }
+    else if (strcmp(type, "char") == 0) {
+        *size = sizeof(char);
+        return VehicleInfoDefine::Status::CHAR;
+    }
+    else if (strcmp(type, "int16_t") == 0 || strcmp(type, "int16") == 0) {
+        *size = sizeof(int16_t);
+        return VehicleInfoDefine::Status::INT16;
+    }
+    else if (strcmp(type, "uint16_t") == 0 || strcmp(type, "uint16") == 0) {
+        *size = sizeof(uint16_t);
+        return VehicleInfoDefine::Status::UINT16;
+    }
+    else if (strcmp(type, "uint32_t") == 0 || strcmp(type, "uint32") == 0) {
+        *size = sizeof(uint32_t);
+        return VehicleInfoDefine::Status::UINT32;
+    }
+    else if (strcmp(type, "int64_t") == 0 || strcmp(type, "int64") == 0) {
+        *size = sizeof(int64_t);
+        return VehicleInfoDefine::Status::INT64;
+    }
+    else if (strcmp(type, "uint64_t") == 0 || strcmp(type, "uint64") == 0) {
+        *size = sizeof(uint64_t);
+        return VehicleInfoDefine::Status::UINT64;
+    }
+    else if (strcmp(type, "bool") == 0 || strcmp(type, "boolean") == 0) {
+        *size = sizeof(bool);
+        return VehicleInfoDefine::Status::BOOL;
+    }
+    return VehicleInfoDefine::Status::NONE;
+}
diff --git a/src/config.h b/src/config.h
new file mode 100644 (file)
index 0000000..3b3c518
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <string>
+#include <vector>
+
+/**
+ * Table of vehicle information that is described in the configuration file.
+ * 04-18 Add String
+ */
+struct VehicleInfoDefine {
+    struct Status {
+        std::string ambPropertyName;
+        enum DataType {
+            INT, DOUBLE, CHAR, INT16, UINT16, UINT32, INT64, UINT64, BOOL, NONE
+        } type;
+        int typesize;
+        std::string accessControl;
+        std::string defaultvalue;
+        std::string dbusPropertyName;
+    };
+    /* ToDo */
+    //undefine data structure;
+    struct Sense {
+        int temp;
+    };
+    /* ToDo */
+    //undefine data structure;
+    struct EventMask {
+        int temp;
+    };
+
+    char KeyEventType[64];
+    std::vector<Status> status;
+    std::vector<Sense> sense;
+    std::vector<EventMask> event_mask;
+    int priority;
+    std::string dbusInterface;
+    std::string dbusObject;
+};
+
+/**
+ * Information Websocket port.
+ */
+struct PortInfo {
+    struct {
+        int dataPort;
+        int controlPort;
+    } standard;
+
+    struct {
+        int dataPort;
+        int controlPort;
+    } custom;
+};
+
+/**
+ * This class handles the data in the configuration file.
+ */
+class Config {
+public:
+    /**
+     * Constructor.
+     */
+    Config();
+    /**
+     * Destructor.
+     */
+    ~Config();
+    /**
+     * Read configuration file.
+     *
+     * @param confpath Path to the configuration file.
+     */
+    bool
+    readConfig(std::string confpath);
+    /**
+     * This function will return a table of vehicle information read from the configuration file.
+     *
+     * @return Vehicle information defined by the configuration file.(Failure NULL)
+     */
+    std::vector<VehicleInfoDefine>
+    getVehicleInfoConfig();
+    /**
+     * This function returns the socket port used to Websocket.
+     */
+    PortInfo
+    getPort();
+protected:
+    bool
+    parseJson(std::string config);
+
+    std::string filename;
+    bool readflag;
+private:
+    VehicleInfoDefine::Status::DataType
+    getType(char *type, int *size);
+
+    std::vector<VehicleInfoDefine> vehicleinfoList;
+    PortInfo portinfo;
+};
+#endif // #ifndef CONFIG_H
diff --git a/src/controlwebsocket.cc b/src/controlwebsocket.cc
new file mode 100644 (file)
index 0000000..556ae0f
--- /dev/null
@@ -0,0 +1,386 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <pthread.h>
+#include <string.h>
+
+#include "debugout.h"
+
+#include "controlwebsocket.h"
+#include "mwinterface.h"
+#include "standardmessage.h"
+
+/**
+ * Socket ID generated class.
+ */
+template<class T>
+    class GenerateCommID {
+    public:
+        /**
+         * This function retrieves an instance of the class.
+         *
+         * @return Instance of GenerateCommID
+         */
+        static GenerateCommID *
+        getInstance()
+        {
+            static GenerateCommID<T> instance;
+            return &instance;
+        }
+
+        /**
+         * This function returns the ID that is registered.
+         * If the ID is not registerd, it register the ID.
+         *
+         * @param value Value of socket.
+         * @return ID
+         */
+        int
+        getID(T value)
+        {
+            pthread_mutex_lock(&mutex);
+            for (auto itr = commidmap.begin(); itr != commidmap.end(); itr++) {
+                if ((*itr).second == value) {
+                    pthread_mutex_unlock(&mutex);
+                    return (*itr).first;
+                }
+            }
+            int newid = generateID();
+            commidmap.insert(make_pair(newid, value));
+            pthread_mutex_unlock(&mutex);
+            return newid;
+        }
+        /**
+         * This function returns the socket information registered.
+         *
+         * @param id Socket ID
+         * @return Value of socket
+         */
+        T
+        getValue(int id)
+        {
+            pthread_mutex_lock(&mutex);
+            if (commidmap.find(id) == commidmap.end()) {
+                pthread_mutex_unlock(&mutex);
+                return NULL;
+            }
+            pthread_mutex_unlock(&mutex);
+            return commidmap[id];
+        }
+
+        /**
+         * This function removes the socket information registered.
+         *
+         * @param id Socket ID
+         * @return Success : true Failure : false
+         */
+        bool
+        unsetID(int id)
+        {
+            pthread_mutex_lock(&mutex);
+            bool ret = false;
+            auto itr = commidmap.find(id);
+            if (itr != commidmap.end()) {
+                itr = commidmap.erase(itr);
+                ret = true;
+            }
+            pthread_mutex_unlock(&mutex);
+            return ret;
+        }
+    private:
+        GenerateCommID() : mutex(PTHREAD_MUTEX_INITIALIZER)
+        {
+        }
+
+        ~GenerateCommID()
+        {
+            commidmap.clear();
+        }
+
+        GenerateCommID(const GenerateCommID &)
+        {
+        }
+
+        const GenerateCommID&
+        operator =(const GenerateCommID &)
+        {
+        }
+
+        int
+        generateID()
+        {
+            if (commidmap.empty()) {
+                return 1;
+            }
+            int count = 1;
+            for (auto itr = commidmap.begin(); itr != commidmap.end(); itr++) {
+                if (itr->first != count) {
+                    return count;
+                }
+                count++;
+            }
+            return count + 1;
+        }
+
+        std::map<int, T> commidmap;
+        pthread_mutex_t mutex;
+    };
+
+MWIF *ControlWebsocket::mwif = NULL;
+
+ControlWebsocket::ControlWebsocket()
+{
+    mutex = PTHREAD_MUTEX_INITIALIZER;
+    protocollist[1] = {NULL, NULL, 0};
+}
+
+ControlWebsocket::~ControlWebsocket()
+{
+    socketmap.clear();
+}
+
+bool
+ControlWebsocket::initialize(int port, enum ServerProtocol stype)
+{
+    DebugOut() << "ControlWebsocket[" << type << "]" << " initialize.(" << port
+               << ")\n";
+    type = stype;
+    switch (type) {
+    case DATA_STANDARD:
+    {
+        protocollist[0] = {"standarddatamessage-only", ControlWebsocket::callback_receive, 0};
+        break;
+    }
+    case CONTROL_STANDARD : {
+        protocollist[0] = {"standardcontrolmessage-only", ControlWebsocket::callback_receive, 0};
+        break;
+    }
+    case DATA_CUSTOM : {
+        protocollist[0] = {"customdatamessage-only", ControlWebsocket::callback_receive, 0};
+        break;
+    }
+    case CONTROL_CUSTOM : {
+        protocollist[0] = {"customcontrolmessage-only", ControlWebsocket::callback_receive, 0};
+        break;
+    }
+    default : {
+        return false;
+    }
+}
+    context = libwebsocket_create_context(port, "lo", protocollist,
+                                          libwebsocket_internal_extensions,
+                                          NULL, NULL, -1, -1, 0);
+    if (context == NULL) {
+        DebugOut() << "ControlWebsocket[" << type << "]" 
+                   << " couldn't create libwebsockets_context." << std::endl;
+        return false;
+    }
+    if (pthread_create(&threadid, NULL, ControlWebsocket::run, (void*)this)
+        == -1) {
+        libwebsocket_context_destroy(context);
+        DebugOut() << "ControlWebsocket[" << type << "]" 
+                   << " couldn't create thread." << std::endl;
+        return false;
+    }
+    return true;
+}
+
+bool
+ControlWebsocket::send(int commid, char *keyeventtype, timeval time, void *data,
+                       size_t len)
+{
+    DebugOut() << "ControlWebsocket[" << type << "]" << " send data(" << commid
+               << "," << keyeventtype << ") len = " << len << std::endl;
+    libwebsocket *wsi = NULL;
+    if (socketmap.find(commid) == socketmap.end()) {
+        if (!registSocket(commid)) {
+            DebugOut() << "ControlWebsocket[" << type << "]" 
+                       << " can't regist socket(" << commid << ")" 
+                       << std::endl;
+            return false;
+        }
+    }
+    wsi = socketmap[commid];
+
+    if (wsi == NULL) {
+        DebugOut() << "ControlWebsocket Get websocket object is NULL."
+                   << std::endl;
+        return false;
+    }
+    pthread_mutex_lock(&mutex);
+    memset(buf, 0, sizeof(buf));
+    memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING,
+           datamsg.encode(keyeventtype, time,
+                          *(reinterpret_cast<DataOpt*>(data))),
+           len);
+    DebugOut() << "ControlWebsocket Send Data[" << keyeventtype << "]"
+               << std::endl;
+    libwebsocket_write(
+            wsi,
+            reinterpret_cast<unsigned char*>(buf + LWS_SEND_BUFFER_PRE_PADDING),
+            len, LWS_WRITE_BINARY);
+    pthread_mutex_unlock(&mutex);
+    return true;
+}
+
+bool
+ControlWebsocket::receive(int commid, char *keyeventtype, timeval recordtime,
+                          void *data, size_t len)
+{
+    DebugOut() << "ControlWebsocket[" << type << "]" << " receive message("
+               << commid << "," << keyeventtype << ")\n";
+    switch (type) {
+    case DATA_STANDARD:
+    case DATA_CUSTOM:
+    {
+        datamsg.decodeOpt(keyeventtype, recordtime, data);
+        DataOpt dop = datamsg.getDataOpt();
+        mwif->recvMessage(SET, commid, keyeventtype, recordtime, (void*)&dop,
+                          len);
+        break;
+    }
+    case CONTROL_STANDARD:
+    case CONTROL_CUSTOM:
+    {
+        eventmsg.decodeOpt(keyeventtype, recordtime, data);
+        EventOpt opt = eventmsg.getEventOpt();
+        if (opt.common == -1 && opt.sense == -1) {
+            mwif->recvMessage(GET, commid, keyeventtype, recordtime,
+                              (void*)&opt, len);
+        }
+        else {
+            mwif->recvMessage(CALLBACK, commid, keyeventtype, recordtime,
+                              (void*)&opt, len);
+        }
+        break;
+    }
+    default:
+    {
+        return false;
+    }
+    }
+    return true;
+}
+
+void
+ControlWebsocket::observation()
+{
+    int ret = 0;
+    while (ret >= 0) {
+        ret = libwebsocket_service(context, 100);
+        if (ret != 0) {
+            break;
+        }
+    }
+}
+
+bool
+ControlWebsocket::registSocket(int commid)
+{
+    if (socketmap.find(commid) != socketmap.end()) {
+        return true;
+    }
+    GenerateCommID<libwebsocket*> *idserver =
+            GenerateCommID<libwebsocket*>::getInstance();
+    libwebsocket *wsi = idserver->getValue(commid);
+    if (wsi == NULL) {
+        return false;
+    }
+    libwebsocket_protocols *protocol =
+            const_cast<libwebsocket_protocols*>(libwebsockets_get_protocol(wsi));
+    if (protocol != NULL) {
+        if (context == protocol[0].owning_server) {
+            socketmap[commid] = wsi;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+ControlWebsocket::unregistSocket(int commid)
+{
+    if (socketmap.find(commid) == socketmap.end()) {
+        return false;
+    }
+    socketmap.erase(commid);
+    GenerateCommID<libwebsocket*> *idserver =
+            GenerateCommID<libwebsocket*>::getInstance();
+    return idserver->unsetID(commid);
+}
+
+int
+ControlWebsocket::callback_receive(libwebsocket_context *context,
+                                   libwebsocket *wsi,
+                                   libwebsocket_callback_reasons reason,
+                                   void *user, void *in, size_t len)
+{
+    DebugOut(10) << "Reason(" << reason << ")\n";
+    switch (reason) {
+    case LWS_CALLBACK_ESTABLISHED:
+    {
+        GenerateCommID<libwebsocket*> *idserver =
+                GenerateCommID<libwebsocket*>::getInstance();
+        int id = idserver->getID(wsi);
+        DebugOut() << "ControlWebsocket callback_receive Insert ID is " << id
+                   << "\n";
+        break;
+    }
+    case LWS_CALLBACK_CLOSED:
+    {
+        GenerateCommID<libwebsocket*> *idserver =
+                GenerateCommID<libwebsocket*>::getInstance();
+        int id = idserver->getID(wsi);
+        idserver->unsetID(id);
+        DebugOut() << "ControlWebsocket callback_receive Delete ID is " << id
+                   << "\n";
+        ControlWebsocket::mwif->unregistDestination(id);
+        break;
+    }
+    case LWS_CALLBACK_RECEIVE:
+    {
+        GenerateCommID<libwebsocket*> *idserver =
+                GenerateCommID<libwebsocket*>::getInstance();
+        int id = idserver->getID(wsi);
+        StandardMessage msg;
+        char *buf = reinterpret_cast<char*>(in);
+        msg.decode(buf, len);
+        DebugOut() << "ControlWebsocket callback_receive Receive message : "
+                   << msg.getKeyEventType() << "," << msg.getRecordtime().tv_sec
+                   << "\n";
+        ControlWebsocket::mwif->recvRawdata(
+                id, msg.getKeyEventType(), msg.getRecordtime(),
+                (buf + StandardMessage::KEYEVENTTYPESIZE + sizeof(timeval)),
+                len);
+        break;
+    }
+    default:
+    {
+        break;
+    }
+    }
+    return 0;
+}
+
+void *
+ControlWebsocket::run(void *arg)
+{
+    ControlWebsocket *control = reinterpret_cast<ControlWebsocket*>(arg);
+    control->observation();
+    return NULL;
+}
diff --git a/src/controlwebsocket.h b/src/controlwebsocket.h
new file mode 100644 (file)
index 0000000..093059b
--- /dev/null
@@ -0,0 +1,144 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef CONTROLWEBSOCKET_H_
+#define CONTROLWEBSOCKET_H_
+
+#include <pthread.h>
+#include <sys/time.h>
+
+#include <map>
+#include <vector>
+
+#include <libwebsockets.h>
+
+#include "eventmessage.h"
+#include "datamessage.h"
+
+class MWIF;
+
+/**
+ * Class that manages the Websocket.
+ */
+class ControlWebsocket {
+public:
+    /**
+     * The protocol used to Websocket communicate.
+     */
+    enum ServerProtocol {
+        DATA_STANDARD, CONTROL_STANDARD, DATA_CUSTOM, CONTROL_CUSTOM
+    };
+    /**
+     * Constructor.
+     */
+    ControlWebsocket();
+    /**
+     * Destructor.
+     */
+    ~ControlWebsocket();
+    /**
+     * Initialization.
+     *
+     * @param port The port number used by websocket server.
+     * @param type Kind of the protocol.
+     * @return Success : true Failure : false
+     */
+    bool
+    initialize(int port, enum ServerProtocol stype);
+    /**
+     * This function sends a message to the MW.
+     * 
+     * @param commid socket id.
+     * @param keyeventtype The name of vehicle information of MW.
+     * @param time Time of the message.
+     * @param data Data of the message.
+     * @return Success : true Failure : false
+     */
+    bool
+    send(int commid, char *keyeventtype, timeval time, void *data, size_t len);
+    /**
+     * This function analyzes the received message.
+     *
+     * @param commid socket id.
+     * @param keyeventtype The name of vehicle information of MW.
+     * @param time Time of the message.
+     * @param data Data of the message.
+     * @param len Length of the message.
+     * @return Success : true Failure : false
+     */
+    bool
+    receive(int commid, char *keyeventtype, timeval recordtime, void *data,
+            size_t len);
+    /**
+     * This function monitors the file descriptor for Websocket Server.
+     */
+    void
+    observation();
+    /**
+     * Registration of the socket. This function retrieves the socket information from the socket ID.
+     * 
+     * @param commid socket id.
+     * @return Success : true Failure : false
+     */
+    bool
+    registSocket(int commid);
+    /**
+     * Delete the socket. This function removes the socket information from the socket ID.
+     *
+     * @param commid socket id.
+     * @return Success : true Failure : false
+     */
+    bool
+    unregistSocket(int commid);
+    /**
+     * Callback function for libwebsockets
+     *
+     * @param context Websockets context
+     * @param wsi Opaque websocket instance pointer
+     * @param reason The reason for the call
+     * @param user Pointer to per-session user data allocated by library.
+     * @param in Pointer used for some callback reasons
+     * @param len Length set for some callback reasons.
+     */
+    static int
+    callback_receive(libwebsocket_context *context, libwebsocket *wsi,
+                     libwebsocket_callback_reasons reason, void *user, void *in,
+                     size_t len);
+    /**
+     * Function for multi-threaded execution.
+     */
+    static void *
+    run(void *arg);
+
+    /**
+     * Instance of MWIF.
+     */
+    static MWIF *mwif;
+private:
+    libwebsocket_context *context;
+    libwebsocket_protocols protocollist[2];
+    enum ServerProtocol type;
+    std::map<int, libwebsocket*> socketmap;
+    EventMessage eventmsg;
+    DataMessage datamsg;
+    pthread_t threadid;
+    pthread_mutex_t mutex;
+    char buf[LWS_SEND_BUFFER_PRE_PADDING + StandardMessage::BUFSIZE
+            + LWS_SEND_BUFFER_POST_PADDING];
+};
+#endif // #ifndef CONTROLWEBSOCKET_H_
diff --git a/src/convert.cc b/src/convert.cc
new file mode 100644 (file)
index 0000000..1c33d3c
--- /dev/null
@@ -0,0 +1,663 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include <algorithm>
+#include <sstream>
+
+#include "debugout.h"
+
+#include "ambinterface.h"
+#include "convert.h"
+#include "mwinterface.h"
+
+Converter::Converter()
+{
+    specialconvertlist.push_back(VehicleProperty::TransmissionShiftPosition);
+    specialconvertlist.push_back(VehicleProperty::TransmissionGearPosition);
+    specialconvertlist.push_back(VehicleProperty::TransmissionMode);
+    specialconvertlist.push_back(VehicleProperty::TurnSignal);
+    specialconvertlist.push_back(VehicleProperty::ButtonEvent);
+}
+
+Converter::~Converter()
+{
+    converttablelist.clear();
+}
+
+bool
+Converter::initialize(Config *conf)
+{
+    vector<VehicleInfoDefine> dtableArray;
+    dtableArray = conf->getVehicleInfoConfig();
+    for (auto itr = dtableArray.begin(); itr != dtableArray.end(); itr++) {
+        ConvertTable ctable;
+        ctable.mwname = string((*itr).KeyEventType);
+        DebugOut() << "Converter initialize mwname = " << ctable.mwname << "\n";
+        for (auto itr2 = (*itr).status.begin(); itr2 != (*itr).status.end();
+             itr2++) {
+            ConvertTable::AmbVehicleInfoData ambdata;
+            ambdata.ambname = (*itr2).ambPropertyName;
+            DebugOut() << "Converter initialize ambname = " << ambdata.ambname
+                       << "\n";
+            ambdata.type = (*itr2).type;
+            ambdata.typesize = (*itr2).typesize;
+            ctable.ambdataarray.push_back(ambdata);
+        }
+        converttablelist.push_back(ctable);
+    }
+    return true;
+}
+
+int
+Converter::convertMWtoAMB(MWVehicleInfo *mwvehicleinfo,
+                          AMBVehicleInfo *ambvehicleinfo, int arraysize)
+{
+    int ret = 0;
+    for (auto itr = converttablelist.begin(); itr != converttablelist.end();
+         itr++) {
+        DebugOut(10) << "Converter convertMWtoAMB mwname = " << (*itr).mwname
+                     << "\n";
+        if ((*itr).mwname == mwvehicleinfo->name) {
+            int arrayidx = 0;
+            int statusidx = 0;
+            for (auto itr2 = (*itr).ambdataarray.begin();
+                    itr2 != (*itr).ambdataarray.end(); itr2++) {
+                ambvehicleinfo[arrayidx].name = (*itr2).ambname;
+                ambvehicleinfo[arrayidx].value =
+                        VehicleProperty::getPropertyTypeForPropertyNameValue(
+                                ambvehicleinfo[arrayidx].name, "0");
+                ambvehicleinfo[arrayidx].value->timestamp = toDouble(
+                        mwvehicleinfo->recordtime);
+                char statusbuf[(*itr2).typesize];
+                memcpy(statusbuf, mwvehicleinfo->status + statusidx,
+                       sizeof(statusbuf));
+                ambvehicleinfo[arrayidx].value->fromString(
+                        toString((*itr2).ambname, statusbuf, sizeof(statusbuf),
+                                 (*itr2).type));
+                statusidx += sizeof(statusbuf);
+                DebugOut() << "Converter convertMWtoAMB ambname = "
+                           << (*itr2).ambname << "(" 
+                           << ambvehicleinfo[arrayidx].value->toString() 
+                           << ")\n";
+                arrayidx++;
+                if (arrayidx == arraysize
+                        && arraysize
+                               < static_cast<int>((*itr).ambdataarray.size())) {
+                    ret = -1;
+                    break;
+                }
+                ret = arrayidx;
+            }
+            break;
+        }
+    }
+    return ret;
+}
+
+int
+Converter::convertAMBtoMW(AMBVehicleInfo *ambvehicleinfo,
+                          MWVehicleInfo *mwvehicleinfo)
+{
+    int ret = 0;
+    int statusidx = 0;
+    for (auto itr = converttablelist.begin(); itr != converttablelist.end();
+         itr++) {
+        statusidx = 0;
+        DebugOut(10) << "Converter convertAMBtoMW mwname = " << (*itr).mwname
+                << "\n";
+        for (auto itr2 = (*itr).ambdataarray.begin();
+             itr2 != (*itr).ambdataarray.end(); itr2++) {
+            DebugOut(10) << "Converter convertAMBtoMW ambname = "
+                       << (*itr2).ambname << "\n";
+            if ((*itr2).ambname == ambvehicleinfo->name) {
+                DebugOut() << "Converter convertAMBtoMW ambname = "
+                           << (*itr2).ambname << "\n";
+                mwvehicleinfo->name = (*itr).mwname;
+                mwvehicleinfo->recordtime = toTimeval(
+                        ambvehicleinfo->value->timestamp);
+                if (ambvehicleinfo->value == NULL) {
+                    DebugOut() << "Converter convertAMBtoMW " 
+                               << "ambvehicleinfo->value is NULL\n";
+                    ret = -1;
+                }
+                else {
+                    DebugOut() << "Converter check data "
+                               << ambvehicleinfo->value->toString() 
+                               << std::endl;
+                    toBinary(ambvehicleinfo->name, ambvehicleinfo->value,
+                             (*itr2).typesize, (*itr2).type,
+                             mwvehicleinfo->status + statusidx);
+                    ret = 1;
+                }
+                return ret;
+            }
+            statusidx += (*itr2).typesize;
+        }
+    }
+    return ret;
+}
+
+string
+Converter::toString(string ambname, char *data, int size,
+                    VehicleInfoDefine::Status::DataType type)
+{
+    if (find(specialconvertlist.begin(), specialconvertlist.end(), ambname)
+        != specialconvertlist.end()) {
+        return specialConvertMWtoAMB(ambname, data, size, type);
+    }
+    stringstream sstr;
+    sstr.str("");
+    sstr.precision(10);
+    switch (type) {
+    case VehicleInfoDefine::Status::INT:
+    {
+        int val;
+        memcpy(&val, data, size);
+        sstr << val;
+        break;
+    }
+    case VehicleInfoDefine::Status::DOUBLE:
+    {
+        double val;
+        memcpy(&val, data, size);
+        sstr << val;
+        break;
+    }
+    case VehicleInfoDefine::Status::CHAR:
+    {
+        char val;
+        memcpy(&val, data, size);
+        sstr << val;
+        break;
+    }
+    case VehicleInfoDefine::Status::INT16:
+    {
+        int16_t val;
+        memcpy(&val, data, size);
+        sstr << val;
+        break;
+    }
+    case VehicleInfoDefine::Status::UINT16:
+    {
+        uint16_t val;
+        memcpy(&val, data, size);
+        sstr << val;
+        break;
+    }
+    case VehicleInfoDefine::Status::UINT32:
+    {
+        uint32_t val;
+        memcpy(&val, data, size);
+        sstr << val;
+        break;
+    }
+    case VehicleInfoDefine::Status::INT64:
+    {
+        int64_t val;
+        memcpy(&val, data, size);
+        sstr << val;
+        break;
+    }
+    case VehicleInfoDefine::Status::UINT64:
+    {
+        uint64_t val;
+        memcpy(&val, data, size);
+        sstr << val;
+        break;
+    }
+    case VehicleInfoDefine::Status::BOOL:
+    {
+        bool val;
+        memcpy(&val, data, size);
+        sstr << val;
+        break;
+    }
+    default:
+    {
+        break;
+    }
+    }
+    return sstr.str();
+}
+
+int
+Converter::toBinary(string ambname, AbstractPropertyType *value, int size,
+                    VehicleInfoDefine::Status::DataType type, char *buf)
+{
+    stringstream sstr;
+    sstr.str("");
+    if (find(specialconvertlist.begin(), specialconvertlist.end(), ambname)
+        != specialconvertlist.end()) {
+        sstr << specialConvertAMBtoMW(ambname, value);
+    }
+    else {
+        sstr << value->toString();
+    }
+    DebugOut(10) << "Converter toBinary " << sstr.str() << "\n";
+    switch (type) {
+    case VehicleInfoDefine::Status::INT:
+    {
+        int val;
+        sstr >> val;
+        memcpy(buf, &val, size);
+        DebugOut() << "Converter toBinary<int> " << val << "\n";
+        break;
+    }
+    case VehicleInfoDefine::Status::DOUBLE:
+    {
+        double val;
+        sstr >> val;
+        memcpy(buf, &val, size);
+        DebugOut() << "Converter toBinary<double> " << val << "\n";
+        break;
+    }
+    case VehicleInfoDefine::Status::CHAR:
+    {
+        char val;
+        sstr >> val;
+        memcpy(buf, &val, size);
+        DebugOut() << "Converter toBinary<char> " << val << "\n";
+        break;
+    }
+    case VehicleInfoDefine::Status::INT16:
+    {
+        int16_t val;
+        sstr >> val;
+        memcpy(buf, &val, size);
+        DebugOut() << "Converter toBinary<int16_t> " << val << "\n";
+        break;
+    }
+    case VehicleInfoDefine::Status::UINT16:
+    {
+        uint16_t val;
+        sstr >> val;
+        memcpy(buf, &val, size);
+        DebugOut() << "Converter toBinary<uint16_t> " << val << "\n";
+        break;
+    }
+    case VehicleInfoDefine::Status::UINT32:
+    {
+        uint32_t val;
+        sstr >> val;
+        memcpy(buf, &val, size);
+        DebugOut() << "Converter toBinary<uint32_t> " << val << "\n";
+        break;
+    }
+    case VehicleInfoDefine::Status::INT64:
+    {
+        int64_t val;
+        sstr >> val;
+        memcpy(buf, &val, size);
+        DebugOut() << "Converter toBinary<int64_t> " << val << "\n";
+        break;
+    }
+    case VehicleInfoDefine::Status::UINT64:
+    {
+        uint64_t val;
+        sstr >> val;
+        memcpy(buf, &val, size);
+        DebugOut() << "Converter toBinary<uint64_t> " << val << "\n";
+        break;
+    }
+    case VehicleInfoDefine::Status::BOOL:
+    {
+        int tmpval;
+        bool val;
+        sstr >> tmpval;
+        if (tmpval > 0) {
+            val = true;
+        }
+        else {
+            val = false;
+        }
+        memcpy(buf, &val, sizeof(bool));
+        DebugOut() << "Converter toBinary<bool> " << val << "\n";
+        break;
+    }
+    default:
+    {
+        size = 0;
+        break;
+    }
+    }
+    return size;
+}
+
+double
+Converter::toDouble(timeval time)
+{
+    return static_cast<double>(time.tv_sec + (time.tv_usec / 1000000));
+}
+
+timeval
+Converter::toTimeval(double time)
+{
+    timeval tv;
+    tv.tv_sec = time;
+    double utime = time - tv.tv_sec;
+    tv.tv_usec = utime * 1000000;
+    return tv;
+}
+
+std::string
+Converter::specialConvertAMBtoMW(std::string ambname,
+                                 AbstractPropertyType *value)
+{
+    stringstream retstr;
+    retstr.str("");
+    if (ambname == VehicleProperty::TransmissionShiftPosition) {
+        switch (boost::any_cast<Transmission::TransmissionPositions>
+                (value->anyValue())) {
+        case Transmission::Neutral:
+        {
+            retstr << 2;
+            break;
+        }
+        case Transmission::First:
+        {
+            retstr << 5;
+            break;
+        }
+        case Transmission::Second:
+        {
+            retstr << 6;
+            break;
+        }
+        case Transmission::Third:
+        {
+            retstr << 7;
+            break;
+        }
+        case Transmission::Forth:
+        {
+            retstr << 8;
+            break;
+        }
+        case Transmission::Fifth:
+        {
+            retstr << 9;
+            break;
+        }
+        case Transmission::Sixth:
+        {
+            retstr << 10;
+            break;
+        }
+        case Transmission::Seventh:
+        {
+            retstr << 11;
+            break;
+        }
+        case Transmission::Eighth:
+        {
+            retstr << 12;
+            break;
+        }
+        case Transmission::Ninth:
+        {
+            retstr << 13;
+            break;
+        }
+        case Transmission::Tenth:
+        {
+            retstr << 14;
+            break;
+        }
+        case Transmission::CVT:
+        {
+            retstr << 15;
+            break;
+        }
+        case Transmission::Drive:
+        {
+            retstr << 4;
+            break;
+        }
+        case Transmission::Reverse:
+        {
+            retstr << 1;
+            break;
+        }
+        case Transmission::Park:
+        {
+            retstr << 0;
+            break;
+        }
+        }
+        DebugOut() << "Converter specialConvertAMBtoMW"
+                   << "(TransmissionShiftPosition): "
+                   << value->toString() << "->" << retstr.str() << std::endl;
+    }
+    else if (ambname == VehicleProperty::TransmissionGearPosition) {
+        switch (boost::any_cast<Transmission::TransmissionPositions> 
+                (value->anyValue())) {
+        case Transmission::Neutral:
+        {
+            retstr << 64;
+            break;
+        }
+        case Transmission::First:
+        case Transmission::Second:
+        case Transmission::Third:
+        case Transmission::Forth:
+        case Transmission::Fifth:
+        case Transmission::Sixth:
+        case Transmission::Seventh:
+        case Transmission::Eighth:
+        case Transmission::Ninth:
+        case Transmission::Tenth:
+        {
+            retstr << value->toString();
+            break;
+        }
+        case Transmission::CVT:
+        {
+            retstr << 256;
+            break;
+        }
+        case Transmission::Drive:
+        {
+            retstr << 0;
+            break;
+        }
+        case Transmission::Reverse:
+        {
+            retstr << 128;
+            break;
+        }
+        case Transmission::Park:
+        {
+            retstr << 0;
+            break;
+        }
+        default:
+        {
+            retstr << 172;
+            break;
+        }
+        }
+        DebugOut() << "Converter specialConvertAMBtoMW"
+                   << "(TransmissionGearPosition): "
+                   << value->toString() << "->" << retstr.str() << std::endl;
+    }
+    else if (ambname == VehicleProperty::TransmissionMode) {
+        retstr << value->toString();
+    }
+    else if (ambname == VehicleProperty::TurnSignal) {
+        retstr << value->toString();
+    }
+    else if (ambname == VehicleProperty::ButtonEvent) {
+        /* ToDo */
+    }
+    return retstr.str();
+}
+
+std::string
+Converter::specialConvertMWtoAMB(std::string ambname, char *data, int size,
+                                 VehicleInfoDefine::Status::DataType type)
+{
+    stringstream retstr;
+    retstr.str("");
+    if (ambname == VehicleProperty::TransmissionShiftPosition) {
+        int val;
+        memcpy(&val, data, size);
+        switch (val) {
+        case 0:
+        {
+            retstr << Transmission::Park;
+            break;
+        }
+        case 1:
+        {
+            retstr << Transmission::Reverse;
+            break;
+        }
+        case 2:
+        {
+            retstr << Transmission::Neutral;
+            break;
+        }
+        case 4:
+        {
+            retstr << Transmission::Drive;
+            break;
+        }
+        case 5:
+        {
+            retstr << Transmission::First;
+            break;
+        }
+        case 6:
+        {
+            retstr << Transmission::Second;
+            break;
+        }
+        case 7:
+        {
+            retstr << Transmission::Third;
+            break;
+        }
+        case 8:
+        {
+            retstr << Transmission::Forth;
+            break;
+        }
+        case 9:
+        {
+            retstr << Transmission::Fifth;
+            break;
+        }
+        case 10:
+        {
+            retstr << Transmission::Sixth;
+            break;
+        }
+        case 11:
+        {
+            retstr << Transmission::Seventh;
+            break;
+        }
+        case 12:
+        {
+            retstr << Transmission::Eighth;
+            break;
+        }
+        case 13:
+        {
+            retstr << Transmission::Ninth;
+            break;
+        }
+        case 14:
+        {
+            retstr << Transmission::Tenth;
+            break;
+        }
+        case 15:
+        {
+            retstr << Transmission::CVT;
+            break;
+        }
+        default:
+        {
+            break;
+        }
+        }
+        DebugOut() << "Converter specialConvertMWtoAMB"
+                   << "(TransmissionShiftPosition): "
+                   << val << "->" << retstr.str() << std::endl;
+    }
+    else if (ambname == VehicleProperty::TransmissionGearPosition) {
+        int val;
+        memcpy(&val, data, size);
+        switch (val) {
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
+        case 8:
+        case 9:
+        case 10:
+        {
+            retstr << val;
+            break;
+        }
+        case 64:
+        {
+            retstr << Transmission::Neutral;
+            break;
+        }
+        case 128:
+        {
+            retstr << Transmission::Reverse;
+            break;
+        }
+        case 256:
+        {
+            retstr << Transmission::CVT;
+            break;
+        }
+        default:
+        {
+            retstr << 0;
+            break;
+        }
+        }
+        DebugOut() << "Converter specialConvertMWtoAMB"
+                   << "(TransmissionGearPosition): "
+                   << val << "->" << retstr.str() << std::endl;
+    }
+    else if (ambname == VehicleProperty::TransmissionMode) {
+        int val;
+        memcpy(&val, data, size);
+        retstr << val;
+    }
+    else if (ambname == VehicleProperty::TurnSignal) {
+        int val;
+        memcpy(&val, data, size);
+        retstr << val;
+    }
+    else if (ambname == VehicleProperty::ButtonEvent) {
+        /* ToDo */
+    }
+    return retstr.str();
+}
diff --git a/src/convert.h b/src/convert.h
new file mode 100644 (file)
index 0000000..f6bea27
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef CONVERT_H
+#define CONVERT
+#include <string>
+
+#include "abstractpropertytype.h"
+
+#include "config.h"
+
+struct AMBVehicleInfo;
+struct MWVehicleInfo;
+
+/**
+ * This class performs the conversion of vehicle information of AMB and vehicle information of MW.
+ */
+class Converter {
+public:
+    /**
+     * Constructor.
+     */
+    Converter();
+    /**
+     * Destructor.
+     */
+    ~Converter();
+    /**
+     * Initialization.
+     *
+     * @param conf Instanse of Config class.
+     * @return Success : true Failure : false
+     */
+    bool
+    initialize(Config *conf);
+    /**
+     * This function converts the vehicle infomation of MW into the vehicle information of AMB.
+     *
+     * @param mwvehicleinfo Vehicle information of MW.
+     * @param ambvehicleinfo Vehicle information of AMB.
+     * @return -1 : Conversion failure >0 : The number of pieces of vehicle information of AMB that has been converted.
+     */
+    int
+    convertMWtoAMB(MWVehicleInfo *mwvehicleinfo, AMBVehicleInfo *ambvehicleinfo,
+                   int arraysize);
+    /**
+     * This function converts the vehicle information of AMB into the vehicle information of MW.
+     *
+     * @param ambvehicleinfo Vehicle information of AMB.
+     * @param mwvehicleinfo Vehicle information of MW.
+     * @return -1 : Conversion failure >0 : The number of pieces of vehicle information of AMB that has been converted.
+     */
+    int
+    convertAMBtoMW(AMBVehicleInfo *ambvehicleinfo,
+                   MWVehicleInfo *mwvehicleinfo);
+private:
+    std::string
+    toString(std::string ambname, char *data, int size,
+             VehicleInfoDefine::Status::DataType type);
+    int
+    toBinary(std::string ambname, AbstractPropertyType *value, int size,
+             VehicleInfoDefine::Status::DataType type, char *buf);
+    double
+    toDouble(timeval time);
+    timeval
+    toTimeval(double time);
+    std::string
+    specialConvertAMBtoMW(std::string ambname, AbstractPropertyType *value);
+    std::string
+    specialConvertMWtoAMB(std::string ambname, char *data, int size,
+                          VehicleInfoDefine::Status::DataType type);
+    struct ConvertTable {
+        std::string mwname;
+        struct AmbVehicleInfoData {
+            std::string ambname;
+            VehicleInfoDefine::Status::DataType type;
+            int typesize;
+        };
+        std::vector<AmbVehicleInfoData> ambdataarray;
+    };
+
+    std::vector<ConvertTable> converttablelist;
+    std::vector<std::string> specialconvertlist;
+};
+#endif // CONVERT_H
diff --git a/src/datamessage.cc b/src/datamessage.cc
new file mode 100644 (file)
index 0000000..2d6446e
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include "datamessage.h"
+
+DataMessage::DataMessage()
+{
+}
+
+DataMessage::~DataMessage()
+{
+}
+
+void
+DataMessage::decode(char *msg, int size)
+{
+    int restsize = size;
+    if (size <= KEYEVENTTYPESIZE) {
+        memset(KeyEventType, 0, size);
+        memcpy(KeyEventType, msg, size);
+        return;
+    }
+    memcpy(KeyEventType, msg, KEYEVENTTYPESIZE);
+    restsize -= KEYEVENTTYPESIZE;
+    int offset = KEYEVENTTYPESIZE;
+    if (restsize < static_cast<int>(sizeof(timeval))) {
+        return;
+    }
+    memcpy(&recordtime, msg + offset, sizeof(timeval));
+    restsize -= sizeof(timeval);
+    offset += sizeof(timeval);
+    if (restsize > static_cast<int>(sizeof(int))) {
+        memcpy(&dataopt, msg + offset, offset);
+    }
+}
+
+void
+DataMessage::decodeOpt(char *keyeventtype, timeval time, void *opt)
+{
+    memset(KeyEventType, 0, KEYEVENTTYPESIZE);
+    memcpy(KeyEventType, keyeventtype, KEYEVENTTYPESIZE);
+    recordtime = time;
+    memcpy(&dataopt, opt, sizeof(dataopt));
+}
+
+char *
+DataMessage::encode(char *name, timeval time, DataOpt opt)
+{
+    memset(messagebuf, 0, sizeof(messagebuf));
+    memcpy(messagebuf, name, KEYEVENTTYPESIZE);
+    int offset = KEYEVENTTYPESIZE;
+    memcpy(messagebuf + offset, &time, sizeof(time));
+    offset += sizeof(time);
+    memcpy(messagebuf + offset, &opt, sizeof(int) + STATUSSIZE);
+    return &messagebuf[0];
+}
+
+DataOpt
+DataMessage::getDataOpt()
+{
+    return dataopt;
+}
diff --git a/src/datamessage.h b/src/datamessage.h
new file mode 100644 (file)
index 0000000..482199c
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef DATAMESSAGE_H_
+#define DATAMESSAGE_H_
+
+#include "messageformat.h"
+
+class StandardMessage;
+
+/**
+ * This class handled the data message.
+ */
+class DataMessage : public StandardMessage {
+public:
+    static const int STATUSSIZE = BUFSIZE - KEYEVENTTYPESIZE - sizeof(timeval)
+            - sizeof(int);
+    /**
+     * Constructor.
+     */
+    DataMessage();
+    /**
+     * Destructor.
+     */
+    ~DataMessage();
+    /**
+     * This function will attempt to decode the message.
+     *
+     * @param msg Message to be deceded.
+     * @param size the size of the message.
+     */
+    void
+    decode(char *msg, int size);
+    /**
+     * This function decodes the data portion of the data message.
+     *
+     * @param keyeventtype The name of vehicle information of MW.
+     * @param time The recordtime of vehicle information of MW.
+     * @param opt The data portion of the data message.
+     */
+    void
+    decodeOpt(char *keyeventype, timeval time, void *opt);
+    /**
+     * This function will attempt to encode the message.
+     *
+     * @param name The name of vehicle information of MW.
+     * @param time The recordtime of vehicle information of MW.
+     * @param opt The data portion of the data message.
+     * @return Binary data.
+     */
+    char *
+    encode(char *name, timeval time, DataOpt opt);
+
+    /**
+     * Get the data portion of the data message.
+     *
+     * @return The data portion of the data message.
+     */
+    DataOpt
+    getDataOpt();
+
+public:
+    DataOpt dataopt;
+};
+#endif // #ifndef DATAMESSAGE_H_
diff --git a/src/eventmessage.cc b/src/eventmessage.cc
new file mode 100644 (file)
index 0000000..e13b2ec
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include "eventmessage.h"
+
+EventMessage::EventMessage()
+{
+}
+
+EventMessage::~EventMessage()
+{
+}
+
+void
+EventMessage::decode(char *msg, int size)
+{
+    int restsize = size;
+    if (size <= KEYEVENTTYPESIZE) {
+        memset(KeyEventType, 0, size);
+        memcpy(KeyEventType, msg, size);
+        return;
+    }
+    memcpy(KeyEventType, msg, KEYEVENTTYPESIZE);
+    restsize -= KEYEVENTTYPESIZE;
+    int offset = KEYEVENTTYPESIZE;
+    if (restsize < static_cast<int>(sizeof(timeval))) {
+        return;
+    }
+    memcpy(&recordtime, msg + offset, sizeof(timeval));
+    restsize -= sizeof(timeval);
+    offset += sizeof(timeval);
+    if (restsize >= static_cast<int>(sizeof(eventopt))) {
+        memcpy(&eventopt, msg + offset, sizeof(eventopt));
+    }
+}
+
+void
+EventMessage::decodeOpt(char *keyeventtype, timeval time, void *opt)
+{
+    memset(KeyEventType, 0, KEYEVENTTYPESIZE);
+    memcpy(KeyEventType, keyeventtype, KEYEVENTTYPESIZE);
+    recordtime = time;
+    memcpy(&eventopt, opt, sizeof(eventopt));
+}
+
+char *
+EventMessage::encode(char *name, timeval time, EventOpt opt)
+{
+    memset(messagebuf, 0, sizeof(messagebuf));
+    memcpy(messagebuf, name, KEYEVENTTYPESIZE);
+    int offset = KEYEVENTTYPESIZE;
+    memcpy(messagebuf + offset, &time, sizeof(time));
+    offset += sizeof(time);
+    memcpy(messagebuf + offset, &opt, sizeof(opt));
+    return &messagebuf[0];
+}
+
+EventOpt
+EventMessage::getEventOpt()
+{
+    return eventopt;
+}
diff --git a/src/eventmessage.h b/src/eventmessage.h
new file mode 100644 (file)
index 0000000..7f1854b
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef EVENTMESSAGE_H_
+#define EVENTMESSAGE_H_
+#include "messageformat.h"
+
+class StandardMessage;
+
+/**
+ * This class handled the event message.
+ */
+class EventMessage : public StandardMessage {
+public:
+    /**
+     * Constructor.
+     */
+    EventMessage();
+    /**
+     * Destructor.
+     */
+    ~EventMessage();
+    /**
+     * This function will attempt to decode the message.
+     *
+     * @param msg Message to be deceded.
+     * @param size The size of the message.
+     */
+    void
+    decode(char *msg, int size);
+    /**
+     * This function decodes the data portion of the event message.
+     *
+     * @param keyeventtype The name of vehicle information of MW.
+     * @param time The recordtime of vehicle information of MW.
+     * @param opt The data portion of the event message.
+     */
+    void
+    decodeOpt(char *keyeventype, timeval time, void *opt);
+    /**
+     * This function will attempt to encode the message.
+     *
+     * @param name The name of vehicle information of MW.
+     * @param time The recordtime of vehicle information of MW.
+     * @param opt The data portion of the event message.
+     * @return Binary data.
+     */
+    char *
+    encode(char *name, timeval time, EventOpt opt);
+    /**
+     * Get the data portion of the event message.
+     *
+     * @return The data portion of the event message.
+     */
+    EventOpt
+    getEventOpt();
+
+public:
+    EventOpt eventopt;
+};
+#endif // #ifndef EVENTMESSAGE_H_
diff --git a/src/messageformat.h b/src/messageformat.h
new file mode 100644 (file)
index 0000000..7c613d3
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef MESSAGEFORMAT_H_
+#define MESSAGEFORMAT_H_
+#include "standardmessage.h"
+
+/**
+ * Message Type.
+ */
+enum MessageType {
+    SET, GET, CALLBACK
+};
+
+/**
+ * Common_Status(Used in the data message.)
+ */
+enum CommonStatus {
+    UNKNOWN, NOTSUPPORT, SUPPORT
+};
+
+/**
+ * The size of status(Used in the data message.)
+ */
+static const int STATUSSIZE = StandardMessage::BUFSIZE
+                              - StandardMessage::KEYEVENTTYPESIZE 
+                              - sizeof(timeval) - sizeof(int);
+
+/**
+ * The data portion of the data message.
+ */
+struct DataOpt {
+    enum CommonStatus common_status;
+    char status[STATUSSIZE];
+};
+
+/**
+ * The data portion of the event message.
+ */
+struct EventOpt {
+    int common;
+    int sense;
+    int event_mask;
+};
+#endif // MESSAGEFORMAT_H_
diff --git a/src/mwinterface.cc b/src/mwinterface.cc
new file mode 100644 (file)
index 0000000..03f27fa
--- /dev/null
@@ -0,0 +1,433 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include <iostream>
+
+#include "debugout.h"
+
+#include "mwinterface.h"
+#include "controlwebsocket.h"
+#include "viccommunicator.h"
+
+using ::std::string;
+
+MWNotifyInfo::MWNotifyInfo()
+{
+    memset(nochangemask, 0, sizeof(nochangemask));
+    mutex = PTHREAD_MUTEX_INITIALIZER;
+}
+
+MWNotifyInfo::~MWNotifyInfo()
+{
+    for (auto itr = notifyMap.begin(); itr != notifyMap.end(); itr++) {
+        (*itr).second.clear();
+    }
+    notifyMap.clear();
+}
+
+bool
+MWNotifyInfo::insert(std::string name, int interval, int sense, char *mask)
+{
+    if (sense == 0xff) {
+        eraseAllMask(name);
+    }
+    pthread_mutex_lock(&mutex);
+    if (notifyMap.find(name) == notifyMap.end()) {
+        for (auto itr = notifyMap[name].begin(); itr != notifyMap[name].end();
+             itr++) {
+            if (memcpy((*itr).mask, mask, STATUSSIZE) == 0) {
+                (*itr).interval = interval;
+                pthread_mutex_unlock(&mutex);
+                return true;
+            }
+        }
+    }
+    pthread_mutex_unlock(&mutex);
+    NotifyOpt opt;
+    opt.interval = interval;
+    memcpy(opt.mask, mask, STATUSSIZE);
+    opt.lastChanged.tv_sec = 0;
+    opt.lastChanged.tv_usec = 0;
+    pthread_mutex_lock(&mutex);
+    notifyMap[name].push_back(opt);
+    pthread_mutex_unlock(&mutex);
+    return true;
+}
+
+bool
+MWNotifyInfo::erase(std::string name, char *mask)
+{
+    pthread_mutex_lock(&mutex);
+    if (notifyMap.find(name) == notifyMap.end()) {
+        pthread_mutex_unlock(&mutex);
+        return false;
+    }
+    for (auto itr = notifyMap[name].begin(); itr != notifyMap[name].end();
+         itr++) {
+        if (memcpy((*itr).mask, mask, STATUSSIZE) == 0) {
+            itr = notifyMap[name].erase(itr);
+            pthread_mutex_unlock(&mutex);
+            return true;
+        }
+    }
+    pthread_mutex_unlock(&mutex);
+    return false;
+}
+
+bool
+MWNotifyInfo::eraseAllMask(std::string name)
+{
+    pthread_mutex_lock(&mutex);
+    if (notifyMap.find(name) == notifyMap.end()) {
+        pthread_mutex_unlock(&mutex);
+        return false;
+    }
+    notifyMap[name].clear();
+    notifyMap.erase(name);
+    pthread_mutex_unlock(&mutex);
+    return true;
+}
+
+bool
+MWNotifyInfo::checkNotify(std::string name, char *olddata, char *newdata,
+                          timeval newtime)
+{
+    DebugOut() << "MWNotiryInfo checkNotify(" << name << ")" << std::endl;
+    pthread_mutex_lock(&mutex);
+    if (notifyMap.find(name) == notifyMap.end()) {
+        pthread_mutex_unlock(&mutex);
+        return false;
+    }
+    pthread_mutex_unlock(&mutex);
+    DebugOut(10) << "MWNotiryInfo checkStatus(" << name << ")" << std::endl;
+    char checkDiff[STATUSSIZE] = {};
+    for (int i = 0; i < STATUSSIZE; i++) {
+        checkDiff[i] = (*(olddata + i)) ^ (*(newdata + i));
+    }
+    DebugOut(10) << "MWNotiryInfo Update checkDiff" << std::endl;
+    pthread_mutex_lock(&mutex);
+    for (auto itr = notifyMap[name].begin(); itr != notifyMap[name].end();
+         itr++) {
+        for (int i = 0; i < STATUSSIZE; i++) {
+            DebugOut() << "checkDiff[" << i << "] = " << checkDiff[i]
+                       << ", (*itr).mask[i] = " << (*itr).mask[i]
+                       << " , checkDiff[i] & (*itr).mask[i] = "
+                       << (int)(checkDiff[i] & (*itr).mask[i]) << std::endl;
+            if ((checkDiff[i] & (*itr).mask[i]) != 0x00) {
+                pthread_mutex_unlock(&mutex);
+                return true;
+                /* ToDo */
+                /* Check Interval */
+            }
+        }
+    }
+    pthread_mutex_unlock(&mutex);
+    return false;
+}
+
+MWIF::MWIF()
+{
+    for (int i = 0; i < SERVERNUM; i++) {
+        websocketserver[i] = NULL;
+    }
+}
+
+MWIF::~MWIF()
+{
+    vehicleinfoArray.clear();
+    for (int i = 0; i < SERVERNUM; i++) {
+        if (websocketserver[i] != NULL) {
+            delete websocketserver[i];
+        }
+    }
+    websocketservermap.clear();
+    mwnotifyinfomap.clear();
+}
+
+bool
+MWIF::initialize(VICCommunicator *com, Config *conf)
+{
+    communicator = com;
+
+    vector<VehicleInfoDefine> table;
+    table = conf->getVehicleInfoConfig();
+    for (auto itr = table.begin(); itr != table.end(); itr++) {
+        MWVehicleInfo vi;
+        vi.name = string((*itr).KeyEventType);
+        memset(&vi.status, 0, STATUSSIZE);
+        vi.statussize = 0;
+        for (auto itr2 = (*itr).status.begin(); itr2 != (*itr).status.end();
+             itr2++) {
+            vi.statussize += (*itr2).typesize;
+            vi.delimeterposition.push_back((*itr2).typesize);
+        }
+        vehicleinfoArray.push_back(vi);
+        DebugOut() << "MWIF initialize mwvehicleinfo name = " << vi.name 
+                   << std::endl;
+    }
+    PortInfo portinfo = conf->getPort();
+    DebugOut() << "MWIF initialize portinfo (" << portinfo.standard.dataPort 
+               << "," << portinfo.standard.controlPort << "," 
+               << portinfo.custom.dataPort << "," 
+               << portinfo.custom.controlPort << ")\n";
+    createThread(&portinfo);
+    return true;
+}
+
+void
+MWIF::send(MWVehicleInfo *vehicleinfo)
+{
+    DebugOut(10) << "MWIF " << "send data is " << vehicleinfo->name << "("
+                 << vehicleinfo->status[0] << ")" << std::endl;
+    if (vehicleinfo == NULL) {
+        return;
+    }
+
+    MWVehicleInfo *curvehicleinfo = find(vehicleinfo->name);
+    if (curvehicleinfo != NULL) {
+        vehicleinfo->statussize = curvehicleinfo->statussize;
+        vehicleinfo->delimeterposition = curvehicleinfo->delimeterposition;
+        DebugOut(10) << "MWIF send : mwnotifyinfomap.size() = "
+                     << mwnotifyinfomap.size() << "\n";
+        for (auto itr = mwnotifyinfomap.begin(); itr != mwnotifyinfomap.end();
+             itr++) {
+            if ((*itr).second.checkNotify(vehicleinfo->name,
+                                          curvehicleinfo->status,
+                                          vehicleinfo->status,
+                                          vehicleinfo->recordtime)) {
+                DebugOut(10) << "MWIF send Notify" << std::endl;
+                sendMessage((*itr).first, SUPPORT, vehicleinfo);
+            }
+        }
+        memcpy(curvehicleinfo->status, vehicleinfo->status, STATUSSIZE);
+        curvehicleinfo->recordtime = vehicleinfo->recordtime;
+    }
+}
+
+void
+MWIF::recvRawdata(int commid, char *keyeventtype, timeval recordtime,
+                  void *data, size_t len)
+{
+    DebugOut() << "MWIF recvRawdata(" << commid << "," << keyeventtype << ")\n";
+    if (find(string(keyeventtype)) != NULL) {
+        if (websocketservermap.find(commid) == websocketservermap.end()) {
+            registDestination(commid);
+        }
+        websocketserver[static_cast<int>(websocketservermap[commid])]->receive(
+                commid, keyeventtype, recordtime, data, len);
+    }
+    // Error Message
+    else {
+        DebugOut() << "MWIF recvRawdata " << "Error Data." << std::endl;
+        MWVehicleInfo errorvi;
+        errorvi.name = string(keyeventtype);
+        errorvi.recordtime = recordtime;
+        errorvi.statussize = len - StandardMessage::KEYEVENTTYPESIZE
+                             - sizeof(timeval) - sizeof(int);
+        memset(errorvi.status, 0, STATUSSIZE);
+        sendMessage(commid, UNKNOWN, &errorvi);
+    }
+}
+
+void
+MWIF::recvMessage(MessageType type, int commid, char *keyeventtype,
+                  timeval recordtime, void *data, size_t len)
+{
+    DebugOut(10) << "MWIF recvMessage(" << commid << ")\n";
+    switch (type) {
+    case MessageType::SET:
+    {
+        DebugOut() << "MWIF recvMessage(" << commid << ",SET) " << keyeventtype
+                   << "\n";
+        DataOpt *opt = reinterpret_cast<DataOpt*>(data);
+        procSetMessage(commid, keyeventtype, recordtime, opt, len);
+        break;
+    }
+    case MessageType::GET:
+    {
+        DebugOut() << "MWIF recvMessage(" << commid << ",GET) " << keyeventtype
+                   << "\n";
+        EventOpt *opt = reinterpret_cast<EventOpt*>(data);
+        procGetMessage(commid, keyeventtype, recordtime, opt, len);
+        break;
+    }
+    case MessageType::CALLBACK:
+    {
+        DebugOut() << "MWIF recvMessage(" << commid << ",CALLBACK) "
+                   << keyeventtype << "\n";
+        EventOpt *opt = reinterpret_cast<EventOpt*>(data);
+        procCallbackMessage(commid, keyeventtype, recordtime, opt, len);
+        break;
+    }
+    default:
+    {
+        break;
+    }
+    }
+}
+
+void
+MWIF::registDestination(int commid)
+{
+    if (websocketservermap.find(commid) == websocketservermap.end()) {
+        for (int i = 0; i < SERVERNUM; i++) {
+            if (websocketserver[i]->registSocket(commid)) {
+                DebugOut() << "MWIF registDestination insert(" << commid << ","
+                           << i << ")\n";
+                websocketservermap.insert(
+                        make_pair(
+                                commid,
+                                static_cast<ControlWebsocket::ServerProtocol>(i)));
+                break;
+            }
+        }
+    }
+}
+
+void
+MWIF::unregistDestination(int commid)
+{
+    if (websocketservermap.find(commid) != websocketservermap.end()) {
+        for (int i = 0; i < SERVERNUM; i++) {
+            if (websocketserver[i]->unregistSocket(commid)) {
+                DebugOut() << "MWIF unregistDestination erase(" << commid << ","
+                           << i << ")\n";
+                websocketservermap.erase(commid);
+                break;
+            }
+        }
+    }
+}
+
+void
+MWIF::sendMessage(int commid, CommonStatus status, MWVehicleInfo *vehicleinfo)
+{
+    DataOpt opt;
+    opt.common_status = status;
+    memcpy(opt.status, vehicleinfo->status, STATUSSIZE);
+    size_t len = StandardMessage::KEYEVENTTYPESIZE + sizeof(timeval)
+                 + sizeof(int) + vehicleinfo->statussize;
+    DebugOut(10) << "MWIF sendMessage vehicleinfo->statussize = "
+                 << vehicleinfo->statussize << ", len = " << len << std::endl;
+    if (websocketservermap.find(commid) == websocketservermap.end()) {
+        registDestination(commid);
+    }
+    DebugOut() << "MWIF sendMessage controlwebsocket->send(" << commid << ","
+               << vehicleinfo->name << "),len = " << len << std::endl;
+    websocketserver[websocketservermap[commid]]->send(
+            commid, const_cast<char*>(vehicleinfo->name.c_str()),
+            vehicleinfo->recordtime, (void *)&opt, len);
+}
+
+void
+MWIF::createThread(PortInfo *portinfo)
+{
+    for (int i = 0; i < SERVERNUM; i++) {
+        websocketserver[i] = new ControlWebsocket();
+    }
+    ControlWebsocket::mwif = this;
+    websocketserver[ControlWebsocket::DATA_STANDARD]->initialize(
+            portinfo->standard.dataPort, ControlWebsocket::DATA_STANDARD);
+    websocketserver[ControlWebsocket::CONTROL_STANDARD]->initialize(
+            portinfo->standard.controlPort, ControlWebsocket::CONTROL_STANDARD);
+    websocketserver[ControlWebsocket::DATA_CUSTOM]->initialize(
+            portinfo->custom.dataPort, ControlWebsocket::DATA_CUSTOM);
+    websocketserver[ControlWebsocket::CONTROL_CUSTOM]->initialize(
+            portinfo->custom.controlPort, ControlWebsocket::CONTROL_CUSTOM);
+}
+
+MWVehicleInfo *
+MWIF::find(string name)
+{
+    for (auto itr = vehicleinfoArray.begin(); itr != vehicleinfoArray.end();
+         itr++) {
+        DebugOut(10) << "MWIF find" << (*itr).name << std::endl;
+        if ((*itr).name == name) {
+            return &(*itr);
+        }
+    }
+    DebugOut() << "MWIF find can't find property = " << name << std::endl;
+    return NULL;
+}
+
+void
+MWIF::procSetMessage(int commid, char *keyeventtype, timeval recordtime,
+                     DataOpt *data, size_t len)
+{
+    MWVehicleInfo *vehicleinfo = find(string(keyeventtype));
+    MWVehicleInfo updatevehicleinfo;
+    updatevehicleinfo.name = vehicleinfo->name;
+    updatevehicleinfo.recordtime = recordtime;
+    updatevehicleinfo.statussize = vehicleinfo->statussize;
+    memcpy(updatevehicleinfo.status, data->status, STATUSSIZE);
+    // Update AMB Data
+    communicator->setAMBVehicleInfo(&updatevehicleinfo);
+    // Update MW Data
+    vehicleinfo->recordtime = recordtime;
+    memcpy(vehicleinfo->status, updatevehicleinfo.status, STATUSSIZE);
+}
+
+void
+MWIF::procGetMessage(int commid, char *keyeventtype, timeval recordtime,
+                     EventOpt *data, size_t len)
+{
+    MWVehicleInfo vehicleinfo;
+    vehicleinfo.name = string(keyeventtype);
+    vehicleinfo.statussize = find(vehicleinfo.name)->statussize;
+    communicator->getAMBVehicleInfo(&vehicleinfo);
+    sendMessage(commid, SUPPORT, &vehicleinfo);
+}
+
+void
+MWIF::procCallbackMessage(int commid, char *keyeventtype, timeval recordtime,
+                          EventOpt *data, size_t len)
+{
+    MWVehicleInfo *vehicleinfo = find(string(keyeventtype));
+    //Set Mask bit.
+    int index = 0;
+    char mask[STATUSSIZE];
+    memset(mask, 0, STATUSSIZE);
+    for (int i = 0; i < static_cast<int>(vehicleinfo->delimeterposition.size());
+         i++) {
+        char flg = 0x00;
+        if (data->sense == 0xff || (i + 1) == data->sense) {
+            flg = 0xff;
+        }
+        for (int j = 0; j < vehicleinfo->delimeterposition[i]; j++) {
+            mask[index++] = flg;
+        }
+    }
+
+    MWNotifyInfo notifyinfo;
+    if (mwnotifyinfomap.find(commid) == mwnotifyinfomap.end()) {
+        mwnotifyinfomap.insert(make_pair(commid, notifyinfo));
+    }
+    else {
+        notifyinfo = mwnotifyinfomap[commid];
+    }
+    if (notifyinfo.insert(string(keyeventtype), data->common, data->sense,
+                          mask)) {
+        sendMessage(commid, SUPPORT, vehicleinfo);
+    }
+    else {
+        sendMessage(commid, NOTSUPPORT, vehicleinfo);
+    }
+    mwnotifyinfomap[commid] = notifyinfo;
+}
diff --git a/src/mwinterface.h b/src/mwinterface.h
new file mode 100644 (file)
index 0000000..ff42886
--- /dev/null
@@ -0,0 +1,214 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef MWINTERFACE_H
+#define MWINTERFACE_H
+
+#include <pthread.h>
+#include <sys/time.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <libwebsockets.h>
+
+#include "config.h"
+#include "controlwebsocket.h"
+#include "messageformat.h"
+
+class VICCommunicator;
+
+/**
+ * Vehicle information of MW
+ */
+struct MWVehicleInfo {
+    std::string name;
+    timeval recordtime;
+    char status[STATUSSIZE];
+    int statussize;
+    vector<int> delimeterposition;
+};
+
+/**
+ * This class manages the vehicle information to be notified to MW.
+ */
+class MWNotifyInfo {
+public:
+    /**
+     * Conditions of vehicle information changes notification.
+     */
+    struct NotifyOpt {
+        std::string name;
+        int interval;
+        char mask[STATUSSIZE];
+        timeval lastChanged;
+    };
+    /**
+     * Constructor.
+     */
+    MWNotifyInfo();
+    /**
+     * Destructor.
+     */
+    ~MWNotifyInfo();
+    /**
+     * This function registers the change notifiction contitions.
+     *
+     * @param name The name of vehicle information of MW
+     * @param interval Transmission interval change notification.
+     * @param sense Information to detect.
+     * @param mask For change detection mask.
+     * @return Success : true Failure : false
+     */
+    bool
+    insert(std::string name, int interval, int sense, char *mask);
+    /**
+     * This function removes the notification conditions.
+     *
+     * @param name The name of vehicle information of MW.
+     * @param mask For change detection mask.
+     * @return Success : true Failure : false
+     */
+    bool
+    erase(std::string name, char *mask);
+    /**
+     * This function removes the all notification conditions with a matching name.
+     *
+     * @param name The name of vehicle information of MW.
+     * @return Success : true Failure : false
+     */
+    bool
+    eraseAllMask(std::string name);
+    /**
+     * This function will check whether the vehicle information is applicable to the notification conditions.
+     * If applicable, update the internal table.
+     *
+     * @param name The name of vehicle information of MW.
+     * @param olddata Value before the change.
+     * @param newdata Value after the change.
+     * @param newtime Time after the change.
+     * @return Success : true Failure : false
+     */
+    bool
+    checkNotify(std::string name, char *olddata, char *newdata,
+                timeval newtime);
+private:
+    enum GetType {
+        NORMAL, ALLNAME, ALLCOMMID, ALLDATA
+    };
+    std::map<std::string, std::vector<NotifyOpt> > notifyMap;
+    char nochangemask[STATUSSIZE];
+    pthread_mutex_t mutex;
+};
+
+/**
+ * Interface of MW and Plugin.
+ */
+class MWIF {
+public:
+    /**
+     * Constructor.
+     */
+    MWIF();
+    /**
+     * Destructor.
+     */
+    ~MWIF();
+    /**
+     * Initialization.
+     *
+     * @param comm Instance of VICCommunicator.
+     * @param conf Instance of Config.
+     * @return Success : true Failure : false
+     */
+    bool
+    initialize(VICCommunicator *com, Config *conf);
+    /**
+     * This function issues a request to send vehicle information to the MW.
+     *
+     * @param vehicleinfo Vehicle information of MW.
+     */
+    void
+    send(MWVehicleInfo *vehicleinfo);
+    /**
+     * This function distributes the incoming mesage from the MW.
+     *
+     * @param commid socket id.
+     * @param keyeventtype The name of vehicle information of MW.
+     * @param recordtime Time of the message.
+     * @param data Binary data other than intersection.
+     * @param len Length of the message.
+     */
+    void
+    recvRawdata(int commid, char *keyeventtype, timeval recordtime, void *data,
+                size_t len);
+    /*
+     * This function is a function of the received vehicle information message.
+     *
+     * @param type Type of the received message.
+     * @param commid socket id.
+     * @param keyeventtype The name of vehicle information of MW.
+     * @param recordtime Time of the message.
+     * @param data Binary data other than intersection.
+     * @param len Length of the message.
+     */
+    void
+    recvMessage(MessageType type, int commid, char *keyeventtype,
+                timeval recordtime, void *data, size_t len);
+    /**
+     * Mapping the instance and destination socket ID.
+     *
+     * @param commid Socket ID.
+     */
+
+    void
+    registDestination(int commid);
+    /**
+     * Unmapped instances and destination socket ID.
+     * 
+     * @param commid Socket ID.
+     */
+    void
+    unregistDestination(int commid);
+private:
+
+    void
+    sendMessage(int commid, CommonStatus status, MWVehicleInfo *vehicleinfo);
+    void
+    createThread(PortInfo *portinfo);
+    MWVehicleInfo *
+    find(std::string name);
+    void
+    procSetMessage(int commid, char *keyeventtype, timeval recordtime,
+                   DataOpt *data, size_t len);
+    void
+    procGetMessage(int commid, char *keyeventtype, timeval recordtime,
+                   EventOpt *data, size_t len);
+    void
+    procCallbackMessage(int commid, char *keyeventtype, timeval recordtime,
+                        EventOpt *data, size_t len);
+
+    static const int SERVERNUM = 4;
+    std::vector<MWVehicleInfo> vehicleinfoArray;
+    ControlWebsocket *websocketserver[SERVERNUM];
+    VICCommunicator *communicator;
+    std::map<int, ControlWebsocket::ServerProtocol> websocketservermap;
+    std::map<int, MWNotifyInfo> mwnotifyinfomap;
+};
+#endif // MWINTERFACE_H
diff --git a/src/standardmessage.cc b/src/standardmessage.cc
new file mode 100644 (file)
index 0000000..03b9ee8
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include "standardmessage.h"
+
+StandardMessage::StandardMessage()
+{
+}
+
+StandardMessage::~StandardMessage()
+{
+}
+
+void
+StandardMessage::decode(char *msg, int size)
+{
+    int restsize = size;
+    if (size <= KEYEVENTTYPESIZE) {
+        memset(KeyEventType, 0, size);
+        memcpy(KeyEventType, msg, size);
+        return;
+    }
+    memcpy(KeyEventType, msg, KEYEVENTTYPESIZE);
+    restsize -= KEYEVENTTYPESIZE;
+    if (restsize >= static_cast<int>(sizeof(timeval))) {
+        memcpy(&recordtime, msg + KEYEVENTTYPESIZE, sizeof(timeval));
+    }
+}
+
+char *
+StandardMessage::encode(char *name, timeval time)
+{
+    memset(messagebuf, 0, sizeof(messagebuf));
+    memcpy(messagebuf, name, KEYEVENTTYPESIZE);
+    memcpy(messagebuf + KEYEVENTTYPESIZE, &time, sizeof(time));
+    return &messagebuf[0];
+}
+char *
+StandardMessage::getKeyEventType()
+{
+    return &KeyEventType[0];
+}
+
+timeval
+StandardMessage::getRecordtime()
+{
+    return recordtime;
+}
diff --git a/src/standardmessage.h b/src/standardmessage.h
new file mode 100644 (file)
index 0000000..d84ae0d
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef STANDARDMESSGAE_H_
+#define STANDARDMESSGAE_H_
+
+#include <sys/time.h>
+
+/**
+ * This class handles the common parts of the message.
+ */
+class StandardMessage {
+public:
+    /**
+     * Constructor.
+     */
+    StandardMessage();
+    /**
+     * Destoructor.
+     */
+    ~StandardMessage();
+    /**
+     * This function will attempt to decode the message.
+     *
+     * @param msg Message to be deceded.
+     * @param size the size of the message.
+     */
+    virtual void
+    decode(char *msg, int size);
+    /**
+     * This function decodes the data portion of the data message.
+     *
+     * @param keyeventtype The name of vehicle information of MW.
+     * @param time The recordtime of vehicle information of MW.
+     * @param opt The data portion of the data message.
+     */
+    char*
+    encode(char *name, timeval time);
+
+    /**
+     * Get the name of vehicle information of MW.
+     *
+     * @return The name of vehicle information of MW.
+     */
+    char *
+    getKeyEventType();
+    /**
+     * Get the recordtime of vehicle information of MW.
+     *
+     * @return The recordtime of vehicle information of MW.
+     */
+    timeval
+    getRecordtime();
+
+    /**
+     * The size of message buffer.
+     */
+    static const int BUFSIZE = 256;
+    /**
+     * The size of name of vehicle information of MW.
+     */
+    static const int KEYEVENTTYPESIZE = 64;
+
+protected:
+    char messagebuf[BUFSIZE];
+    char KeyEventType[KEYEVENTTYPESIZE];
+    timeval recordtime;
+};
+#endif // #ifndef STANDARDMESSGAE_H_
diff --git a/src/viccommunicator.cc b/src/viccommunicator.cc
new file mode 100644 (file)
index 0000000..747a953
--- /dev/null
@@ -0,0 +1,131 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include "debugout.h"
+
+#include "ambinterface.h"
+#include "convert.h"
+#include "messageformat.h"
+#include "mwinterface.h"
+#include "viccommunicator.h"
+
+VICCommunicator::VICCommunicator()
+{
+}
+
+VICCommunicator::~VICCommunicator()
+{
+}
+
+bool
+VICCommunicator::initialize(AMBIF *amb, MWIF *mw, Converter *conv)
+{
+    converter = conv;
+    ambif = amb;
+    mwif = mw;
+    return true;
+}
+
+void
+VICCommunicator::setAMBVehicleInfo(MWVehicleInfo *vehicleinfo)
+{
+    AMBVehicleInfo ambvehicleinfo[maxambdatasize];
+    DebugOut() << "VICCOMM" << " in setAMBVehicleInfo(" << vehicleinfo->name
+               << ")" << " status[0] = " << vehicleinfo->status[0] << "\n";
+    resetAmbBuf(&ambvehicleinfo[0], maxambdatasize);
+    int ret = converter->convertMWtoAMB(vehicleinfo, &ambvehicleinfo[0],
+                                        maxambdatasize);
+    for (int i = 0; i < ret; i++) {
+        ambif->requestUpdate(&ambvehicleinfo[i]);
+        DebugOut() << "VICCOMM" << " out setAMBVehicleInfo(AMBname = "
+                   << ambvehicleinfo[i].name << ","
+                   << ambvehicleinfo[i].value->toString() << ")\n";
+    }
+    for (int i = 0; i < maxambdatasize; i++) {
+        if (ambvehicleinfo[i].value != NULL) {
+            delete ambvehicleinfo[i].value;
+        }
+    }
+    DebugOut(10) << "VICCOMM" << " out setAMBVehicleInfo(MWname = "
+                 << vehicleinfo->name << ")";
+}
+
+void
+VICCommunicator::getAMBVehicleInfo(MWVehicleInfo *vehicleinfo)
+{
+    AMBVehicleInfo *ambvehicleinfo[maxambdatasize];
+    AMBVehicleInfo tempambvehicleinfo[maxambdatasize];
+
+    DebugOut() << "VICCOMM" << " in getAMBVehicleInfo(" << vehicleinfo->name
+               << "," << vehicleinfo->status[0] << ")\n";
+    resetAmbBuf(&tempambvehicleinfo[0], maxambdatasize);
+    int ret = converter->convertMWtoAMB(vehicleinfo, &tempambvehicleinfo[0],
+                                        maxambdatasize);
+    for (int i = 0; i < ret; i++) {
+        delete tempambvehicleinfo[i].value;
+        ambvehicleinfo[i] = ambif->getPropertyRequest(
+                tempambvehicleinfo[i].name);
+        DebugOut() << "VICCOMM" << " getAMBVehicleInfo(AMBname = "
+                   << ambvehicleinfo[i]->name << ","
+                   << ambvehicleinfo[i]->value->toString() << ")\n";
+        converter->convertAMBtoMW(ambvehicleinfo[i], vehicleinfo);
+    }
+    DebugOut() << "VICCOMM" << " out getAMBVehicleInfo(MWname = "
+               << vehicleinfo->name << "," << vehicleinfo->status[0] << ")\n";
+}
+
+void
+VICCommunicator::setMWVehicleInfo(AMBVehicleInfo *vehicleinfo)
+{
+    MWVehicleInfo mwvehicleinfo;
+    DebugOut() << "VICCOMM" << " in setMWVehicleInfo(AMBname = "
+               << vehicleinfo->name << "," << vehicleinfo->value->toString()
+               << ")\n";
+    resetMwBuf(&mwvehicleinfo);
+    converter->convertAMBtoMW(vehicleinfo, &mwvehicleinfo);
+    mwif->send(&mwvehicleinfo);
+    DebugOut() << "VICCOMM" << " out setMWVehicleInfo(MWname = "
+               << mwvehicleinfo.name << "," << mwvehicleinfo.status[0] << ")\n";
+}
+
+void
+VICCommunicator::getMWVehicleInfo(AMBVehicleInfo *vehicleinfo)
+{
+    /* don't use */
+}
+
+void
+VICCommunicator::resetAmbBuf(AMBVehicleInfo *vehicleinfo, size_t len)
+{
+    for (int i = 0; i < static_cast<int>(len); i++) {
+        vehicleinfo[i].name = "";
+        vehicleinfo[i].value = NULL;
+        vehicleinfo[i].isCustom = false;
+    }
+}
+
+void
+VICCommunicator::resetMwBuf(MWVehicleInfo *vehicleinfo)
+{
+    vehicleinfo->name = "";
+    vehicleinfo->recordtime.tv_sec = 0;
+    vehicleinfo->recordtime.tv_usec = 0;
+    memset(vehicleinfo->status, 0, STATUSSIZE);
+}
diff --git a/src/viccommunicator.h b/src/viccommunicator.h
new file mode 100644 (file)
index 0000000..985e842
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef VICCOMMUNICATOR_H
+#define VICCOMMUNICATOR_H
+
+#include "ambinterface.h"
+
+class Converter;
+class MWIF;
+
+/**
+ * This class is an interface AMBIF class and MWIF class.
+ *
+ */
+class VICCommunicator {
+public:
+    /**
+     * Constructor.
+     */
+    VICCommunicator();
+    /**
+     * Destructor.
+     */
+    ~VICCommunicator();
+    /**
+     * Initialization.
+     * 
+     * @param ambif Instance of AMBIF
+     * @param mwif Instance of MWIF
+     * @param conf Instance of Converter
+     * @return Success : true Failure : false
+     */
+    bool
+    initialize(AMBIF *ambif, MWIF *mwif, Converter *conv);
+    /**
+     * This function changes the vehicle information of AMBIF.
+     *
+     * @param vehicleinfo Vehicle information of MW.
+     */
+    void
+    setAMBVehicleInfo(MWVehicleInfo *vehicleinfo);
+    /**
+     * This function retrieves vehicle information about the AMBIF.
+     *
+     * @param vehicleinfo Vehicle information of MW.
+     */
+    void
+    getAMBVehicleInfo(MWVehicleInfo *vehicleinfo);
+    /**
+     * This function changes the vehicle information of MWIF.
+     *
+     * @param vehicleinfo Vehicle information of AMB.
+     */
+    void
+    setMWVehicleInfo(AMBVehicleInfo *vehicleinfo);
+    /**
+     * Unused class
+     */
+    void
+    getMWVehicleInfo(AMBVehicleInfo *vehicleinfo);
+    /**
+     * Buffer size of vehicle information of AMB.
+     */
+    static const int maxambdatasize = 16;
+private:
+    void
+    resetAmbBuf(AMBVehicleInfo *vehicleinfo, size_t len);
+    void
+    resetMwBuf(MWVehicleInfo *vehicleinfo);
+
+    Converter *converter;
+    AMBIF *ambif;
+    MWIF *mwif;
+    AMBVehicleInfo ambvehicleinfo[maxambdatasize];
+    MWVehicleInfo mwvehicleinfo;
+};
+#endif // #ifndef VICCOMMUNICATOR_H
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e5c6a51
--- /dev/null
@@ -0,0 +1,11 @@
+include(CheckIncludeFiles)
+set(CMAKE_CXX_FLAGS "-g")
+include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} ${gio_INCLUDE_DIRS} ${gio-unix_INCLUDE_DIRS} /usr/include/amb /usr/include/dbus-1.0 ../src)
+
+set(testVehiclePluginMW_sources ../src/config.cc ../src/standardmessage.cc ../src/eventmessage.cc ../src/datamessage.cc controlwebsocketclient.cc scenarioengine.cc mwscenario.cc)
+add_executable(testVehiclePluginMW ${testVehiclePluginMW_sources})
+target_link_libraries(testVehiclePluginMW amb pthread websockets -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} ${gio_LIBRARIES} ${gio-unix_LIBRARIES})
+
+set(testVehiclePluginWSApp_sources ../src/config.cc ../src/standardmessage.cc ../src/eventmessage.cc ../src/datamessage.cc configamb.cc standardjsonmessage.cc controlwebsocketclient.cc controlwebsocketclientapp.cc scenarioengine.cc websocketscenario.cc)
+add_executable(testVehiclePluginWSApp ${testVehiclePluginWSApp_sources})
+target_link_libraries(testVehiclePluginWSApp amb pthread websockets -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} ${gio_LIBRARIES} ${gio-unix_LIBRARIES})
diff --git a/tests/configamb.cc b/tests/configamb.cc
new file mode 100644 (file)
index 0000000..e197d87
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include <fstream>
+#include <iostream>
+#include <stdexcept>
+
+#ifdef JSONC
+#include <json/json.h>
+#else
+#include <json-glib/json-glib.h>
+
+#include "nullptr.h"
+#endif
+
+#include "debugout.h"
+
+#include "configamb.h"
+
+using std::string;
+using std::vector;
+
+ConfigAMB::ConfigAMB() : port(23000)
+{
+}
+
+ConfigAMB::~ConfigAMB()
+{
+}
+
+std::string
+ConfigAMB::getAMBformatPath()
+{
+    return ambformatpath;
+}
+
+int
+ConfigAMB::getPort()
+{
+    return port;
+}
+
+bool
+ConfigAMB::readConfig(std::string confpath)
+{
+    std::ifstream in(confpath, std::ios::in);
+    std::string output;
+    std::string line;
+    while (in.good()) {
+        getline(in, line);
+        output.append(line);
+    }
+    return parseJson(output);
+}
+
+bool
+ConfigAMB::parseJson(string config)
+{
+    bool ret = false;
+    JsonParser* parser = json_parser_new();
+    GError* error = nullptr;
+    if (!json_parser_load_from_data(parser, config.c_str(), config.length(),
+                                    &error)) {
+        DebugOut() << "Failed to load config: " << error->message;
+        return ret;
+    }
+
+    JsonNode* node = json_parser_get_root(parser);
+
+    if (node == nullptr) {
+        DebugOut() << "Unable to get JSON root object";
+        return ret;
+    }
+
+    JsonReader* reader = json_reader_new(node);
+
+    if (reader == nullptr) {
+        DebugOut() << "Unable to create JSON reader";
+        return ret;
+    }
+
+    DebugOut(10) << "Config members: " << json_reader_count_members(reader)
+                 << endl;
+
+    json_reader_read_member(reader, "sources");
+
+    const GError * srcReadError = json_reader_get_error(reader);
+
+    if (srcReadError != nullptr) {
+        DebugOut() << "Error getting sources member: " << srcReadError->message
+                   << endl;
+        return ret;
+    }
+
+    g_assert(json_reader_is_array(reader));
+
+    std::string name = "";
+    for (int i = 0; i < json_reader_count_elements(reader); i++) {
+        json_reader_read_element(reader, i);
+
+        json_reader_read_member(reader, "name");
+        name = std::string(json_reader_get_string_value(reader));
+        json_reader_end_member(reader);
+
+        if (name != "VehicleSource") {
+            continue;
+        }
+        json_reader_read_member(reader, "configfile");
+        ambformatpath = std::string(json_reader_get_string_value(reader));
+        json_reader_end_member(reader);
+        json_reader_end_element(reader);
+        ret = true;
+    }
+
+    json_reader_end_member(reader);
+    if (!ret) {
+        std::cerr << "Can't find AMBformat path.\n";
+        return ret;
+    }
+
+    ///read the sinks:
+
+    json_reader_read_member(reader, "sinks");
+
+    for (int i = 0; i < json_reader_count_elements(reader); i++) {
+        json_reader_read_element(reader, i);
+
+        json_reader_read_member(reader, "name");
+        name = std::string(json_reader_get_string_value(reader));
+        json_reader_end_member(reader);
+
+        if (name != "WebsocketSink") {
+            continue;
+        }
+
+        if (json_reader_read_member(reader, "port")) {
+            port = json_reader_get_int_value(reader);
+            json_reader_end_member(reader);
+        }
+        else {
+            port = 23000;
+        }
+
+        json_reader_end_element(reader);
+    }
+
+    json_reader_end_member(reader);
+
+    ///TODO: this will probably explode:
+
+    if (error) {
+        g_error_free(error);
+    }
+
+    g_object_unref(reader);
+    g_object_unref(parser);
+    return ret;
+}
diff --git a/tests/configamb.h b/tests/configamb.h
new file mode 100644 (file)
index 0000000..db28cb4
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef CONFIGAPP_H
+#define CONFIGAPP_H
+
+#include <string>
+#include <vector>
+
+#include "config.h"
+
+/**
+ * This class handles the data in the configuration file.
+ */
+class ConfigAMB : public Config {
+public:
+    /**
+     * Constructor.
+     */
+    ConfigAMB();
+    /**
+     * Destructor.
+     */
+    ~ConfigAMB();
+    bool
+    readConfig(std::string confpath);
+    int
+    getPort();
+    std::string
+    getAMBformatPath();
+private:
+    bool
+    parseJson(std::string config);
+    std::string ambformatpath;
+    int port;
+};
+#endif // #ifndef CONFIGAPP_H
diff --git a/tests/controlwebsocketclient.cc b/tests/controlwebsocketclient.cc
new file mode 100644 (file)
index 0000000..1aa370d
--- /dev/null
@@ -0,0 +1,191 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include <iostream>
+
+#include "debugout.h"
+
+#include "config.h"
+#include "controlwebsocketclient.h"
+#include "datamessage.h"
+#include "eventmessage.h"
+#include "messageformat.h"
+
+pthread_mutex_t ControlWebsocketClient::mutex_scenario =
+        PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t ControlWebsocketClient::cond_scenario = PTHREAD_COND_INITIALIZER;
+std::string ControlWebsocketClient::vehiclename_scenario = "";
+
+ControlWebsocketClient::ControlWebsocketClient()
+{
+    mutex = PTHREAD_MUTEX_INITIALIZER;
+    protocollist[1] = {NULL, NULL, 0};
+}
+
+ControlWebsocketClient::~ControlWebsocketClient()
+{
+}
+
+bool
+ControlWebsocketClient::initialize(int port,
+                                   enum ControlWebsocket::ServerProtocol stype)
+{
+    DebugOut(10) << "ControlWebsocketClient initialize.(" << port << ")\n";
+    type = stype;
+    switch (type) {
+    case ControlWebsocket::DATA_STANDARD:
+    {
+        protocollist[0] = {"standarddatamessage-only", ControlWebsocketClient::callback_receive, 0};
+        break;
+    }
+    case ControlWebsocket::CONTROL_STANDARD : {
+        protocollist[0] = {"standardcontrolmessage-only", ControlWebsocketClient::callback_receive, 0};
+        break;
+    }
+    case ControlWebsocket::DATA_CUSTOM : {
+        protocollist[0] = {"customdatamessage-only", ControlWebsocketClient::callback_receive, 0};
+        break;
+    }
+    case ControlWebsocket::CONTROL_CUSTOM : {
+        protocollist[0] = {"customcontrolmessage-only", ControlWebsocketClient::callback_receive, 0};
+        break;
+    }
+    default : {
+        return false;
+    }
+    }
+    context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, "lo",
+                                          protocollist,
+                                          libwebsocket_internal_extensions,
+                                          NULL, NULL, -1, -1, 0);
+    if (context == NULL) {
+        return false;
+    }
+    socket = libwebsocket_client_connect(context, "127.0.0.1", port, 0, "/",
+                                         "localhost", "websocket",
+                                         protocollist[0].name, -1);
+    if (socket == NULL) {
+        return false;
+    }
+    if (pthread_create(&threadid, NULL, ControlWebsocketClient::run,
+                       (void*)this) == -1) {
+        libwebsocket_context_destroy(context);
+        return false;
+    }
+    return true;
+}
+
+bool
+ControlWebsocketClient::send(char *keyeventtype, timeval time, void *data,
+                             size_t len)
+{
+    pthread_mutex_lock(&mutex);
+    memset(buf, 0, sizeof(buf));
+    switch (type) {
+    case ControlWebsocket::DATA_STANDARD:
+    case ControlWebsocket::DATA_CUSTOM:
+    {
+        memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING,
+               datamsg.encode(keyeventtype, time,
+                              *(reinterpret_cast<DataOpt*>(data))),
+               len);
+        DebugOut(10) << keyeventtype << " encode\n";
+        break;
+    }
+    case ControlWebsocket::CONTROL_STANDARD:
+    case ControlWebsocket::CONTROL_CUSTOM:
+    {
+        memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING,
+               eventmsg.encode(keyeventtype, time,
+                               *(reinterpret_cast<EventOpt*>(data))),
+               len);
+        break;
+    }
+    default:
+    {
+        return false;
+        break;
+    }
+    }
+    int ret = libwebsocket_write(
+            socket,
+            reinterpret_cast<unsigned char*>(buf + LWS_SEND_BUFFER_PRE_PADDING),
+            len, LWS_WRITE_BINARY);
+    DebugOut(10) << "libwebsocket_write return " << ret << "\n";
+    pthread_mutex_unlock(&mutex);
+    return true;
+}
+
+bool
+ControlWebsocketClient::receive(char *keyeventtype, timeval recordtime,
+                                void *data, size_t len)
+{
+    datamsg.decodeOpt(keyeventtype, recordtime, data);
+    return true;
+}
+
+void
+ControlWebsocketClient::observation()
+{
+    int ret = 0;
+    while (ret >= 0) {
+        ret = libwebsocket_service(context, 100);
+        if (ret != 0) {
+            break;
+        }
+    }
+}
+
+int
+ControlWebsocketClient::callback_receive(libwebsocket_context *context,
+                                         libwebsocket *wsi,
+                                         libwebsocket_callback_reasons reason,
+                                         void *user, void *in, size_t len)
+{
+    switch (reason) {
+    case LWS_CALLBACK_CLIENT_RECEIVE:
+    {
+        DataMessage msg;
+        msg.decode(reinterpret_cast<char*>(in), len);
+        DebugOut(10) << "[R]: " << msg.getKeyEventType() << " , "
+                     << msg.getRecordtime().tv_sec << "."
+                     << msg.getRecordtime().tv_usec << " , ";
+        if (string(msg.getKeyEventType())
+                == ControlWebsocketClient::vehiclename_scenario) {
+            pthread_cond_signal(&ControlWebsocketClient::cond_scenario);
+        }
+        break;
+    }
+    default:
+    {
+        break;
+    }
+    }
+    return 0;
+}
+
+void *
+ControlWebsocketClient::run(void *arg)
+{
+    ControlWebsocketClient *control =
+            reinterpret_cast<ControlWebsocketClient*>(arg);
+    control->observation();
+    return NULL;
+}
diff --git a/tests/controlwebsocketclient.h b/tests/controlwebsocketclient.h
new file mode 100644 (file)
index 0000000..3ce2baa
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef CONTROLWEBSOCKETCLIENT_H_
+#define CONTROLWEBSOCKETCLIENT_H_
+
+#include <pthread.h>
+#include <sys/time.h>
+
+#include <map>
+#include <vector>
+
+#include <libwebsockets.h>
+
+#include "controlwebsocket.h"
+#include "eventmessage.h"
+#include "datamessage.h"
+
+class ControlWebsocketClient {
+public:
+    ControlWebsocketClient();
+    ~ControlWebsocketClient();
+    bool
+    initialize(int port, enum ControlWebsocket::ServerProtocol stype);
+    bool
+    send(char *keyeventtype, timeval time, void *data, size_t len);
+    bool
+    receive(char *keyeventtype, timeval recordtime, void *data, size_t len);
+    void
+    observation();
+    static int
+    callback_receive(libwebsocket_context *context, libwebsocket *wsi,
+                     libwebsocket_callback_reasons reason, void *user, void *in,
+                     size_t len);
+    static void *
+    run(void *arg);
+
+    static pthread_mutex_t mutex_scenario;
+    static pthread_cond_t cond_scenario;
+    static std::string vehiclename_scenario;
+
+private:
+    libwebsocket_context *context;
+    libwebsocket* socket;
+    libwebsocket_protocols protocollist[2];
+    enum ControlWebsocket::ServerProtocol type;
+    EventMessage eventmsg;
+    DataMessage datamsg;
+    pthread_t threadid;
+    pthread_mutex_t mutex;
+    char buf[LWS_SEND_BUFFER_PRE_PADDING + StandardMessage::BUFSIZE
+            + LWS_SEND_BUFFER_POST_PADDING];
+};
+#endif // #ifndef CONTROLWEBSOCKETCLIENT_H_
diff --git a/tests/controlwebsocketclientapp.cc b/tests/controlwebsocketclientapp.cc
new file mode 100644 (file)
index 0000000..23b13d4
--- /dev/null
@@ -0,0 +1,157 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include <iostream>
+
+#include "debugout.h"
+
+#include "config.h"
+#include "controlwebsocketclientapp.h"
+#include "messageformat.h"
+
+pthread_mutex_t ControlWebsocketClientApp::mutex_scenario =
+        PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t ControlWebsocketClientApp::cond_scenario =
+        PTHREAD_COND_INITIALIZER;
+std::string ControlWebsocketClientApp::vehiclename_scenario = "";
+
+ControlWebsocketClientApp::ControlWebsocketClientApp()
+{
+    mutex = PTHREAD_MUTEX_INITIALIZER;
+    protocollist[1] = {NULL, NULL, 0};
+}
+
+ControlWebsocketClientApp::~ControlWebsocketClientApp()
+{
+}
+
+bool
+ControlWebsocketClientApp::initialize(int port)
+{
+    DebugOut(10) << "ControlWebsocketClientApp initialize.(" << port << ")\n";
+    protocollist[0] = {"http-only", ControlWebsocketClientApp::callback_receive, 0};
+
+    context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, "lo",
+                                          protocollist,
+                                          libwebsocket_internal_extensions,
+                                          NULL, NULL, -1, -1, 0);
+    if (context == NULL) {
+        return false;
+    }
+    socket = libwebsocket_client_connect(context, "127.0.0.1", port, 0, "/",
+                                         "localhost", "websocket",
+                                         protocollist[0].name, -1);
+    if (socket == NULL) {
+        return false;
+    }
+    if (pthread_create(&threadid, NULL, ControlWebsocketClientApp::run,
+                       (void*)this) == -1) {
+        libwebsocket_context_destroy(context);
+        return false;
+    }
+    return true;
+}
+
+bool
+ControlWebsocketClientApp::send(std::string type, std::string name,
+                                std::string propertyname, std::string value,
+                                double timestamp)
+{
+    pthread_mutex_lock(&mutex);
+    memset(buf, 0, sizeof(buf));
+    JsonData jdata;
+    jdata.propertyName = propertyname;
+    jdata.value = value;
+    jdata.timestamp = timestamp;
+    vector<JsonData> dataarray;
+    dataarray.push_back(jdata);
+    memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING,
+           jsonmsg.encode(type, name, "transactionid", dataarray),
+           JsonMessage::BUFSIZE);
+    int i = 0;
+    while (buf[(i++) + LWS_SEND_BUFFER_PRE_PADDING] != '\0') ;
+    int ret = libwebsocket_write(
+            socket,
+            reinterpret_cast<unsigned char*>(buf + LWS_SEND_BUFFER_PRE_PADDING),
+            i, LWS_WRITE_TEXT);
+    DebugOut(10) << "libwebsocket_write return " << ret << "\n";
+    pthread_mutex_unlock(&mutex);
+    return true;
+}
+
+bool
+ControlWebsocketClientApp::receive(char *keyeventtype, timeval recordtime,
+                                   void *data, size_t len)
+{
+    return true;
+}
+
+void
+ControlWebsocketClientApp::observation()
+{
+    int ret = 0;
+    while (ret >= 0) {
+        ret = libwebsocket_service(context, 100);
+        if (ret != 0) {
+            break;
+        }
+    }
+}
+
+int
+ControlWebsocketClientApp::callback_receive(
+        libwebsocket_context *context, libwebsocket *wsi,
+        libwebsocket_callback_reasons reason, void *user, void *in, size_t len)
+{
+    switch (reason) {
+    case LWS_CALLBACK_CLIENT_RECEIVE:
+    {
+        JsonMessage jmsg;
+        jmsg.decode(std::string(reinterpret_cast<char*>(in)), len);
+        std::vector<JsonData> jdataarray;
+        jdataarray = jmsg.getData();
+        for (auto itr = jdataarray.begin(); itr != jdataarray.end(); itr++) {
+            DebugOut(10) << "[R]: " << (*itr).propertyName << " , "
+                         << (*itr).timestamp << " , " << (*itr).value << std::endl;
+            if (((*itr).propertyName
+                == ControlWebsocketClientApp::vehiclename_scenario)
+                || (jmsg.getName()
+                == ControlWebsocketClientApp::vehiclename_scenario)) {
+                pthread_cond_signal(&ControlWebsocketClientApp::cond_scenario);
+            }
+        }
+        break;
+    }
+    default:
+    {
+        break;
+    }
+    }
+    return 0;
+}
+
+void *
+ControlWebsocketClientApp::run(void *arg)
+{
+    ControlWebsocketClientApp *control =
+            reinterpret_cast<ControlWebsocketClientApp*>(arg);
+    control->observation();
+    return NULL;
+}
diff --git a/tests/controlwebsocketclientapp.h b/tests/controlwebsocketclientapp.h
new file mode 100644 (file)
index 0000000..6fab240
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#ifndef CONTROLWEBSOCKETCLIENTAPP_H_
+#define CONTROLWEBSOCKETCLIENTAPP_H_
+
+#include <pthread.h>
+#include <sys/time.h>
+
+#include <map>
+#include <vector>
+
+#include <libwebsockets.h>
+
+#include "controlwebsocket.h"
+#include "controlwebsocketclient.h"
+#include "standardjsonmessage.h"
+
+class ControlWebsocketClientApp : public ControlWebsocketClient {
+public:
+    ControlWebsocketClientApp();
+    ~ControlWebsocketClientApp();
+    bool
+    initialize(int port);
+    bool
+    send(std::string type, std::string name, std::string propertyname,
+         std::string value, double timestamp);
+    bool
+    receive(char *keyeventtype, timeval recordtime, void *data, size_t len);
+    void
+    observation();
+    static int
+    callback_receive(libwebsocket_context *context, libwebsocket *wsi,
+                     libwebsocket_callback_reasons reason, void *user, void *in,
+                     size_t len);
+    static void *
+    run(void *arg);
+
+    static pthread_mutex_t mutex_scenario;
+    static pthread_cond_t cond_scenario;
+    static std::string vehiclename_scenario;
+
+private:
+    libwebsocket_context *context;
+    libwebsocket* socket;
+    libwebsocket_protocols protocollist[2];
+    JsonMessage jsonmsg;
+    pthread_t threadid;
+    pthread_mutex_t mutex;
+    char buf[LWS_SEND_BUFFER_PRE_PADDING + JsonMessage::BUFSIZE
+             + LWS_SEND_BUFFER_POST_PADDING];
+};
+#endif // #ifndef CONTROLWEBSOCKETCLIENTAPP_H_
diff --git a/tests/mwscenario.cc b/tests/mwscenario.cc
new file mode 100644 (file)
index 0000000..50662ad
--- /dev/null
@@ -0,0 +1,290 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+#include <sys/time.h>
+
+#include <iostream>
+#include <list>
+
+#include <json-glib/json-glib.h>
+
+#include "debugout.h"
+#include "vehicleproperty.h"
+
+#include "messageformat.h"
+#include "scenarioengine.h"
+
+extern std::list<VehicleProperty::Property> VehicleProperty::mCapabilities;
+extern VehicleProperty vehiclePropertyConstruct;
+const int sleeptime = 25 * 1000;
+
+MWScenarioEngine::MWScenarioEngine()
+{
+}
+
+MWScenarioEngine::~MWScenarioEngine()
+{
+    vehicleinfomap.clear();
+}
+
+void
+MWScenarioEngine::start()
+{
+    char value = 1;
+    char status[STATUSSIZE];
+    int idx = 0;
+    int server = 0;
+    timeval time;
+    DataOpt dopt;
+    EventOpt eopt;
+    int setnotifycall = 0;
+    if ((vehicleinfomap.size() % 2) == 0) {
+        setnotifycall = 1;
+    }
+    int waitcount = 0;
+    auto vehicleinfomapbeginitr = vehicleinfomap.begin();
+    DebugOut(10) << "=========" << "MW Callback" << "=========" << std::endl;
+    usleep(12 * 1000);
+    // Subscribe
+    for (; setnotifycall < vehicleinfomap.size(); setnotifycall += 2) {
+        usleep(sleeptime);
+        vehicleinfomapbeginitr = vehicleinfomap.begin();
+        advance(vehicleinfomapbeginitr, setnotifycall);
+        server = ControlWebsocket::CONTROL_STANDARD;
+        for (int i = 0; i < vehicleinfomapbeginitr->second.size(); i++) {
+            if (vehicleinfomapbeginitr->second[i].isCustom) {
+                server = ControlWebsocket::CONTROL_CUSTOM;
+            }
+        }
+        gettimeofday(&time, NULL);
+        eopt.common = 50;
+        eopt.sense = 0xff;
+        eopt.event_mask = 0;
+        client[server].send(
+                const_cast<char*>(vehicleinfomapbeginitr->first.c_str()), time,
+                &eopt, 64 + sizeof(timeval) + sizeof(EventOpt));
+        DebugOut(10) << "[S]: " << vehicleinfomapbeginitr->first << " , "
+                     << time.tv_sec << "." << time.tv_usec << " , " 
+                     << eopt.common << " , " << eopt.sense << " , " 
+                     << eopt.event_mask << std::endl;
+        ControlWebsocketClient::vehiclename_scenario =
+                vehicleinfomapbeginitr->first;
+        waitcount = vehicleinfomapbeginitr->second.size();
+    }
+    DebugOut(10) << "vehiclename_scenario = "
+                 << ControlWebsocketClient::vehiclename_scenario << std::endl;
+    // Wait Subscribe
+    pthread_mutex_lock(&ControlWebsocketClient::mutex_scenario);
+    pthread_cond_wait(&ControlWebsocketClient::cond_scenario,
+                      &ControlWebsocketClient::mutex_scenario);
+    pthread_mutex_unlock(&ControlWebsocketClient::mutex_scenario);
+    DebugOut(10) << "MW Next." << std::endl;
+    // Get
+    DebugOut(10) << "=========" << "MW Get" << "=========" << std::endl;
+    for (auto itr = vehicleinfomap.begin(); itr != vehicleinfomap.end();
+            itr++) {
+        usleep(sleeptime);
+        memset(status, 0, sizeof(status));
+        idx = 0;
+        server = ControlWebsocket::CONTROL_STANDARD;
+        for (auto itr2 = (*itr).second.begin(); itr2 != (*itr).second.end();
+             itr2++) {
+            memcpy(status + idx, &value, sizeof(value));
+            if ((*itr2).isCustom) {
+                server = ControlWebsocket::CONTROL_CUSTOM;
+            }
+            idx += (*itr2).typesize;
+        }
+        gettimeofday(&time, NULL);
+        eopt.common = -1;
+        eopt.sense = -1;
+        eopt.event_mask = 0;
+        client[server].send(const_cast<char*>(itr->first.c_str()), time, &eopt,
+                            64 + sizeof(timeval) + sizeof(EventOpt));
+        DebugOut(10) << "[S]: " << itr->first << " , " << time.tv_sec << "."
+                     << time.tv_usec << " , " << eopt.common << " , " 
+                     << eopt.sense << " , " << eopt.event_mask << std::endl;
+    }
+    // Wait Get
+    pthread_mutex_lock(&ControlWebsocketClient::mutex_scenario);
+    pthread_cond_wait(&ControlWebsocketClient::cond_scenario,
+                      &ControlWebsocketClient::mutex_scenario);
+    pthread_mutex_unlock(&ControlWebsocketClient::mutex_scenario);
+    DebugOut(10) << "MW Next." << std::endl;
+    // Error
+    DebugOut(10) << "=========" << "MW Error" << "=========" << std::endl;
+    memset(status, 0, sizeof(status));
+    memcpy(status, &value, sizeof(value));
+    for (server = 0; server < 4; server += 2) {
+        usleep(sleeptime);
+        client[server].send(const_cast<char*>("Detarame"), time, &dopt,
+                            64 + sizeof(timeval) + sizeof(int) + sizeof(int));
+        DebugOut(10) << "[S]: " << "Detarame" << " , " << time.tv_sec << "."
+                     << time.tv_usec << std::endl;
+
+        usleep(sleeptime);
+        eopt.common = -1;
+        eopt.sense = -1;
+        client[server + 1].send(const_cast<char*>("Detarame"), time, &eopt,
+                                64 + sizeof(timeval) + sizeof(EventOpt));
+        DebugOut(10) << "[S]: " << "Detarame" << " , " << time.tv_sec << "."
+                     << time.tv_usec << " , " << eopt.common << " , " 
+                     << eopt.sense << " , " << eopt.event_mask << std::endl;
+
+        usleep(sleeptime);
+        eopt.common = 50;
+        eopt.sense = 0xff;
+        client[server + 1].send(const_cast<char*>("Detarame"), time, &eopt,
+                                64 + sizeof(timeval) + sizeof(EventOpt));
+        DebugOut(10) << "[S]: " << "Detarame" << " , " << time.tv_sec << "."
+                     << time.tv_usec << " , " << eopt.common << " , " 
+                     << eopt.sense << " , " << eopt.event_mask << std::endl;
+    }
+    // Set(1st)
+    DebugOut(10) << "=========" << "MW Set" << "=========" << std::endl;
+    for (auto itr = vehicleinfomap.begin(); itr != vehicleinfomap.end();
+         itr++) {
+        usleep(sleeptime);
+        memset(status, 0, sizeof(status));
+        idx = 0;
+        server = ControlWebsocket::DATA_STANDARD;
+        for (auto itr2 = (*itr).second.begin(); itr2 != (*itr).second.end();
+             itr2++) {
+            memcpy(status + idx, &value, sizeof(value));
+            if ((*itr2).isCustom) {
+                server = ControlWebsocket::DATA_CUSTOM;
+            }
+            idx += (*itr2).typesize;
+        }
+        gettimeofday(&time, NULL);
+        dopt.common_status = SUPPORT;
+        memcpy(dopt.status, status, STATUSSIZE);
+        client[server].send(const_cast<char*>(itr->first.c_str()), time, &dopt,
+                            64 + sizeof(timeval) + sizeof(int) + idx);
+        DebugOut(10) << "[S]: " << itr->first << " , " << time.tv_sec << "."
+                     << time.tv_usec << " , ";
+    }
+    value++;
+    // Wait valuechanged
+    for (int i = 0; i < waitcount; i++) {
+        pthread_mutex_lock(&ControlWebsocketClient::mutex_scenario);
+        pthread_cond_wait(&ControlWebsocketClient::cond_scenario,
+                          &ControlWebsocketClient::mutex_scenario);
+        pthread_mutex_unlock(&ControlWebsocketClient::mutex_scenario);
+        DebugOut(10) << "MW Next." << std::endl;
+    }
+    // Set(2nd)
+    DebugOut(10) << "=========" << "MW Set2" << "=========" << std::endl;
+    for (auto itr = vehicleinfomap.begin(); itr != vehicleinfomap.end();
+         itr++) {
+        usleep(sleeptime);
+        memset(status, 0, sizeof(status));
+        idx = 0;
+        server = ControlWebsocket::DATA_STANDARD;
+        for (auto itr2 = (*itr).second.begin(); itr2 != (*itr).second.end();
+             itr2++) {
+            memcpy(status + idx, &value, sizeof(value));
+            if ((*itr2).isCustom) {
+                server = ControlWebsocket::DATA_CUSTOM;
+            }
+            idx += (*itr2).typesize;
+        }
+        gettimeofday(&time, NULL);
+        dopt.common_status = SUPPORT;
+        memcpy(dopt.status, status, STATUSSIZE);
+        client[server].send(const_cast<char*>(itr->first.c_str()), time, &dopt,
+                            64 + sizeof(timeval) + sizeof(int) + idx);
+        DebugOut(10) << "[S]: " << itr->first << " , " << time.tv_sec << "."
+                     << time.tv_usec << " , ";
+    }
+    // Wait valuechanged.
+    for (int i = 0; i < waitcount; i++) {
+        pthread_mutex_lock(&ControlWebsocketClient::mutex_scenario);
+        pthread_cond_wait(&ControlWebsocketClient::cond_scenario,
+                          &ControlWebsocketClient::mutex_scenario);
+        pthread_mutex_unlock(&ControlWebsocketClient::mutex_scenario);
+        DebugOut(10) << "MW Next." << std::endl;
+    }
+    std::cerr << "=========" << "MW End" << "=========" << std::endl;
+}
+
+bool
+MWScenarioEngine::initialize()
+{
+    conf.readConfig(CONFPATH);
+
+    std::vector<VehicleInfoDefine> vehicleinfoList;
+    vehicleinfoList = conf.getVehicleInfoConfig();
+    AbstractPropertyType *type;
+    for (auto itr = vehicleinfoList.begin(); itr != vehicleinfoList.end();
+         itr++) {
+        for (auto itr2 = (*itr).status.begin(); itr2 != (*itr).status.end();
+             itr2++) {
+            MWInfo info;
+            info.type = (*itr2).type;
+            info.typesize = (*itr2).typesize;
+            info.isCustom = true;
+            type = VehicleProperty::getPropertyTypeForPropertyNameValue(
+                    (*itr2).ambPropertyName, "0");
+            DebugOut(10) << "Read config file. " << (*itr2).ambPropertyName
+                         << " is ";
+            if (type != nullptr) {
+                info.isCustom = false;
+                DebugOut(10) << "Standard." << std::endl;
+                delete type;
+            }
+            else {
+                DebugOut(10) << "Custom." << std::endl;
+            }
+            vehicleinfomap[std::string((*itr).KeyEventType)].push_back(info);
+        }
+    }
+    PortInfo portinfo = conf.getPort();
+    if (!client[0].initialize(portinfo.standard.dataPort,
+                              ControlWebsocket::DATA_STANDARD)) {
+        return false;
+    }
+    if (!client[1].initialize(portinfo.standard.controlPort,
+                              ControlWebsocket::CONTROL_STANDARD)) {
+        return false;
+    }
+    if (!client[2].initialize(portinfo.custom.dataPort,
+                              ControlWebsocket::DATA_CUSTOM)) {
+        return false;
+    }
+    if (!client[3].initialize(portinfo.custom.controlPort,
+                              ControlWebsocket::CONTROL_CUSTOM)) {
+        return false;
+    }
+    return true;
+}
+
+int
+main()
+{
+    g_type_init();
+    DebugOut::setDebugThreshhold(5);
+    MWScenarioEngine mwengine;
+    if (!mwengine.initialize()) {
+        std::cerr << "Error dbusengine.initialize." << std::endl;
+        return 0;
+    }
+    mwengine.start();
+    return 0;
+}
diff --git a/tests/scenarioengine.cc b/tests/scenarioengine.cc
new file mode 100644 (file)
index 0000000..ae877c2
--- /dev/null
@@ -0,0 +1,26 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <boost/any.hpp>
+
+#include "scenarioengine.h"
+
+ScenarioEngine::~ScenarioEngine()
+{
+}
+
diff --git a/tests/scenarioengine.h b/tests/scenarioengine.h
new file mode 100644 (file)
index 0000000..f7041be
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <map>
+#include <string>
+#include <vector>
+
+#include "abstractpropertytype.h"
+#include "config.h"
+#include "controlwebsocketclient.h"
+#include "controlwebsocketclientapp.h"
+
+const std::string CONFPATH = "/etc/ambd/AMBformat.conf";
+
+struct MWInfo {
+    VehicleInfoDefine::Status::DataType type;
+    int typesize;
+    bool isCustom;
+};
+
+class ScenarioEngine {
+public:
+    ScenarioEngine() :
+            loadscenario(0)
+    {
+    }
+    ~ScenarioEngine();
+    virtual void
+    start() = 0;
+    virtual bool
+    initialize() = 0;
+protected:
+
+    Config conf;
+    int loadscenario;
+};
+
+class MWScenarioEngine : public ScenarioEngine {
+public:
+    MWScenarioEngine();
+    ~MWScenarioEngine();
+    void
+    start();
+    bool
+    initialize();
+private:
+    bool stopFlg;
+    std::map<std::string, std::vector<MWInfo> > vehicleinfomap;
+    ControlWebsocketClient client[4];
+};
+
+class WebsocketAppScenarioEngine : public ScenarioEngine {
+public:
+    WebsocketAppScenarioEngine();
+    ~WebsocketAppScenarioEngine();
+    void
+    start();
+    bool
+    initialize();
+private:
+    std::map<std::string, std::vector<std::string> > namelist;
+    ControlWebsocketClientApp client;
+};
diff --git a/tests/standardjsonmessage.cc b/tests/standardjsonmessage.cc
new file mode 100644 (file)
index 0000000..bf14739
--- /dev/null
@@ -0,0 +1,231 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <string.h>
+
+#include <iostream>
+
+#include <json-glib/json-glib.h>
+
+#include "nullptr.h"
+
+#include "standardjsonmessage.h"
+
+JsonMessage::JsonMessage()
+{
+}
+
+JsonMessage::~JsonMessage()
+{
+    data.clear();
+}
+
+char *
+JsonMessage::encode(std::string type_, std::string name_,
+                    std::string transactionid_, std::vector<JsonData>& data_)
+{
+    sstr.str("");
+    sstr << "{\"type\":\"" << type_ << "\", \"name\":\"" << name_
+         << "\", \"data\":[";
+    for (auto itr = data_.begin(); itr != data_.end(); itr++) {
+        if (itr != data_.begin()) {
+            sstr << ",";
+        }
+        if (name_ != "set") {
+            sstr << "\"" << (*itr).propertyName << "\"";
+        }
+        else {
+            sstr << "{\"property\":\"" << (*itr).propertyName
+                    << "\", \"value\":\"" << (*itr).value << "\"}";
+        }
+    }
+    sstr << "],\"transactionid\":\"" << transactionid_ << "\"}";
+    memset(encodebuf, 0, sizeof(encodebuf));
+    memcpy(encodebuf, const_cast<char*>(sstr.str().c_str()), sizeof(encodebuf));
+    return &encodebuf[0];
+}
+
+void
+JsonMessage::decode(std::string msg, size_t len)
+{
+    data.clear();
+
+    JsonParser* parser = json_parser_new();
+    GError* error = nullptr;
+    if (!json_parser_load_from_data(parser, msg.c_str(), len, &error)) {
+        std::cerr << "Failed to load config: " << error->message << '\n';
+        return;
+    }
+
+    JsonNode* node = json_parser_get_root(parser);
+
+    if (node == nullptr) {
+        std::cerr << "Unable to get JSON root object\n";
+        return;
+    }
+
+    JsonReader* reader = json_reader_new(node);
+
+    if (reader == nullptr) {
+        std::cerr << "Unable to create JSON reader\n";
+        return;
+    }
+
+    if (json_reader_read_member(reader, "type")) {
+        type = std::string(json_reader_get_string_value(reader));
+        json_reader_end_member(reader);
+    }
+    else {
+        std::cerr << "Error Get type\n";
+        return;
+    }
+
+    if (json_reader_read_member(reader, "name")) {
+        name = std::string(json_reader_get_string_value(reader));
+        json_reader_end_member(reader);
+    }
+    else {
+        std::cerr << "Error Get name\n";
+        return;
+    }
+
+    if (json_reader_read_member(reader, "transactionid")) {
+        transactionid = std::string(json_reader_get_string_value(reader));
+        json_reader_end_member(reader);
+    }
+    else {
+        std::cerr << "Error Get transactionid\n";
+        return;
+    }
+
+    if (json_reader_read_member(reader, "data")) {
+        if (json_reader_is_array(reader)) {
+            JsonData jdata;
+            for (int i = 0; i < json_reader_count_elements(reader); i++) {
+                json_reader_read_element(reader, i);
+                if (json_reader_is_object(reader)) {
+                    if (json_reader_read_member(reader, "property")) {
+                        jdata.propertyName = std::string(
+                                json_reader_get_string_value(reader));
+                        json_reader_end_member(reader);
+                    }
+                    if (json_reader_read_member(reader, "value")) {
+                        jdata.value = std::string(
+                                json_reader_get_string_value(reader));
+                        json_reader_end_member(reader);
+                    }
+                    if (json_reader_read_member(reader, "timestamp")) {
+                        jdata.timestamp = json_reader_get_double_value(reader);
+                        json_reader_end_member(reader);
+                    }
+                    if (json_reader_read_member(reader, "sequence")) {
+                        jdata.sequence = json_reader_get_int_value(reader);
+                        json_reader_end_member(reader);
+                    }
+                    data.push_back(jdata);
+                }
+                else if (json_reader_is_value(reader)) {
+                    jdata.propertyName = std::string(
+                            json_reader_get_string_value(reader));
+                    data.push_back(jdata);
+                }
+                json_reader_end_element(reader);
+            }
+        }
+        else {
+            JsonData jdata;
+            if (json_reader_is_object(reader)) {
+                if (type == "valuechanged") {
+                    jdata.propertyName = name;
+                }
+                else {
+                    if (json_reader_read_member(reader, "property")) {
+                        jdata.propertyName = std::string(
+                                json_reader_get_string_value(reader));
+                        json_reader_end_member(reader);
+                    }
+                }
+                if (json_reader_read_member(reader, "value")) {
+                    jdata.value = std::string(
+                            json_reader_get_string_value(reader));
+                    json_reader_end_member(reader);
+                }
+                else {
+                    std::cerr << "Error Get value\n";
+                    return;
+                }
+                if (json_reader_read_member(reader, "timestamp")) {
+                    jdata.timestamp = json_reader_get_double_value(reader);
+                    json_reader_end_member(reader);
+                }
+                else {
+                    std::cerr << "Error Get timestamp\n";
+                    return;
+                }
+                if (json_reader_read_member(reader, "sequence")) {
+                    jdata.sequence = json_reader_get_int_value(reader);
+                    json_reader_end_member(reader);
+                }
+                else {
+                    std::cerr << "Error Get sequence\n";
+                    return;
+                }
+            }
+            else if (json_reader_is_value(reader)) {
+                jdata.propertyName = std::string(
+                        json_reader_get_string_value(reader));
+            }
+            data.push_back(jdata);
+        }
+    }
+    else {
+        std::cerr << "Error Get data\n";
+        return;
+    }
+    json_reader_end_member(reader);
+
+    if (error)
+        g_error_free(error);
+
+    g_object_unref(reader);
+    g_object_unref(parser);
+}
+
+std::string
+JsonMessage::getType()
+{
+    return type;
+}
+
+std::string
+JsonMessage::getName()
+{
+    return name;
+}
+
+std::string
+JsonMessage::getTransactionid()
+{
+    return transactionid;
+}
+
+std::vector<JsonData>
+JsonMessage::getData()
+{
+    return data;
+}
diff --git a/tests/standardjsonmessage.h b/tests/standardjsonmessage.h
new file mode 100644 (file)
index 0000000..bf6eb8d
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <sstream>
+#include <string>
+#include <vector>
+
+struct JsonData {
+    std::string propertyName;
+    std::string value;
+    double timestamp;
+    int sequence;
+};
+
+class JsonMessage {
+public:
+    JsonMessage();
+    ~JsonMessage();
+    char *
+    encode(std::string type_, std::string name_, std::string transactionid_,
+           std::vector<JsonData>& data_);
+    void
+    decode(std::string msg, size_t len);
+
+    std::string
+    getType();
+    std::string
+    getName();
+    std::string
+    getTransactionid();
+    std::vector<JsonData>
+    getData();
+
+    static const int BUFSIZE = 256;
+protected:
+    std::stringstream sstr;
+
+    std::string type;
+    std::string name;
+    std::string transactionid;
+    std::vector<JsonData> data;
+    char encodebuf[BUFSIZE];
+};
diff --git a/tests/startTestSuite.sh b/tests/startTestSuite.sh
new file mode 100755 (executable)
index 0000000..d00b742
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+echo "==========Prepare Test ico-vic-amb-plugin=========="
+./testVehiclePluginWSApp 2>&1 | tee wslog &
+sleep 10
+echo "==========Start Test ico-vic-amb-plugin=========="
+./testVehiclePluginMW 2>&1 |tee mwlog
diff --git a/tests/websocketscenario.cc b/tests/websocketscenario.cc
new file mode 100644 (file)
index 0000000..1b8d9f1
--- /dev/null
@@ -0,0 +1,184 @@
+/**
+ * Copyright (C) 2012  TOYOTA MOTOR CORPORATION.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+#include <sys/time.h>
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <json-glib/json-glib.h>
+
+#include "debugout.h"
+
+#include "configamb.h"
+#include "scenarioengine.h"
+
+std::string AMBCONFPATH = "/etc/ambd/config";
+const int sleeptime = 100 * 1000;
+
+WebsocketAppScenarioEngine::WebsocketAppScenarioEngine()
+{
+}
+
+WebsocketAppScenarioEngine::~WebsocketAppScenarioEngine()
+{
+    namelist.clear();
+}
+
+void
+WebsocketAppScenarioEngine::start()
+{
+    int value = 0;
+    std::stringstream sstr;
+    sstr.str("");
+    timeval time;
+    double timestamp = 0.0;
+
+    int setnotifycall = namelist.size() - 1;
+    DebugOut(10) << "=========" << "WebsocketApp Subscribe" << "========="
+                 << std::endl;
+    usleep(12 * 1000);
+    for (auto itr = namelist.begin(); itr != namelist.end(); itr++) {
+        for (auto itr2 = (*itr).second.begin(); itr2 != (*itr).second.end();
+             itr2++) {
+            usleep(sleeptime);
+            gettimeofday(&time, NULL);
+            timestamp = time.tv_sec + (time.tv_usec / (1000 * 1000));
+            ControlWebsocketClientApp::vehiclename_scenario = (*itr2);
+            client.send("method", "subscribe", (*itr2), sstr.str(), timestamp);
+            DebugOut(10) << "[S]: " << (*itr).first << "->" << (*itr2)
+                         << " , subscribe , " << timestamp << " , " << sstr.str()
+                         << std::endl;
+        }
+    }
+    for (int i = 0; i < 2; i++) {
+        pthread_mutex_lock(&ControlWebsocketClientApp::mutex_scenario);
+        pthread_cond_wait(&ControlWebsocketClientApp::cond_scenario,
+                          &ControlWebsocketClientApp::mutex_scenario);
+        pthread_mutex_unlock(&ControlWebsocketClientApp::mutex_scenario);
+        DebugOut(10) << "WebsocketApp Next." << std::endl;
+    }
+    DebugOut(10) << "vehiclename_scenario = "
+                 << ControlWebsocketClientApp::vehiclename_scenario << std::endl;
+    DebugOut(10) << "=========" << "WebsocketApp Set" << "========="
+                 << std::endl;
+
+    for (auto itr = namelist.begin(); itr != namelist.end(); itr++) {
+        for (auto itr2 = (*itr).second.begin(); itr2 != (*itr).second.end();
+             itr2++) {
+            usleep(sleeptime);
+            gettimeofday(&time, NULL);
+            timestamp = time.tv_sec + (time.tv_usec / (1000 * 1000));
+            sstr.str("");
+            sstr << value;
+            DebugOut(10) << "Send Data : " << sstr.str() << "," << timestamp
+                         << std::endl;
+            client.send("method", "set", (*itr2), sstr.str(), timestamp);
+            DebugOut(10) << "[S]: " << (*itr2) << " , set , " << timestamp
+                         << " , " << sstr.str() << std::endl;
+        }
+    }
+    pthread_mutex_lock(&ControlWebsocketClientApp::mutex_scenario);
+    pthread_cond_wait(&ControlWebsocketClientApp::cond_scenario,
+                      &ControlWebsocketClientApp::mutex_scenario);
+    pthread_mutex_unlock(&ControlWebsocketClientApp::mutex_scenario);
+    DebugOut(10) << "WebsocketApp Next." << std::endl;
+    pthread_mutex_lock(&ControlWebsocketClientApp::mutex_scenario);
+    pthread_cond_wait(&ControlWebsocketClientApp::cond_scenario,
+                      &ControlWebsocketClientApp::mutex_scenario);
+    pthread_mutex_unlock(&ControlWebsocketClientApp::mutex_scenario);
+    DebugOut(10) << "WebsocketApp Next." << std::endl;
+    DebugOut(10) << "=========" << "WebsocketApp Set & Get" << "========="
+            << std::endl;
+    for (auto itr = namelist.begin(); itr != namelist.end(); itr++) {
+        for (auto itr2 = (*itr).second.begin(); itr2 != (*itr).second.end();
+             itr2++) {
+            usleep(sleeptime);
+            gettimeofday(&time, NULL);
+            timestamp = time.tv_sec + (time.tv_usec / (1000 * 1000));
+            sstr.str("");
+            sstr << value;
+            DebugOut(10) << "Send Data : " << sstr.str() << "," << timestamp
+                         << std::endl;
+            client.send("method", "set", (*itr2), sstr.str(), timestamp);
+            DebugOut(10) << "[S]: " << (*itr2) << " , set , " << timestamp
+                         << " , " << sstr.str() << std::endl;
+            usleep(sleeptime);
+            gettimeofday(&time, NULL);
+            timestamp = time.tv_sec + (time.tv_usec / (1000 * 1000));
+            client.send("method", "get", (*itr2), sstr.str(), timestamp);
+            DebugOut(10) << "[S]: " << (*itr2) << " , get , " << timestamp
+                         << " , " << sstr.str() << std::endl;
+        }
+    }
+    // Wait Get
+    pthread_mutex_lock(&ControlWebsocketClientApp::mutex_scenario);
+    pthread_cond_wait(&ControlWebsocketClientApp::cond_scenario,
+                      &ControlWebsocketClientApp::mutex_scenario);
+    pthread_mutex_unlock(&ControlWebsocketClientApp::mutex_scenario);
+    std::cerr << "=========" << "WebsocketApp End" << "=========" << std::endl;
+}
+
+bool
+WebsocketAppScenarioEngine::initialize()
+{
+    ConfigAMB confamb;
+    if (!confamb.readConfig(AMBCONFPATH)) {
+        std::cerr << "Error configamb.initialize." << std::endl;
+        return false;
+    }
+    if (!conf.readConfig(confamb.getAMBformatPath())) {
+        std::cerr << "Error config.initialize." << std::endl;
+        return false;
+    }
+    if (!client.initialize(confamb.getPort())) {
+        std::cerr << "Error controlwebsocketclientapp.initialize("
+                  << confamb.getPort() << "." << std::endl;
+        return false;
+    }
+
+    std::vector<VehicleInfoDefine> vehicleinfoList;
+    vehicleinfoList = conf.getVehicleInfoConfig();
+    for (auto itr = vehicleinfoList.begin(); itr != vehicleinfoList.end();
+         itr++) {
+        for (auto itr2 = (*itr).status.begin(); itr2 != (*itr).status.end();
+             itr2++) {
+            namelist[std::string((*itr).KeyEventType)].push_back(
+                    (*itr2).ambPropertyName);
+        }
+    }
+    return true;
+}
+
+int
+main()
+{
+    g_type_init();
+    DebugOut::setDebugThreshhold(5);
+    WebsocketAppScenarioEngine wsengine;
+    if (!wsengine.initialize()) {
+        std::cerr << "Error websocketengine.initialize." << std::endl;
+        return 0;
+    }
+    wsengine.start();
+
+    return 0;
+}