From 81bde1d3b160757237c5475443678d85d9edd970 Mon Sep 17 00:00:00 2001 From: Shibata Makoto Date: Fri, 26 Apr 2013 20:48:04 +0900 Subject: [PATCH] Updated package changelog. Change-Id: I0c2fbe210babc5364e174d256528ac169bb72cb5 Signed-off-by: Shibata Makoto --- CMakeLists.txt | 54 ++ LICENSE | 18 + README | 32 ++ packaging/ico-vic-amb-plugin.changes | 3 + packaging/ico-vic-amb-plugin.spec | 42 ++ src/AMBformat.conf | 973 +++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 14 + src/ambinterface.cc | 388 ++++++++++++++ src/ambinterface.h | 212 ++++++++ src/config.cc | 269 ++++++++++ src/config.h | 120 +++++ src/controlwebsocket.cc | 386 ++++++++++++++ src/controlwebsocket.h | 144 ++++++ src/convert.cc | 663 ++++++++++++++++++++++++ src/convert.h | 100 ++++ src/datamessage.cc | 79 +++ src/datamessage.h | 80 +++ src/eventmessage.cc | 79 +++ src/eventmessage.h | 76 +++ src/messageformat.h | 60 +++ src/mwinterface.cc | 433 ++++++++++++++++ src/mwinterface.h | 214 ++++++++ src/standardmessage.cc | 65 +++ src/standardmessage.h | 84 +++ src/viccommunicator.cc | 131 +++++ src/viccommunicator.h | 93 ++++ tests/CMakeLists.txt | 11 + tests/configamb.cc | 175 +++++++ tests/configamb.h | 52 ++ tests/controlwebsocketclient.cc | 191 +++++++ tests/controlwebsocketclient.h | 69 +++ tests/controlwebsocketclientapp.cc | 157 ++++++ tests/controlwebsocketclientapp.h | 68 +++ tests/mwscenario.cc | 290 +++++++++++ tests/scenarioengine.cc | 26 + tests/scenarioengine.h | 78 +++ tests/standardjsonmessage.cc | 231 +++++++++ tests/standardjsonmessage.h | 58 +++ tests/startTestSuite.sh | 7 + tests/websocketscenario.cc | 184 +++++++ 40 files changed, 6409 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 README create mode 100644 packaging/ico-vic-amb-plugin.changes create mode 100644 packaging/ico-vic-amb-plugin.spec create mode 100644 src/AMBformat.conf create mode 100644 src/CMakeLists.txt create mode 100644 src/ambinterface.cc create mode 100644 src/ambinterface.h create mode 100644 src/config.cc create mode 100644 src/config.h create mode 100644 src/controlwebsocket.cc create mode 100644 src/controlwebsocket.h create mode 100644 src/convert.cc create mode 100644 src/convert.h create mode 100644 src/datamessage.cc create mode 100644 src/datamessage.h create mode 100644 src/eventmessage.cc create mode 100644 src/eventmessage.h create mode 100644 src/messageformat.h create mode 100644 src/mwinterface.cc create mode 100644 src/mwinterface.h create mode 100644 src/standardmessage.cc create mode 100644 src/standardmessage.h create mode 100644 src/viccommunicator.cc create mode 100644 src/viccommunicator.h create mode 100644 tests/CMakeLists.txt create mode 100644 tests/configamb.cc create mode 100644 tests/configamb.h create mode 100644 tests/controlwebsocketclient.cc create mode 100644 tests/controlwebsocketclient.h create mode 100644 tests/controlwebsocketclientapp.cc create mode 100644 tests/controlwebsocketclientapp.h create mode 100644 tests/mwscenario.cc create mode 100644 tests/scenarioengine.cc create mode 100644 tests/scenarioengine.h create mode 100644 tests/standardjsonmessage.cc create mode 100644 tests/standardjsonmessage.h create mode 100755 tests/startTestSuite.sh create mode 100644 tests/websocketscenario.cc diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7847620 --- /dev/null +++ b/CMakeLists.txt @@ -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 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 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 index 0000000..cfb1ef3 --- /dev/null +++ b/packaging/ico-vic-amb-plugin.changes @@ -0,0 +1,3 @@ +* Fri Apr 26 2013 Shibata Makoto 2e12f9a +- Import initial. + diff --git a/packaging/ico-vic-amb-plugin.spec b/packaging/ico-vic-amb-plugin.spec new file mode 100644 index 0000000..2b1e6b6 --- /dev/null +++ b/packaging/ico-vic-amb-plugin.spec @@ -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 index 0000000..8bc741f --- /dev/null +++ b/src/AMBformat.conf @@ -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 index 0000000..9e2026f --- /dev/null +++ b/src/CMakeLists.txt @@ -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 index 0000000..9ff7ffa --- /dev/null +++ b/src/ambinterface.cc @@ -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 +#include + +#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 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 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 config) +{ +} + +bool +AMBIF::initialize(VICCommunicator *comm, Config *conf) +{ + DebugOut() << "AMBIF Initialize\n"; + communicator = comm; + mutex = PTHREAD_MUTEX_INITIALIZER; + + vector 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(value); + }; + break; + } + case VehicleInfoDefine::Status::DOUBLE: + { + factory = [value]() { + return new BasicPropertyType(value); + }; + break; + } + case VehicleInfoDefine::Status::CHAR: + { + factory = [value]() { + return new BasicPropertyType(value); + }; + break; + } + case VehicleInfoDefine::Status::INT16: + { + factory = [value]() { + return new BasicPropertyType(value); + }; + break; + } + case VehicleInfoDefine::Status::UINT16: + { + factory = [value]() { + return new BasicPropertyType(value); + }; + break; + } + case VehicleInfoDefine::Status::UINT32: + { + factory = [value]() { + return new BasicPropertyType(value); + }; + break; + } + case VehicleInfoDefine::Status::INT64: + { + factory = [value]() { + return new BasicPropertyType(value); + }; + break; + } + case VehicleInfoDefine::Status::UINT64: + { + factory = [value]() { + return new BasicPropertyType(value); + }; + break; + } + case VehicleInfoDefine::Status::BOOL: + { + factory = [value]() { + return new BasicPropertyType(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 index 0000000..56206f3 --- /dev/null +++ b/src/ambinterface.h @@ -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 + +#include +#include +#include + +#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 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 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 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 index 0000000..95dcd8f --- /dev/null +++ b/src/config.cc @@ -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 + +#include +#include +#include + +#include + +#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 +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(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 index 0000000..3b3c518 --- /dev/null +++ b/src/config.h @@ -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 +#include + +/** + * 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; + std::vector sense; + std::vector 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 + 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 vehicleinfoList; + PortInfo portinfo; +}; +#endif // #ifndef CONFIG_H diff --git a/src/controlwebsocket.cc b/src/controlwebsocket.cc new file mode 100644 index 0000000..556ae0f --- /dev/null +++ b/src/controlwebsocket.cc @@ -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 +#include + +#include "debugout.h" + +#include "controlwebsocket.h" +#include "mwinterface.h" +#include "standardmessage.h" + +/** + * Socket ID generated class. + */ +template + class GenerateCommID { + public: + /** + * This function retrieves an instance of the class. + * + * @return Instance of GenerateCommID + */ + static GenerateCommID * + getInstance() + { + static GenerateCommID 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 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(data))), + len); + DebugOut() << "ControlWebsocket Send Data[" << keyeventtype << "]" + << std::endl; + libwebsocket_write( + wsi, + reinterpret_cast(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 *idserver = + GenerateCommID::getInstance(); + libwebsocket *wsi = idserver->getValue(commid); + if (wsi == NULL) { + return false; + } + libwebsocket_protocols *protocol = + const_cast(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 *idserver = + GenerateCommID::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 *idserver = + GenerateCommID::getInstance(); + int id = idserver->getID(wsi); + DebugOut() << "ControlWebsocket callback_receive Insert ID is " << id + << "\n"; + break; + } + case LWS_CALLBACK_CLOSED: + { + GenerateCommID *idserver = + GenerateCommID::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 *idserver = + GenerateCommID::getInstance(); + int id = idserver->getID(wsi); + StandardMessage msg; + char *buf = reinterpret_cast(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(arg); + control->observation(); + return NULL; +} diff --git a/src/controlwebsocket.h b/src/controlwebsocket.h new file mode 100644 index 0000000..093059b --- /dev/null +++ b/src/controlwebsocket.h @@ -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 +#include + +#include +#include + +#include + +#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 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 index 0000000..1c33d3c --- /dev/null +++ b/src/convert.cc @@ -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 + +#include +#include + +#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 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((*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 " << val << "\n"; + break; + } + case VehicleInfoDefine::Status::DOUBLE: + { + double val; + sstr >> val; + memcpy(buf, &val, size); + DebugOut() << "Converter toBinary " << val << "\n"; + break; + } + case VehicleInfoDefine::Status::CHAR: + { + char val; + sstr >> val; + memcpy(buf, &val, size); + DebugOut() << "Converter toBinary " << val << "\n"; + break; + } + case VehicleInfoDefine::Status::INT16: + { + int16_t val; + sstr >> val; + memcpy(buf, &val, size); + DebugOut() << "Converter toBinary " << val << "\n"; + break; + } + case VehicleInfoDefine::Status::UINT16: + { + uint16_t val; + sstr >> val; + memcpy(buf, &val, size); + DebugOut() << "Converter toBinary " << val << "\n"; + break; + } + case VehicleInfoDefine::Status::UINT32: + { + uint32_t val; + sstr >> val; + memcpy(buf, &val, size); + DebugOut() << "Converter toBinary " << val << "\n"; + break; + } + case VehicleInfoDefine::Status::INT64: + { + int64_t val; + sstr >> val; + memcpy(buf, &val, size); + DebugOut() << "Converter toBinary " << val << "\n"; + break; + } + case VehicleInfoDefine::Status::UINT64: + { + uint64_t val; + sstr >> val; + memcpy(buf, &val, size); + DebugOut() << "Converter toBinary " << 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 " << val << "\n"; + break; + } + default: + { + size = 0; + break; + } + } + return size; +} + +double +Converter::toDouble(timeval time) +{ + return static_cast(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 + (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 + (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 index 0000000..f6bea27 --- /dev/null +++ b/src/convert.h @@ -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 + +#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 ambdataarray; + }; + + std::vector converttablelist; + std::vector specialconvertlist; +}; +#endif // CONVERT_H diff --git a/src/datamessage.cc b/src/datamessage.cc new file mode 100644 index 0000000..2d6446e --- /dev/null +++ b/src/datamessage.cc @@ -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 + +#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(sizeof(timeval))) { + return; + } + memcpy(&recordtime, msg + offset, sizeof(timeval)); + restsize -= sizeof(timeval); + offset += sizeof(timeval); + if (restsize > static_cast(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 index 0000000..482199c --- /dev/null +++ b/src/datamessage.h @@ -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 index 0000000..e13b2ec --- /dev/null +++ b/src/eventmessage.cc @@ -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 + +#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(sizeof(timeval))) { + return; + } + memcpy(&recordtime, msg + offset, sizeof(timeval)); + restsize -= sizeof(timeval); + offset += sizeof(timeval); + if (restsize >= static_cast(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 index 0000000..7f1854b --- /dev/null +++ b/src/eventmessage.h @@ -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 index 0000000..7c613d3 --- /dev/null +++ b/src/messageformat.h @@ -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 index 0000000..03f27fa --- /dev/null +++ b/src/mwinterface.cc @@ -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 + +#include + +#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 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(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(data); + procSetMessage(commid, keyeventtype, recordtime, opt, len); + break; + } + case MessageType::GET: + { + DebugOut() << "MWIF recvMessage(" << commid << ",GET) " << keyeventtype + << "\n"; + EventOpt *opt = reinterpret_cast(data); + procGetMessage(commid, keyeventtype, recordtime, opt, len); + break; + } + case MessageType::CALLBACK: + { + DebugOut() << "MWIF recvMessage(" << commid << ",CALLBACK) " + << keyeventtype << "\n"; + EventOpt *opt = reinterpret_cast(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(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(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(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 index 0000000..ff42886 --- /dev/null +++ b/src/mwinterface.h @@ -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 +#include + +#include +#include +#include + +#include + +#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 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 > 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 vehicleinfoArray; + ControlWebsocket *websocketserver[SERVERNUM]; + VICCommunicator *communicator; + std::map websocketservermap; + std::map mwnotifyinfomap; +}; +#endif // MWINTERFACE_H diff --git a/src/standardmessage.cc b/src/standardmessage.cc new file mode 100644 index 0000000..03b9ee8 --- /dev/null +++ b/src/standardmessage.cc @@ -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 + +#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(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 index 0000000..d84ae0d --- /dev/null +++ b/src/standardmessage.h @@ -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 + +/** + * 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 index 0000000..747a953 --- /dev/null +++ b/src/viccommunicator.cc @@ -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 + +#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(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 index 0000000..985e842 --- /dev/null +++ b/src/viccommunicator.h @@ -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 index 0000000..e5c6a51 --- /dev/null +++ b/tests/CMakeLists.txt @@ -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 index 0000000..e197d87 --- /dev/null +++ b/tests/configamb.cc @@ -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 + +#include +#include +#include + +#ifdef JSONC +#include +#else +#include + +#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 index 0000000..db28cb4 --- /dev/null +++ b/tests/configamb.h @@ -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 +#include + +#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 index 0000000..1aa370d --- /dev/null +++ b/tests/controlwebsocketclient.cc @@ -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 + +#include + +#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(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(data))), + len); + break; + } + default: + { + return false; + break; + } + } + int ret = libwebsocket_write( + socket, + reinterpret_cast(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(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(arg); + control->observation(); + return NULL; +} diff --git a/tests/controlwebsocketclient.h b/tests/controlwebsocketclient.h new file mode 100644 index 0000000..3ce2baa --- /dev/null +++ b/tests/controlwebsocketclient.h @@ -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 +#include + +#include +#include + +#include + +#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 index 0000000..23b13d4 --- /dev/null +++ b/tests/controlwebsocketclientapp.cc @@ -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 + +#include + +#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 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(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(in)), len); + std::vector 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(arg); + control->observation(); + return NULL; +} diff --git a/tests/controlwebsocketclientapp.h b/tests/controlwebsocketclientapp.h new file mode 100644 index 0000000..6fab240 --- /dev/null +++ b/tests/controlwebsocketclientapp.h @@ -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 +#include + +#include +#include + +#include + +#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 index 0000000..50662ad --- /dev/null +++ b/tests/mwscenario.cc @@ -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 +#include + +#include +#include + +#include + +#include "debugout.h" +#include "vehicleproperty.h" + +#include "messageformat.h" +#include "scenarioengine.h" + +extern std::list 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(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(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("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("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("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(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(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 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 index 0000000..ae877c2 --- /dev/null +++ b/tests/scenarioengine.cc @@ -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 + +#include "scenarioengine.h" + +ScenarioEngine::~ScenarioEngine() +{ +} + diff --git a/tests/scenarioengine.h b/tests/scenarioengine.h new file mode 100644 index 0000000..f7041be --- /dev/null +++ b/tests/scenarioengine.h @@ -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 +#include +#include + +#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 > vehicleinfomap; + ControlWebsocketClient client[4]; +}; + +class WebsocketAppScenarioEngine : public ScenarioEngine { +public: + WebsocketAppScenarioEngine(); + ~WebsocketAppScenarioEngine(); + void + start(); + bool + initialize(); +private: + std::map > namelist; + ControlWebsocketClientApp client; +}; diff --git a/tests/standardjsonmessage.cc b/tests/standardjsonmessage.cc new file mode 100644 index 0000000..bf14739 --- /dev/null +++ b/tests/standardjsonmessage.cc @@ -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 + +#include + +#include + +#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& 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(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 +JsonMessage::getData() +{ + return data; +} diff --git a/tests/standardjsonmessage.h b/tests/standardjsonmessage.h new file mode 100644 index 0000000..bf6eb8d --- /dev/null +++ b/tests/standardjsonmessage.h @@ -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 +#include +#include + +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& data_); + void + decode(std::string msg, size_t len); + + std::string + getType(); + std::string + getName(); + std::string + getTransactionid(); + std::vector + getData(); + + static const int BUFSIZE = 256; +protected: + std::stringstream sstr; + + std::string type; + std::string name; + std::string transactionid; + std::vector data; + char encodebuf[BUFSIZE]; +}; diff --git a/tests/startTestSuite.sh b/tests/startTestSuite.sh new file mode 100755 index 0000000..d00b742 --- /dev/null +++ b/tests/startTestSuite.sh @@ -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 index 0000000..1b8d9f1 --- /dev/null +++ b/tests/websocketscenario.cc @@ -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 + +#include +#include +#include +#include +#include + +#include + +#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 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; +} -- 2.7.4