From bd0eaee6dec898575e132aa1185b31587311db53 Mon Sep 17 00:00:00 2001 From: Nakamura Hayato Date: Wed, 17 Jul 2013 19:53:14 +0900 Subject: [PATCH] Support Tizen3.0 Change-Id: I207fb6b9bb7df9fc500350f10f8ce2c6a1d8a48f Signed-off-by: Nakamura Hayato --- CMakeLists.txt | 7 +- packaging/ico-vic-amb-plugin.changes | 7 + packaging/ico-vic-amb-plugin.spec | 23 ++- src/CMakeLists.txt | 6 +- src/abstractconfig.cc | 43 +++++ src/abstractconfig.h | 49 +++++ src/ambconfig.cc | 269 ++++++++++++++++++++++++++ src/ambconfig.h | 113 +++++++++++ src/ambinterface.cc | 57 +++--- src/ambinterface.h | 9 +- src/common.h | 23 +++ src/config.cc | 11 +- src/controlwebsocket.cc | 213 ++++++++++---------- src/controlwebsocket.h | 38 ++-- src/convert.cc | 96 ++++----- src/convert.h | 13 +- src/messageformat.h | 6 +- src/mwinterface.cc | 69 +++---- src/mwinterface.h | 8 +- src/viccommunicator.cc | 4 +- tests/CMakeLists.txt | 8 +- tests/configamb.cc | 153 +++++---------- tests/configamb.h | 7 +- tests/controlwebsocketclient.cc | 115 ++++++----- tests/controlwebsocketclient.h | 23 ++- tests/controlwebsocketclientapp.cc | 85 ++++---- tests/controlwebsocketclientapp.h | 16 +- tests/mwscenario.cc | 24 +-- tests/scenarioengine.h | 6 +- tests/standardjsonmessage.cc | 222 +++++++++------------ tests/standardjsonmessage.h | 18 -- tests/websocketscenario.cc | 10 +- tool/CMakeLists.txt | 6 + tool/ico_set_vehicleinfo.c | 364 +++++++++++++++++++++++++++++++++++ 34 files changed, 1471 insertions(+), 650 deletions(-) create mode 100644 src/abstractconfig.cc create mode 100644 src/abstractconfig.h create mode 100644 src/ambconfig.cc create mode 100644 src/ambconfig.h create mode 100644 src/common.h create mode 100644 tool/CMakeLists.txt create mode 100644 tool/ico_set_vehicleinfo.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 7847620..3a7efd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,13 +34,13 @@ 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(json REQUIRED json) 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(include_dirs ${libtool_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${json_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/lib /usr/include/amb) +set(link_libraries -lamb ${libtool_LIBRARY} ${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}) @@ -52,3 +52,4 @@ install (FILES ${ico-vic-amb-plugin_docs} DESTINATION ${DOC_INSTALL_DIR}) add_subdirectory(src) add_subdirectory(tests) +add_subdirectory(tool) diff --git a/packaging/ico-vic-amb-plugin.changes b/packaging/ico-vic-amb-plugin.changes index 1143e06..0f27c5a 100644 --- a/packaging/ico-vic-amb-plugin.changes +++ b/packaging/ico-vic-amb-plugin.changes @@ -1,3 +1,10 @@ +* Wed Jul 17 2013 Shibata Makoto accepted/2.0alpha-wayland/20130603.172856@298d6ff +- 0.2.1 release. +- Change to ico-uxf-utilities from libwebsocket +- Change to json-c from json-glib +- Add ico-set-vehicleinfo that is instead of CarSim. +- Bug fix : Error when uninstalling. + * Fri May 24 2013 Shibata Makoto accepted/2.0alpha-wayland/20130426.191358@04b4211 - Bug fix for TIVI-992: Collection of spelling error.(WARTER -> WATER) diff --git a/packaging/ico-vic-amb-plugin.spec b/packaging/ico-vic-amb-plugin.spec index 3afa27c..c2a54cc 100644 --- a/packaging/ico-vic-amb-plugin.spec +++ b/packaging/ico-vic-amb-plugin.spec @@ -1,19 +1,23 @@ Name: ico-vic-amb-plugin Summary: Automotive Message Broker is a vehicle network abstraction system. -Version: 0.1.1 -Release: 2 +Version: 0.2.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 +#Requires: json-glib +Requires: libjson +Requires: ico-uxf-utilities BuildRequires: cmake BuildRequires: boost-devel -BuildRequires: json-glib-devel +#BuildRequires: json-glib-devel +BuildRequires: libjson-devel BuildRequires: automotive-message-broker-devel >= 0.6.9 -BuildRequires: libwebsockets-devel +BuildRequires: ico-uxf-utilities-devel +#BuildRequires: libwebsockets-devel >= 1.2 %description Collection of plugins for automotive-message-broker @@ -29,14 +33,17 @@ make %{?jobs:-j%jobs} %install rm -rf %{buildroot} %make_install +mkdir -p %{buildroot}/%{_sysconfdir}/ambd +cp src/AMBformat.conf %{buildroot}/%{_sysconfdir}/ambd/ -%post -p /sbin/ldconfig -%postun -p /sbin/ldconfig mkdir -p %{buildroot}/%{_sysconfdir}/ambd cp src/AMBformat.conf %{buildroot}/%{_sysconfdir}/ambd/ +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + %files %defattr(-,root,root,-) %{_libdir}/automotive-message-broker/*.so %{_sysconfdir}/ambd/AMBformat.conf -%{_docdir}/automotive-message-broker/%{name}/README +/usr/share/doc/automotive-message-broker/%{name}/README diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9e2026f..1cb067f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,11 +2,11 @@ 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) +set(vehicleplugin_headers common.h abstractconfig.h ambconfig.h convert.h standardmessage.h datamessage.h eventmessage.h messageformat.h controlwebsocket.h mwinterface.h viccommunicator.h ambinterface.h) +set(vehicleplugin_sources abstractconfig.cc ambconfig.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}) +target_link_libraries(vehicleplugin amb websockets -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} -lico-util-com) install(TARGETS vehicleplugin LIBRARY DESTINATION lib/automotive-message-broker) diff --git a/src/abstractconfig.cc b/src/abstractconfig.cc new file mode 100644 index 0000000..39a16af --- /dev/null +++ b/src/abstractconfig.cc @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013 TOYOTA MOTOR CORPORATION. + * + * Contact: shibata@mac.tec.toyota.co.jp + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include "abstractconfig.h" + +AbstractConfig::AbstractConfig() +{ +} + +AbstractConfig::~AbstractConfig() +{ +} + +bool +AbstractConfig::readConfig(std::string confpath) +{ + std::ifstream in(confpath.c_str(), std::ios::in); + std::string output; + std::string line; + while (in.good()) { + getline(in, line); + output.append(line); + } + return parseJson(output); +} diff --git a/src/abstractconfig.h b/src/abstractconfig.h new file mode 100644 index 0000000..1eef80f --- /dev/null +++ b/src/abstractconfig.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 TOYOTA MOTOR CORPORATION. + * + * Contact: shibata@mac.tec.toyota.co.jp + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ABSTRACTCONFIG_H_ +#define ABSTRACTCONFIG_H_ +#include + +class AbstractConfig { +public: + /** + * Constructor. + */ + AbstractConfig(); + + /** + * Destructor. + */ + virtual + ~AbstractConfig(); + + /** + * Read configuration file. + * + * @param confpath Path to the configuration file. + */ + bool + readConfig(std::string confpath); +protected: + virtual bool + parseJson(std::string config) = 0; + + bool readflag; +}; +#endif // ABSTRACTCONFIG_H_ + diff --git a/src/ambconfig.cc b/src/ambconfig.cc new file mode 100644 index 0000000..d2a4376 --- /dev/null +++ b/src/ambconfig.cc @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2013 TOYOTA MOTOR CORPORATION. + * + * Contact: shibata@mac.tec.toyota.co.jp + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include +#include +#include + +#include + +#include "ambconfig.h" +#include "debugout.h" + +AMBConfig::AMBConfig() +{ +} + +AMBConfig::~AMBConfig() +{ +} + +std::vector +AMBConfig::getVehicleInfoConfig() +{ + return vehicleinfoList; +} + +PortInfo +AMBConfig::getPort() +{ + return portinfo; +} + +bool +AMBConfig::parseJson(std::string config) +{ + bool ret = false; + json_object *rootobject; + json_tokener *tokener = json_tokener_new(); + if (tokener == NULL) { + return ret; + } + enum json_tokener_error err; + do { + rootobject = json_tokener_parse_ex(tokener, config.c_str(), + config.length()); + } while ((err = json_tokener_get_error(tokener)) == json_tokener_continue); + json_tokener_free(tokener); + + if (err != json_tokener_success) { + std::cerr << "Error: " << json_tokener_error_desc(err) << "\n"; + return ret; + } + json_object *configobject = json_object_object_get(rootobject, "Config"); + if (!configobject) { + DebugOut() << "Error getting Config\n"; + return ret; + } + array_list *configlist = json_object_get_array(configobject); + if (configlist == NULL) { + DebugOut() << "Config is not Array.\n"; + return ret; + } + for (int i = 0; i < array_list_length(configlist); i++) { + json_object *obj = reinterpret_cast(array_list_get_idx( + configlist, i)); + if (obj == NULL) { + break; + } + json_object *sectionobj = json_object_object_get(obj, "Section"); + if (sectionobj == NULL) { + break; + } + if ("Common" != std::string(json_object_get_string(sectionobj))) { + continue; + } + json_object *defineobj = json_object_object_get(obj, + "VehicleInfoDefine"); + if (defineobj == NULL) { + break; + } + array_list *definelist = json_object_get_array(defineobj); + if (definelist == NULL) { + break; + } + for (int j = 0; j < array_list_length(definelist); j++) { + DebugOut() << "VehicleInfoDefine : " << j << "/" + << array_list_length(definelist) << "\n"; + json_object *obj_vi = + reinterpret_cast(array_list_get_idx( + definelist, j)); + if (obj_vi == NULL) { + break; + } + VehicleInfoDefine vid; + json_object *keyeventtypeobj = json_object_object_get( + obj_vi, "KeyEventType"); + if (keyeventtypeobj == NULL) { + continue; + } + strcpy(vid.KeyEventType, json_object_get_string(keyeventtypeobj)); + json_object *statusobj = json_object_object_get(obj_vi, "Status"); + if (statusobj == NULL) { + continue; + } + array_list *statuslist = json_object_get_array(statusobj); + if (statuslist == NULL) { + continue; + } + for (int k = 0; k < array_list_length(statuslist); k++) { + json_object *obj_sts = + reinterpret_cast(array_list_get_idx( + statuslist, k)); + if (obj_sts == NULL) { + break; + } + VehicleInfoDefine::Status status; + json_object *statuschildobj = json_object_object_get( + obj_sts, "AMBPropertyName"); + if (statuschildobj == NULL) { + continue; + } + status.ambPropertyName = string( + json_object_get_string(statuschildobj)); + statuschildobj = json_object_object_get(obj_sts, "Type"); + if (statuschildobj == NULL) { + continue; + } + status.type = + getType(const_cast(json_object_get_string( + statuschildobj)), + &status.typesize); + if (status.type == NONE) { + continue; + } + statuschildobj = json_object_object_get(obj_sts, + "AccessControl"); + if (statuschildobj != NULL) { + status.accessControl = string( + json_object_get_string(statuschildobj)); + } + statuschildobj = json_object_object_get(obj_sts, "Default"); + if (statuschildobj == NULL) { + continue; + } + status.defaultvalue = string( + json_object_to_json_string(statuschildobj)); + statuschildobj = json_object_object_get(obj_sts, + "DBusProperty"); + if (statuschildobj != NULL) { + status.dbusPropertyName = string( + json_object_get_string(statuschildobj)); + } + vid.status.push_back(status); + } + /* ToDo */ + /* Sense, EventMask */ + json_object *priorityobj = json_object_object_get(obj_vi, + "Priority"); + if (priorityobj != NULL) { + vid.priority = json_object_get_int(priorityobj); + } + json_object *dbusifobj = json_object_object_get(obj_vi, + "DBusInterface"); + if (dbusifobj != NULL) { + vid.dbusInterface = string(json_object_get_string(dbusifobj)); + } + json_object *dbusobjobj = json_object_object_get(obj_vi, + "DBusObject"); + if (dbusobjobj != NULL) { + vid.dbusObject = string(json_object_get_string(dbusobjobj)); + } + vehicleinfoList.push_back(vid); + } + json_object *defaultportobj = json_object_object_get(obj, + "DefaultInfoPort"); + if (defaultportobj == NULL) { + break; + } + json_object *portobj = json_object_object_get(defaultportobj, + "DataPort"); + if (portobj == NULL) { + break; + } + portinfo.standard.dataPort = json_object_get_int(portobj); + portobj = json_object_object_get(defaultportobj, "CtrlPort"); + if (portobj == NULL) { + break; + } + portinfo.standard.controlPort = json_object_get_int(portobj); + json_object *customportobj = json_object_object_get( + obj, "CustomizeInfoPort"); + if (customportobj == NULL) { + break; + } + portobj = json_object_object_get(customportobj, "DataPort"); + if (portobj == NULL) { + break; + } + portinfo.custom.dataPort = json_object_get_int(portobj); + portobj = json_object_object_get(customportobj, "CtrlPort"); + if (portobj == NULL) { + break; + } + portinfo.custom.controlPort = json_object_get_int(portobj); + ret = true; + break; + } + + return ret; +} + +DataType +AMBConfig::getType(char *type, int *size) +{ + if (strcmp(type, "int") == 0) { + *size = sizeof(int); + return INT; + } + else if (strcmp(type, "double") == 0) { + *size = sizeof(double); + return DOUBLE; + } + else if (strcmp(type, "char") == 0) { + *size = sizeof(char); + return CHAR; + } + else if (strcmp(type, "int16_t") == 0 || strcmp(type, "int16") == 0) { + *size = sizeof(int16_t); + return INT16; + } + else if (strcmp(type, "uint16_t") == 0 || strcmp(type, "uint16") == 0) { + *size = sizeof(uint16_t); + return UINT16; + } + else if (strcmp(type, "uint32_t") == 0 || strcmp(type, "uint32") == 0) { + *size = sizeof(uint32_t); + return UINT32; + } + else if (strcmp(type, "int64_t") == 0 || strcmp(type, "int64") == 0) { + *size = sizeof(int64_t); + return INT64; + } + else if (strcmp(type, "uint64_t") == 0 || strcmp(type, "uint64") == 0) { + *size = sizeof(uint64_t); + return UINT64; + } + else if (strcmp(type, "bool") == 0 || strcmp(type, "boolean") == 0) { + *size = sizeof(bool); + return BOOL; + } + *size = 0; + return NONE; +} diff --git a/src/ambconfig.h b/src/ambconfig.h new file mode 100644 index 0000000..5554d96 --- /dev/null +++ b/src/ambconfig.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013 TOYOTA MOTOR CORPORATION. + * + * Contact: shibata@mac.tec.toyota.co.jp + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef AMBCONFIG_H_ +#define AMBCONFIG_H_ +#include + +#include + +#include "abstractconfig.h" +#include "common.h" + +/** + * Table of vehicle information that is described in the configuration file. + * 04-18 Add String + */ +struct VehicleInfoDefine { + struct Status { + std::string ambPropertyName; + DataType 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; +}; + +/** + * Reading VehiclePlugin's config file. + */ +class AMBConfig : public AbstractConfig { +public: + /** + * Constructor. + */ + AMBConfig(); + + /** + * Destructor. + */ + ~AMBConfig(); + + /** + * 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(); +private: + bool + parseJson(std::string config); + + DataType + getType(char *type, int *size); + + std::vector vehicleinfoList; + PortInfo portinfo; +}; +#endif // AMBCONFIG_H_ diff --git a/src/ambinterface.cc b/src/ambinterface.cc index 9ff7ffa..837b449 100644 --- a/src/ambinterface.cc +++ b/src/ambinterface.cc @@ -23,7 +23,7 @@ #include "debugout.h" #include "ambinterface.h" -#include "config.h" +#include "ambconfig.h" #include "convert.h" #include "mwinterface.h" #include "viccommunicator.h" @@ -32,7 +32,7 @@ extern "C" AbstractSource * create(AbstractRoutingEngine* routingengine, map config) { AMBIF *ambif = new AMBIF(routingengine, config); - Config *conf = new Config(); + AMBConfig *conf = new AMBConfig(); conf->readConfig(config["configfile"]); VICCommunicator *communicator = new VICCommunicator(); MWIF *mwif = new MWIF(); @@ -90,7 +90,7 @@ AMBIF::getPropertyAsync(AsyncPropertyReply *reply) { reply->success = false; DebugOut() << "AMBIF " << "Get Request property : " << reply->property - << std::endl; + << std::endl; lock(); AMBVehicleInfo *vehicleinfo = find(reply->property); DebugOut() << "AMBIF " << "Find Data : " << reply->property << std::endl; @@ -166,7 +166,7 @@ AMBIF::setConfiguratin(std::map config) } bool -AMBIF::initialize(VICCommunicator *comm, Config *conf) +AMBIF::initialize(VICCommunicator *comm, AMBConfig *conf) { DebugOut() << "AMBIF Initialize\n"; communicator = comm; @@ -185,7 +185,7 @@ AMBIF::initialize(VICCommunicator *comm, Config *conf) if (vi.value == nullptr) { if (!registVehicleInfo(vi.name, (*itr2).type, (*itr2).defaultvalue)) { - DebugOut() << "AMBIF Initialize Couldn't regist property[" + DebugOut() << "AMBIF Initialize Couldn't regist property[" << vi.name << "]\n"; continue; } @@ -195,8 +195,8 @@ AMBIF::initialize(VICCommunicator *comm, Config *conf) } vehicleinfoArray.push_back(vi); propertylist.push_back(vi.name); - DebugOut() << "AMBIF Initialize regist propertyname = " - << vi.name << "\n"; + DebugOut() << "AMBIF Initialize regist propertyname = " << vi.name + << "\n"; } } routingEngine->setSupported(supported(), this); @@ -243,14 +243,15 @@ 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; - } - }; + 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; @@ -297,70 +298,68 @@ AMBIF::requestUpdate(AMBVehicleInfo *vehicleinfo) } bool -AMBIF::registVehicleInfo(std::string propertyName, - VehicleInfoDefine::Status::DataType type, string value) +AMBIF::registVehicleInfo(std::string propertyName, DataType type, string value) { - DebugOut() << "AMBIF registVehicleInfo(" << propertyName - << ")\n"; + DebugOut() << "AMBIF registVehicleInfo(" << propertyName << ")\n"; VehicleProperty::PropertyTypeFactoryCallback factory; switch (type) { - case VehicleInfoDefine::Status::INT: + case INT: { factory = [value]() { return new BasicPropertyType(value); }; break; } - case VehicleInfoDefine::Status::DOUBLE: + case DOUBLE: { factory = [value]() { return new BasicPropertyType(value); }; break; } - case VehicleInfoDefine::Status::CHAR: + case CHAR: { factory = [value]() { return new BasicPropertyType(value); }; break; } - case VehicleInfoDefine::Status::INT16: + case INT16: { factory = [value]() { return new BasicPropertyType(value); }; break; } - case VehicleInfoDefine::Status::UINT16: + case UINT16: { factory = [value]() { return new BasicPropertyType(value); }; break; } - case VehicleInfoDefine::Status::UINT32: + case UINT32: { factory = [value]() { return new BasicPropertyType(value); }; break; } - case VehicleInfoDefine::Status::INT64: + case INT64: { factory = [value]() { return new BasicPropertyType(value); }; break; } - case VehicleInfoDefine::Status::UINT64: + case UINT64: { factory = [value]() { return new BasicPropertyType(value); }; break; } - case VehicleInfoDefine::Status::BOOL: + case BOOL: { factory = [value]() { return new BasicPropertyType(value); @@ -379,7 +378,7 @@ AMBVehicleInfo * AMBIF::find(std::string propertyName) { for (auto itr = vehicleinfoArray.begin(); itr != vehicleinfoArray.end(); - itr++) { + itr++) { if ((*itr).name == propertyName) { return &(*itr); } diff --git a/src/ambinterface.h b/src/ambinterface.h index 56206f3..883a055 100644 --- a/src/ambinterface.h +++ b/src/ambinterface.h @@ -26,7 +26,7 @@ #include #include "abstractsource.h" -#include "config.h" +#include "ambconfig.h" /** * Vehicle information of AMB. @@ -37,7 +37,7 @@ struct AMBVehicleInfo { bool isCustom; }; -class Config; +class AMBConfig; class VICCommunicator; /** @@ -124,7 +124,7 @@ public: * @return Success : true Failure : false */ bool - initialize(VICCommunicator *comm, Config *conf); + initialize(VICCommunicator *comm, AMBConfig *conf); /** * AMBIF class is required to get the vehicle information to AMB-Core. * @@ -198,8 +198,7 @@ public: } private: bool - registVehicleInfo(std::string propertyName, - VehicleInfoDefine::Status::DataType type, + registVehicleInfo(std::string propertyName, DataType type, std::string value); AMBVehicleInfo * find(std::string propertyName); diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..30ff959 --- /dev/null +++ b/src/common.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2013 TOYOTA MOTOR CORPORATION. + * + * Contact: shibata@mac.tec.toyota.co.jp + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef COMMON_H_ +#define COMMON_H_ +enum DataType { + INT, DOUBLE, CHAR, INT16, UINT16, UINT32, INT64, UINT64, BOOL, NONE +}; +#endif // COMMON_H_ diff --git a/src/config.cc b/src/config.cc index 95dcd8f..109b28d 100644 --- a/src/config.cc +++ b/src/config.cc @@ -77,7 +77,8 @@ Config::parseJson(string config) 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; + DebugOut() << "Failed to load config[" << error->message << "]." + << endl; return ret; } @@ -98,10 +99,10 @@ Config::parseJson(string config) 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; + 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)); diff --git a/src/controlwebsocket.cc b/src/controlwebsocket.cc index 556ae0f..c63fbc4 100644 --- a/src/controlwebsocket.cc +++ b/src/controlwebsocket.cc @@ -19,6 +19,9 @@ #include #include +#include +#include + #include "debugout.h" #include "controlwebsocket.h" @@ -51,16 +54,19 @@ template * @return ID */ int - getID(T value) + getID(T value, int key) { pthread_mutex_lock(&mutex); for (auto itr = commidmap.begin(); itr != commidmap.end(); itr++) { - if ((*itr).second == value) { + if ((void*)(*itr).second == (void*)value) { pthread_mutex_unlock(&mutex); return (*itr).first; } } - int newid = generateID(); + int newid = key; + if (newid == -1) { + newid = generateID(); + } commidmap.insert(make_pair(newid, value)); pthread_mutex_unlock(&mutex); return newid; @@ -103,7 +109,8 @@ template return ret; } private: - GenerateCommID() : mutex(PTHREAD_MUTEX_INITIALIZER) + GenerateCommID() : + mutex(PTHREAD_MUTEX_INITIALIZER) { } @@ -128,72 +135,84 @@ template return 1; } int count = 1; - for (auto itr = commidmap.begin(); itr != commidmap.end(); itr++) { - if (itr->first != count) { - return count; - } + while (commidmap.find(count) == commidmap.end()) { count++; } - return count + 1; + return count; } 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(); + pollfds.clear(); } bool -ControlWebsocket::initialize(int port, enum ServerProtocol stype) +ControlWebsocket::initialize(int port, enum ServerProtocol stype, MWIF *mwif_) { + type = stype; DebugOut() << "ControlWebsocket[" << type << "]" << " initialize.(" << port << ")\n"; - type = stype; + stringstream address, protocol; + address.str(""); + protocol.str(""); + address << ":" << port; switch (type) { case DATA_STANDARD: { - protocollist[0] = {"standarddatamessage-only", ControlWebsocket::callback_receive, 0}; + protocol << "standarddatamessage-only"; break; } - case CONTROL_STANDARD : { - protocollist[0] = {"standardcontrolmessage-only", ControlWebsocket::callback_receive, 0}; + case CONTROL_STANDARD: + { + protocol << "standardcontrolmessage-only"; break; } - case DATA_CUSTOM : { - protocollist[0] = {"customdatamessage-only", ControlWebsocket::callback_receive, 0}; + case DATA_CUSTOM: + { + protocol << "customdatamessage-only"; break; } - case CONTROL_CUSTOM : { - protocollist[0] = {"customcontrolmessage-only", ControlWebsocket::callback_receive, 0}; + case CONTROL_CUSTOM: + { + protocol << "customcontrolmessage-only"; break; } - default : { + default: + { return false; } -} - context = libwebsocket_create_context(port, "lo", protocollist, - libwebsocket_internal_extensions, - NULL, NULL, -1, -1, 0); + } + + context = ico_uws_create_context(address.str().c_str(), + protocol.str().c_str()); if (context == NULL) { - DebugOut() << "ControlWebsocket[" << type << "]" + DebugOut() << "ControlWebsocket[" << type << "]" << " couldn't create libwebsockets_context." << std::endl; return false; } + mwif = mwif_; + container.mwif = mwif; + container.type = type; + if (ico_uws_set_event_cb(context, ControlWebsocket::callback_receive, + (void*)&container) != 0) { + DebugOut() << "ControlWebsocket[" << type << "]" + << " couldn't set callback function." << std::endl; + return false; + } if (pthread_create(&threadid, NULL, ControlWebsocket::run, (void*)this) - == -1) { - libwebsocket_context_destroy(context); - DebugOut() << "ControlWebsocket[" << type << "]" + == -1) { + ico_uws_close(context); + DebugOut() << "ControlWebsocket[" << type << "]" << " couldn't create thread." << std::endl; return false; } @@ -206,12 +225,11 @@ ControlWebsocket::send(int commid, char *keyeventtype, timeval time, void *data, { DebugOut() << "ControlWebsocket[" << type << "]" << " send data(" << commid << "," << keyeventtype << ") len = " << len << std::endl; - libwebsocket *wsi = NULL; + void *wsi = NULL; if (socketmap.find(commid) == socketmap.end()) { if (!registSocket(commid)) { - DebugOut() << "ControlWebsocket[" << type << "]" - << " can't regist socket(" << commid << ")" - << std::endl; + DebugOut() << "ControlWebsocket[" << type << "]" + << " can't regist socket(" << commid << ")" << std::endl; return false; } } @@ -224,16 +242,13 @@ ControlWebsocket::send(int commid, char *keyeventtype, timeval time, void *data, } pthread_mutex_lock(&mutex); memset(buf, 0, sizeof(buf)); - memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING, + memcpy(buf, datamsg.encode(keyeventtype, time, *(reinterpret_cast(data))), - len); + len); DebugOut() << "ControlWebsocket Send Data[" << keyeventtype << "]" << std::endl; - libwebsocket_write( - wsi, - reinterpret_cast(buf + LWS_SEND_BUFFER_PRE_PADDING), - len, LWS_WRITE_BINARY); + ico_uws_send(context, wsi, reinterpret_cast(buf), len); pthread_mutex_unlock(&mutex); return true; } @@ -280,35 +295,30 @@ ControlWebsocket::receive(int commid, char *keyeventtype, timeval recordtime, void ControlWebsocket::observation() { - int ret = 0; - while (ret >= 0) { - ret = libwebsocket_service(context, 100); - if (ret != 0) { - break; + int ret; + while (true) { + ret = poll(&pollfds[0], pollfds.size(), -1); + if (ret < 0) { + DebugOut() << "Error: poll(" << strerror(errno) << ")\n"; + continue; } + ico_uws_service(context); } } bool ControlWebsocket::registSocket(int commid) { - if (socketmap.find(commid) != socketmap.end()) { + DebugOut() << "socketmap[" << type << "]!!\n" << std::flush; + GenerateCommID *idserver = GenerateCommID::getInstance(); + if (idserver->getValue(commid) != NULL) { + socketmap[commid] = idserver->getValue(commid); + pollfd fds; + fds.fd = commid; + fds.events = POLLIN | POLLERR; + pollfds.push_back(fds); 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; } @@ -319,62 +329,67 @@ ControlWebsocket::unregistSocket(int commid) return false; } socketmap.erase(commid); - GenerateCommID *idserver = - GenerateCommID::getInstance(); + for (auto itr = pollfds.begin(); itr != pollfds.end(); itr++) { + if ((*itr).fd == commid) { + itr = pollfds.erase(itr); + break; + } + } + 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) +void +ControlWebsocket::callback_receive(const struct ico_uws_context *context, + const ico_uws_evt_e event, const void *id, + const ico_uws_detail *detail, + void *user_data) { - 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"; + user_datacontainer *container = static_cast(user_data); + switch (event) { + case ICO_UWS_EVT_OPEN: 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); + case ICO_UWS_EVT_ERROR: break; - } - case LWS_CALLBACK_RECEIVE: + case ICO_UWS_EVT_CLOSE: + break; + case ICO_UWS_EVT_RECEIVE: { - GenerateCommID *idserver = - GenerateCommID::getInstance(); - int id = idserver->getID(wsi); + GenerateCommID *idserver = GenerateCommID::getInstance(); + int commid = idserver->getID(const_cast(id), -1); StandardMessage msg; - char *buf = reinterpret_cast(in); - msg.decode(buf, len); - DebugOut() << "ControlWebsocket callback_receive Receive message : " + char *buf = reinterpret_cast(detail->_ico_uws_message.recv_data); + msg.decode(buf, detail->_ico_uws_message.recv_len); + DebugOut() << "ControlWebsocket callback_receive Receive message[" + << detail->_ico_uws_message.recv_len << "] : " << msg.getKeyEventType() << "," << msg.getRecordtime().tv_sec << "\n"; - ControlWebsocket::mwif->recvRawdata( - id, msg.getKeyEventType(), msg.getRecordtime(), + container->mwif->recvRawdata( + commid, msg.getKeyEventType(), msg.getRecordtime(), (buf + StandardMessage::KEYEVENTTYPESIZE + sizeof(timeval)), - len); + detail->_ico_uws_message.recv_len); break; } - default: + case ICO_UWS_EVT_ADD_FD: { + GenerateCommID *idserver = GenerateCommID::getInstance(); + int commid = idserver->getID(const_cast(id), + detail->_ico_uws_fd.fd); + DebugOut() << "ControlWebsocket callback_receive Insert ID is " + << commid << "\n"; + container->mwif->registDestination(container->type, + detail->_ico_uws_fd.fd); break; } + case ICO_UWS_EVT_DEL_FD: + { + container->mwif->unregistDestination(container->type, + detail->_ico_uws_fd.fd); + break; + } + default: + break; } - return 0; } void * diff --git a/src/controlwebsocket.h b/src/controlwebsocket.h index 093059b..9eeaf93 100644 --- a/src/controlwebsocket.h +++ b/src/controlwebsocket.h @@ -19,18 +19,20 @@ #ifndef CONTROLWEBSOCKET_H_ #define CONTROLWEBSOCKET_H_ +#include #include #include #include #include -#include +#include "ico-util/ico_uws.h" #include "eventmessage.h" #include "datamessage.h" class MWIF; +struct user_datacontainer; /** * Class that manages the Websocket. @@ -41,7 +43,12 @@ public: * The protocol used to Websocket communicate. */ enum ServerProtocol { - DATA_STANDARD, CONTROL_STANDARD, DATA_CUSTOM, CONTROL_CUSTOM + DATA_STANDARD = 0, CONTROL_STANDARD, DATA_CUSTOM, CONTROL_CUSTOM + }; + + struct user_datacontainer { + enum ControlWebsocket::ServerProtocol type; + MWIF *mwif; }; /** * Constructor. @@ -59,7 +66,7 @@ public: * @return Success : true Failure : false */ bool - initialize(int port, enum ServerProtocol stype); + initialize(int port, enum ServerProtocol stype, MWIF *mwif_); /** * This function sends a message to the MW. * @@ -115,10 +122,10 @@ public: * @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); + static void + callback_receive(const struct ico_uws_context *context, + const ico_uws_evt_e event, const void *id, + const ico_uws_detail *detail, void *user_data); /** * Function for multi-threaded execution. */ @@ -128,17 +135,20 @@ public: /** * Instance of MWIF. */ - static MWIF *mwif; -private: - libwebsocket_context *context; - libwebsocket_protocols protocollist[2]; +protected: enum ServerProtocol type; - std::map socketmap; +private: + ico_uws_context *context; + 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]; + char buf[StandardMessage::BUFSIZE]; + char iface[128]; + std::vector pollfds; + MWIF *mwif; + user_datacontainer container; }; + #endif // #ifndef CONTROLWEBSOCKET_H_ diff --git a/src/convert.cc b/src/convert.cc index 1c33d3c..5d38573 100644 --- a/src/convert.cc +++ b/src/convert.cc @@ -42,7 +42,7 @@ Converter::~Converter() } bool -Converter::initialize(Config *conf) +Converter::initialize(AMBConfig *conf) { vector dtableArray; dtableArray = conf->getVehicleInfoConfig(); @@ -78,11 +78,14 @@ Converter::convertMWtoAMB(MWVehicleInfo *mwvehicleinfo, int arrayidx = 0; int statusidx = 0; for (auto itr2 = (*itr).ambdataarray.begin(); - itr2 != (*itr).ambdataarray.end(); itr2++) { + itr2 != (*itr).ambdataarray.end(); itr2++) { ambvehicleinfo[arrayidx].name = (*itr2).ambname; ambvehicleinfo[arrayidx].value = VehicleProperty::getPropertyTypeForPropertyNameValue( ambvehicleinfo[arrayidx].name, "0"); + if (ambvehicleinfo[arrayidx].value == NULL) { + continue; + } ambvehicleinfo[arrayidx].value->timestamp = toDouble( mwvehicleinfo->recordtime); char statusbuf[(*itr2).typesize]; @@ -93,13 +96,12 @@ Converter::convertMWtoAMB(MWVehicleInfo *mwvehicleinfo, (*itr2).type)); statusidx += sizeof(statusbuf); DebugOut() << "Converter convertMWtoAMB ambname = " - << (*itr2).ambname << "(" - << ambvehicleinfo[arrayidx].value->toString() - << ")\n"; + << (*itr2).ambname << "(" + << ambvehicleinfo[arrayidx].value->toString() << ")\n"; arrayidx++; if (arrayidx == arraysize && arraysize - < static_cast((*itr).ambdataarray.size())) { + < static_cast((*itr).ambdataarray.size())) { ret = -1; break; } @@ -118,14 +120,14 @@ Converter::convertAMBtoMW(AMBVehicleInfo *ambvehicleinfo, int ret = 0; int statusidx = 0; for (auto itr = converttablelist.begin(); itr != converttablelist.end(); - itr++) { + itr++) { statusidx = 0; DebugOut(10) << "Converter convertAMBtoMW mwname = " << (*itr).mwname - << "\n"; + << "\n"; for (auto itr2 = (*itr).ambdataarray.begin(); itr2 != (*itr).ambdataarray.end(); itr2++) { DebugOut(10) << "Converter convertAMBtoMW ambname = " - << (*itr2).ambname << "\n"; + << (*itr2).ambname << "\n"; if ((*itr2).ambname == ambvehicleinfo->name) { DebugOut() << "Converter convertAMBtoMW ambname = " << (*itr2).ambname << "\n"; @@ -133,14 +135,13 @@ Converter::convertAMBtoMW(AMBVehicleInfo *ambvehicleinfo, mwvehicleinfo->recordtime = toTimeval( ambvehicleinfo->value->timestamp); if (ambvehicleinfo->value == NULL) { - DebugOut() << "Converter convertAMBtoMW " + DebugOut() << "Converter convertAMBtoMW " << "ambvehicleinfo->value is NULL\n"; ret = -1; } else { DebugOut() << "Converter check data " - << ambvehicleinfo->value->toString() - << std::endl; + << ambvehicleinfo->value->toString() << std::endl; toBinary(ambvehicleinfo->name, ambvehicleinfo->value, (*itr2).typesize, (*itr2).type, mwvehicleinfo->status + statusidx); @@ -155,74 +156,73 @@ Converter::convertAMBtoMW(AMBVehicleInfo *ambvehicleinfo, } string -Converter::toString(string ambname, char *data, int size, - VehicleInfoDefine::Status::DataType type) +Converter::toString(string ambname, char *data, int size, DataType type) { if (find(specialconvertlist.begin(), specialconvertlist.end(), ambname) - != specialconvertlist.end()) { + != specialconvertlist.end()) { return specialConvertMWtoAMB(ambname, data, size, type); } stringstream sstr; sstr.str(""); sstr.precision(10); switch (type) { - case VehicleInfoDefine::Status::INT: + case INT: { int val; memcpy(&val, data, size); sstr << val; break; } - case VehicleInfoDefine::Status::DOUBLE: + case DOUBLE: { double val; memcpy(&val, data, size); sstr << val; break; } - case VehicleInfoDefine::Status::CHAR: + case CHAR: { char val; memcpy(&val, data, size); sstr << val; break; } - case VehicleInfoDefine::Status::INT16: + case INT16: { int16_t val; memcpy(&val, data, size); sstr << val; break; } - case VehicleInfoDefine::Status::UINT16: + case UINT16: { uint16_t val; memcpy(&val, data, size); sstr << val; break; } - case VehicleInfoDefine::Status::UINT32: + case UINT32: { uint32_t val; memcpy(&val, data, size); sstr << val; break; } - case VehicleInfoDefine::Status::INT64: + case INT64: { int64_t val; memcpy(&val, data, size); sstr << val; break; } - case VehicleInfoDefine::Status::UINT64: + case UINT64: { uint64_t val; memcpy(&val, data, size); sstr << val; break; } - case VehicleInfoDefine::Status::BOOL: + case BOOL: { bool val; memcpy(&val, data, size); @@ -239,12 +239,12 @@ Converter::toString(string ambname, char *data, int size, int Converter::toBinary(string ambname, AbstractPropertyType *value, int size, - VehicleInfoDefine::Status::DataType type, char *buf) + DataType type, char *buf) { stringstream sstr; sstr.str(""); if (find(specialconvertlist.begin(), specialconvertlist.end(), ambname) - != specialconvertlist.end()) { + != specialconvertlist.end()) { sstr << specialConvertAMBtoMW(ambname, value); } else { @@ -252,7 +252,7 @@ Converter::toBinary(string ambname, AbstractPropertyType *value, int size, } DebugOut(10) << "Converter toBinary " << sstr.str() << "\n"; switch (type) { - case VehicleInfoDefine::Status::INT: + case INT: { int val; sstr >> val; @@ -260,7 +260,7 @@ Converter::toBinary(string ambname, AbstractPropertyType *value, int size, DebugOut() << "Converter toBinary " << val << "\n"; break; } - case VehicleInfoDefine::Status::DOUBLE: + case DOUBLE: { double val; sstr >> val; @@ -268,7 +268,7 @@ Converter::toBinary(string ambname, AbstractPropertyType *value, int size, DebugOut() << "Converter toBinary " << val << "\n"; break; } - case VehicleInfoDefine::Status::CHAR: + case CHAR: { char val; sstr >> val; @@ -276,7 +276,7 @@ Converter::toBinary(string ambname, AbstractPropertyType *value, int size, DebugOut() << "Converter toBinary " << val << "\n"; break; } - case VehicleInfoDefine::Status::INT16: + case INT16: { int16_t val; sstr >> val; @@ -284,7 +284,7 @@ Converter::toBinary(string ambname, AbstractPropertyType *value, int size, DebugOut() << "Converter toBinary " << val << "\n"; break; } - case VehicleInfoDefine::Status::UINT16: + case UINT16: { uint16_t val; sstr >> val; @@ -292,7 +292,7 @@ Converter::toBinary(string ambname, AbstractPropertyType *value, int size, DebugOut() << "Converter toBinary " << val << "\n"; break; } - case VehicleInfoDefine::Status::UINT32: + case UINT32: { uint32_t val; sstr >> val; @@ -300,7 +300,7 @@ Converter::toBinary(string ambname, AbstractPropertyType *value, int size, DebugOut() << "Converter toBinary " << val << "\n"; break; } - case VehicleInfoDefine::Status::INT64: + case INT64: { int64_t val; sstr >> val; @@ -308,7 +308,7 @@ Converter::toBinary(string ambname, AbstractPropertyType *value, int size, DebugOut() << "Converter toBinary " << val << "\n"; break; } - case VehicleInfoDefine::Status::UINT64: + case UINT64: { uint64_t val; sstr >> val; @@ -316,7 +316,7 @@ Converter::toBinary(string ambname, AbstractPropertyType *value, int size, DebugOut() << "Converter toBinary " << val << "\n"; break; } - case VehicleInfoDefine::Status::BOOL: + case BOOL: { int tmpval; bool val; @@ -363,8 +363,8 @@ Converter::specialConvertAMBtoMW(std::string ambname, stringstream retstr; retstr.str(""); if (ambname == VehicleProperty::TransmissionShiftPosition) { - switch (boost::any_cast - (value->anyValue())) { + switch (boost::any_cast < Transmission::TransmissionPositions + > (value->anyValue())) { case Transmission::Neutral: { retstr << 2; @@ -442,12 +442,12 @@ Converter::specialConvertAMBtoMW(std::string ambname, } } DebugOut() << "Converter specialConvertAMBtoMW" - << "(TransmissionShiftPosition): " - << value->toString() << "->" << retstr.str() << std::endl; + << "(TransmissionShiftPosition): " << value->toString() << "->" + << retstr.str() << std::endl; } else if (ambname == VehicleProperty::TransmissionGearPosition) { - switch (boost::any_cast - (value->anyValue())) { + switch (boost::any_cast < Transmission::TransmissionPositions + > (value->anyValue())) { case Transmission::Neutral: { retstr << 64; @@ -494,8 +494,8 @@ Converter::specialConvertAMBtoMW(std::string ambname, } } DebugOut() << "Converter specialConvertAMBtoMW" - << "(TransmissionGearPosition): " - << value->toString() << "->" << retstr.str() << std::endl; + << "(TransmissionGearPosition): " << value->toString() << "->" + << retstr.str() << std::endl; } else if (ambname == VehicleProperty::TransmissionMode) { retstr << value->toString(); @@ -511,7 +511,7 @@ Converter::specialConvertAMBtoMW(std::string ambname, std::string Converter::specialConvertMWtoAMB(std::string ambname, char *data, int size, - VehicleInfoDefine::Status::DataType type) + DataType type) { stringstream retstr; retstr.str(""); @@ -600,8 +600,8 @@ Converter::specialConvertMWtoAMB(std::string ambname, char *data, int size, } } DebugOut() << "Converter specialConvertMWtoAMB" - << "(TransmissionShiftPosition): " - << val << "->" << retstr.str() << std::endl; + << "(TransmissionShiftPosition): " << val << "->" + << retstr.str() << std::endl; } else if (ambname == VehicleProperty::TransmissionGearPosition) { int val; @@ -643,8 +643,8 @@ Converter::specialConvertMWtoAMB(std::string ambname, char *data, int size, } } DebugOut() << "Converter specialConvertMWtoAMB" - << "(TransmissionGearPosition): " - << val << "->" << retstr.str() << std::endl; + << "(TransmissionGearPosition): " << val << "->" << retstr.str() + << std::endl; } else if (ambname == VehicleProperty::TransmissionMode) { int val; diff --git a/src/convert.h b/src/convert.h index f6bea27..08f2225 100644 --- a/src/convert.h +++ b/src/convert.h @@ -22,7 +22,7 @@ #include "abstractpropertytype.h" -#include "config.h" +#include "ambconfig.h" struct AMBVehicleInfo; struct MWVehicleInfo; @@ -47,7 +47,7 @@ public: * @return Success : true Failure : false */ bool - initialize(Config *conf); + initialize(AMBConfig *conf); /** * This function converts the vehicle infomation of MW into the vehicle information of AMB. * @@ -70,11 +70,10 @@ public: MWVehicleInfo *mwvehicleinfo); private: std::string - toString(std::string ambname, char *data, int size, - VehicleInfoDefine::Status::DataType type); + toString(std::string ambname, char *data, int size, DataType type); int toBinary(std::string ambname, AbstractPropertyType *value, int size, - VehicleInfoDefine::Status::DataType type, char *buf); + DataType type, char *buf); double toDouble(timeval time); timeval @@ -83,12 +82,12 @@ private: specialConvertAMBtoMW(std::string ambname, AbstractPropertyType *value); std::string specialConvertMWtoAMB(std::string ambname, char *data, int size, - VehicleInfoDefine::Status::DataType type); + DataType type); struct ConvertTable { std::string mwname; struct AmbVehicleInfoData { std::string ambname; - VehicleInfoDefine::Status::DataType type; + DataType type; int typesize; }; std::vector ambdataarray; diff --git a/src/messageformat.h b/src/messageformat.h index 7c613d3..d9977ca 100644 --- a/src/messageformat.h +++ b/src/messageformat.h @@ -37,9 +37,9 @@ enum CommonStatus { /** * The size of status(Used in the data message.) */ -static const int STATUSSIZE = StandardMessage::BUFSIZE - - StandardMessage::KEYEVENTTYPESIZE - - sizeof(timeval) - sizeof(int); +static const int STATUSSIZE = StandardMessage::BUFSIZE - + StandardMessage::KEYEVENTTYPESIZE - + sizeof(timeval) - sizeof(int); /** * The data portion of the data message. diff --git a/src/mwinterface.cc b/src/mwinterface.cc index 03f27fa..c1f7335 100644 --- a/src/mwinterface.cc +++ b/src/mwinterface.cc @@ -162,7 +162,7 @@ MWIF::~MWIF() } bool -MWIF::initialize(VICCommunicator *com, Config *conf) +MWIF::initialize(VICCommunicator *com, AMBConfig *conf) { communicator = com; @@ -179,14 +179,14 @@ MWIF::initialize(VICCommunicator *com, Config *conf) vi.delimeterposition.push_back((*itr2).typesize); } vehicleinfoArray.push_back(vi); - DebugOut() << "MWIF initialize mwvehicleinfo name = " << vi.name + 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"; + DebugOut() << "MWIF initialize portinfo (" << portinfo.standard.dataPort + << "," << portinfo.standard.controlPort << "," + << portinfo.custom.dataPort << "," << portinfo.custom.controlPort + << ")\n"; createThread(&portinfo); return true; } @@ -205,9 +205,9 @@ MWIF::send(MWVehicleInfo *vehicleinfo) vehicleinfo->statussize = curvehicleinfo->statussize; vehicleinfo->delimeterposition = curvehicleinfo->delimeterposition; DebugOut(10) << "MWIF send : mwnotifyinfomap.size() = " - << mwnotifyinfomap.size() << "\n"; + << mwnotifyinfomap.size() << "\n"; for (auto itr = mwnotifyinfomap.begin(); itr != mwnotifyinfomap.end(); - itr++) { + itr++) { if ((*itr).second.checkNotify(vehicleinfo->name, curvehicleinfo->status, vehicleinfo->status, @@ -228,7 +228,7 @@ MWIF::recvRawdata(int commid, char *keyeventtype, timeval recordtime, DebugOut() << "MWIF recvRawdata(" << commid << "," << keyeventtype << ")\n"; if (find(string(keyeventtype)) != NULL) { if (websocketservermap.find(commid) == websocketservermap.end()) { - registDestination(commid); + return; } websocketserver[static_cast(websocketservermap[commid])]->receive( commid, keyeventtype, recordtime, data, len); @@ -240,7 +240,7 @@ MWIF::recvRawdata(int commid, char *keyeventtype, timeval recordtime, errorvi.name = string(keyeventtype); errorvi.recordtime = recordtime; errorvi.statussize = len - StandardMessage::KEYEVENTTYPESIZE - - sizeof(timeval) - sizeof(int); + - sizeof(timeval) - sizeof(int); memset(errorvi.status, 0, STATUSSIZE); sendMessage(commid, UNKNOWN, &errorvi); } @@ -284,34 +284,24 @@ MWIF::recvMessage(MessageType type, int commid, char *keyeventtype, } void -MWIF::registDestination(int commid) +MWIF::registDestination(ControlWebsocket::ServerProtocol type, 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; - } - } + DebugOut() << "MWIF type = " << type << std::endl; + if (websocketserver[type]->registSocket(commid)) { + DebugOut() << "MWIF registDestination insert(" << commid << "," << type + << ")\n"; + websocketservermap.insert(make_pair(commid, type)); } } void -MWIF::unregistDestination(int commid) +MWIF::unregistDestination(ControlWebsocket::ServerProtocol type, 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; - } + if (websocketserver[type]->unregistSocket(commid)) { + DebugOut() << "MWIF unregistDestination erase(" << commid << "," + << type << ")\n"; + websocketservermap.erase(commid); } } } @@ -323,11 +313,11 @@ MWIF::sendMessage(int commid, CommonStatus status, MWVehicleInfo *vehicleinfo) opt.common_status = status; memcpy(opt.status, vehicleinfo->status, STATUSSIZE); size_t len = StandardMessage::KEYEVENTTYPESIZE + sizeof(timeval) - + sizeof(int) + vehicleinfo->statussize; + + sizeof(int) + vehicleinfo->statussize; DebugOut(10) << "MWIF sendMessage vehicleinfo->statussize = " << vehicleinfo->statussize << ", len = " << len << std::endl; if (websocketservermap.find(commid) == websocketservermap.end()) { - registDestination(commid); + return; } DebugOut() << "MWIF sendMessage controlwebsocket->send(" << commid << "," << vehicleinfo->name << "),len = " << len << std::endl; @@ -342,22 +332,23 @@ 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); + portinfo->standard.dataPort, ControlWebsocket::DATA_STANDARD, this); websocketserver[ControlWebsocket::CONTROL_STANDARD]->initialize( - portinfo->standard.controlPort, ControlWebsocket::CONTROL_STANDARD); + portinfo->standard.controlPort, ControlWebsocket::CONTROL_STANDARD, + this); websocketserver[ControlWebsocket::DATA_CUSTOM]->initialize( - portinfo->custom.dataPort, ControlWebsocket::DATA_CUSTOM); + portinfo->custom.dataPort, ControlWebsocket::DATA_CUSTOM, this); websocketserver[ControlWebsocket::CONTROL_CUSTOM]->initialize( - portinfo->custom.controlPort, ControlWebsocket::CONTROL_CUSTOM); + portinfo->custom.controlPort, ControlWebsocket::CONTROL_CUSTOM, + this); } MWVehicleInfo * MWIF::find(string name) { for (auto itr = vehicleinfoArray.begin(); itr != vehicleinfoArray.end(); - itr++) { + itr++) { DebugOut(10) << "MWIF find" << (*itr).name << std::endl; if ((*itr).name == name) { return &(*itr); diff --git a/src/mwinterface.h b/src/mwinterface.h index ff42886..ee2e870 100644 --- a/src/mwinterface.h +++ b/src/mwinterface.h @@ -28,7 +28,7 @@ #include -#include "config.h" +#include "ambconfig.h" #include "controlwebsocket.h" #include "messageformat.h" @@ -138,7 +138,7 @@ public: * @return Success : true Failure : false */ bool - initialize(VICCommunicator *com, Config *conf); + initialize(VICCommunicator *com, AMBConfig *conf); /** * This function issues a request to send vehicle information to the MW. * @@ -178,14 +178,14 @@ public: */ void - registDestination(int commid); + registDestination(ControlWebsocket::ServerProtocol type, int commid); /** * Unmapped instances and destination socket ID. * * @param commid Socket ID. */ void - unregistDestination(int commid); + unregistDestination(ControlWebsocket::ServerProtocol type, int commid); private: void diff --git a/src/viccommunicator.cc b/src/viccommunicator.cc index 747a953..656fad9 100644 --- a/src/viccommunicator.cc +++ b/src/viccommunicator.cc @@ -64,7 +64,7 @@ VICCommunicator::setAMBVehicleInfo(MWVehicleInfo *vehicleinfo) } } DebugOut(10) << "VICCOMM" << " out setAMBVehicleInfo(MWname = " - << vehicleinfo->name << ")"; + << vehicleinfo->name << ")"; } void @@ -74,7 +74,7 @@ VICCommunicator::getAMBVehicleInfo(MWVehicleInfo *vehicleinfo) AMBVehicleInfo tempambvehicleinfo[maxambdatasize]; DebugOut() << "VICCOMM" << " in getAMBVehicleInfo(" << vehicleinfo->name - << "," << vehicleinfo->status[0] << ")\n"; + << "," << vehicleinfo->status[0] << ")\n"; resetAmbBuf(&tempambvehicleinfo[0], maxambdatasize); int ret = converter->convertMWtoAMB(vehicleinfo, &tempambvehicleinfo[0], maxambdatasize); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e5c6a51..3fee0b3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,10 +2,10 @@ 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) +set(testVehiclePluginMW_sources ../src/abstractconfig.cc ../src/ambconfig.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}) +target_link_libraries(testVehiclePluginMW amb pthread websockets -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} ${gio_LIBRARIES} ${gio-unix_LIBRARIES} -lico-util-com) -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) +set(testVehiclePluginWSApp_sources ../src/abstractconfig.cc ../src/ambconfig.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}) +target_link_libraries(testVehiclePluginWSApp amb pthread websockets -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} ${gio_LIBRARIES} ${gio-unix_LIBRARIES} -lico-util-com) diff --git a/tests/configamb.cc b/tests/configamb.cc index e197d87..1012ff1 100644 --- a/tests/configamb.cc +++ b/tests/configamb.cc @@ -1,34 +1,10 @@ -/** - * 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" @@ -37,7 +13,8 @@ using std::string; using std::vector; -ConfigAMB::ConfigAMB() : port(23000) +ConfigAMB::ConfigAMB() : + port(23000) { } @@ -74,102 +51,72 @@ 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"; + json_object *rootobject; + json_tokener *tokener = json_tokener_new(); + enum json_tokener_error err; + do { + rootobject = json_tokener_parse_ex(tokener, config.c_str(), + config.length()); + } while ((err = json_tokener_get_error(tokener)) == json_tokener_continue); + + if (err != json_tokener_success) { + std::cerr << "Error: " << json_tokener_error_desc(err) << "\n"; return ret; } - - JsonReader* reader = json_reader_new(node); - - if (reader == nullptr) { - DebugOut() << "Unable to create JSON reader"; + json_object *configobject = json_object_object_get(rootobject, "sources"); + if (!configobject) { + std::cerr << "Error getting ConfigAMB\n"; 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") { + array_list *configlist = json_object_get_array(configobject); + for (int i = 0; i < array_list_length(configlist); i++) { + json_object *obj = reinterpret_cast(array_list_get_idx( + configlist, i)); + json_object *nameobj = json_object_object_get(obj, "name"); + if ("VehicleSource" != string(json_object_get_string(nameobj))) { + std::cout << "Loop:" << json_object_get_string(nameobj) << "\n"; 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); + json_object *conffileobj = json_object_object_get(obj, "configfile"); + if (!conffileobj) { + std::cerr << "Error: conffileobj = NULL" << std::endl; + break; + } + else { + ambformatpath = std::string(json_object_get_string(conffileobj)); + } ret = true; + break; } - - 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") { + configobject = json_object_object_get(rootobject, "sinks"); + if (!configobject) { + std::cerr << "Error getting ConfigAMB\n"; + return ret; + } + configlist = json_object_get_array(configobject); + for (int i = 0; i < array_list_length(configlist); i++) { + json_object *obj = reinterpret_cast(array_list_get_idx( + configlist, i)); + json_object *nameobj = json_object_object_get(obj, "name"); + if ("WebsocketSink" != string(json_object_get_string(nameobj))) { continue; } - - if (json_reader_read_member(reader, "port")) { - port = json_reader_get_int_value(reader); - json_reader_end_member(reader); + json_object *portobj = json_object_object_get(obj, "port"); + if (!portobj) { + port = 23000; + std::cout << "Default Port = " << port << std::endl; } else { - port = 23000; + port = json_object_get_int(portobj); + std::cout << "Read Port = " << port << std::endl; } - - json_reader_end_element(reader); - } - - json_reader_end_member(reader); - - ///TODO: this will probably explode: - - if (error) { - g_error_free(error); + ret = true; + break; } - - g_object_unref(reader); - g_object_unref(parser); return ret; } diff --git a/tests/configamb.h b/tests/configamb.h index db28cb4..6f80482 100644 --- a/tests/configamb.h +++ b/tests/configamb.h @@ -22,12 +22,12 @@ #include #include -#include "config.h" +#include "ambconfig.h" /** * This class handles the data in the configuration file. */ -class ConfigAMB : public Config { +class ConfigAMB { public: /** * Constructor. @@ -39,13 +39,16 @@ public: ~ConfigAMB(); bool readConfig(std::string confpath); + int getPort(); + std::string getAMBformatPath(); private: bool parseJson(std::string config); + std::string ambformatpath; int port; }; diff --git a/tests/controlwebsocketclient.cc b/tests/controlwebsocketclient.cc index 1aa370d..bdc36a6 100644 --- a/tests/controlwebsocketclient.cc +++ b/tests/controlwebsocketclient.cc @@ -17,8 +17,10 @@ * */ #include +#include #include +#include #include "debugout.h" @@ -32,11 +34,11 @@ pthread_mutex_t ControlWebsocketClient::mutex_scenario = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t ControlWebsocketClient::cond_scenario = PTHREAD_COND_INITIALIZER; std::string ControlWebsocketClient::vehiclename_scenario = ""; +void *ControlWebsocketClient::wsi[4] = {NULL, NULL, NULL, NULL}; ControlWebsocketClient::ControlWebsocketClient() { mutex = PTHREAD_MUTEX_INITIALIZER; - protocollist[1] = {NULL, NULL, 0}; } ControlWebsocketClient::~ControlWebsocketClient() @@ -49,44 +51,58 @@ ControlWebsocketClient::initialize(int port, { DebugOut(10) << "ControlWebsocketClient initialize.(" << port << ")\n"; type = stype; + stringstream address, protocol; + address.str(""); + address << "ws://127.0.0.1:" << port; + protocol.str(""); switch (type) { case ControlWebsocket::DATA_STANDARD: { - protocollist[0] = {"standarddatamessage-only", ControlWebsocketClient::callback_receive, 0}; + protocol << "standarddatamessage-only"; break; } - case ControlWebsocket::CONTROL_STANDARD : { - protocollist[0] = {"standardcontrolmessage-only", ControlWebsocketClient::callback_receive, 0}; + case ControlWebsocket::CONTROL_STANDARD: + { + protocol << "standardcontrolmessage-only"; break; } - case ControlWebsocket::DATA_CUSTOM : { - protocollist[0] = {"customdatamessage-only", ControlWebsocketClient::callback_receive, 0}; + case ControlWebsocket::DATA_CUSTOM: + { + protocol << "customdatamessage-only"; break; } - case ControlWebsocket::CONTROL_CUSTOM : { - protocollist[0] = {"customcontrolmessage-only", ControlWebsocketClient::callback_receive, 0}; + case ControlWebsocket::CONTROL_CUSTOM: + { + protocol << "customcontrolmessage-only"; break; } - default : { + default: + { return false; } } - context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, "lo", - protocollist, - libwebsocket_internal_extensions, - NULL, NULL, -1, -1, 0); + context = ico_uws_create_context(address.str().c_str(), + protocol.str().c_str()); 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) { + if (ico_uws_set_event_cb(context, ControlWebsocketClient::callback_receive, + ((void *)type)) != 0) { + DebugOut() << "ControlWebsocket[" << type << "]" + << " couldn't set callback function." << std::endl; 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); + ico_uws_close(context); return false; } return true; @@ -102,17 +118,17 @@ ControlWebsocketClient::send(char *keyeventtype, timeval time, void *data, case ControlWebsocket::DATA_STANDARD: case ControlWebsocket::DATA_CUSTOM: { - memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING, + memcpy(buf, datamsg.encode(keyeventtype, time, *(reinterpret_cast(data))), - len); + len); DebugOut(10) << keyeventtype << " encode\n"; break; } case ControlWebsocket::CONTROL_STANDARD: case ControlWebsocket::CONTROL_CUSTOM: { - memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING, + memcpy(buf, eventmsg.encode(keyeventtype, time, *(reinterpret_cast(data))), len); @@ -124,11 +140,8 @@ ControlWebsocketClient::send(char *keyeventtype, timeval time, void *data, 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"; + ico_uws_send(context, wsi[type], reinterpret_cast(buf), + len); pthread_mutex_unlock(&mutex); return true; } @@ -144,26 +157,41 @@ ControlWebsocketClient::receive(char *keyeventtype, timeval recordtime, void ControlWebsocketClient::observation() { - int ret = 0; - while (ret >= 0) { - ret = libwebsocket_service(context, 100); - if (ret != 0) { - break; - } + while (true) { + ico_uws_service(context); + usleep(50); } } -int -ControlWebsocketClient::callback_receive(libwebsocket_context *context, - libwebsocket *wsi, - libwebsocket_callback_reasons reason, - void *user, void *in, size_t len) +void +ControlWebsocketClient::callback_receive(const struct ico_uws_context *context, + const ico_uws_evt_e event, + const void *id, + const ico_uws_detail *detail, + void *user_data) { - switch (reason) { - case LWS_CALLBACK_CLIENT_RECEIVE: + switch (event) { + case ICO_UWS_EVT_OPEN: + { + int idx = reinterpret_cast(user_data); + DebugOut() << "Open. wsi index = " << idx << "\n"; + ControlWebsocketClient::wsi[idx] = const_cast(id); + break; + } + case ICO_UWS_EVT_ERROR: + break; + case ICO_UWS_EVT_CLOSE: + { + int idx = reinterpret_cast(user_data); + ControlWebsocketClient::wsi[idx] = NULL; + break; + } + case ICO_UWS_EVT_RECEIVE: { DataMessage msg; - msg.decode(reinterpret_cast(in), len); + char *recvbuf = + reinterpret_cast(detail->_ico_uws_message.recv_data); + msg.decode(recvbuf, detail->_ico_uws_message.recv_len); DebugOut(10) << "[R]: " << msg.getKeyEventType() << " , " << msg.getRecordtime().tv_sec << "." << msg.getRecordtime().tv_usec << " , "; @@ -173,12 +201,13 @@ ControlWebsocketClient::callback_receive(libwebsocket_context *context, } break; } + case ICO_UWS_EVT_ADD_FD: + break; + case ICO_UWS_EVT_DEL_FD: + break; default: - { break; } - } - return 0; } void * diff --git a/tests/controlwebsocketclient.h b/tests/controlwebsocketclient.h index 3ce2baa..b17d92a 100644 --- a/tests/controlwebsocketclient.h +++ b/tests/controlwebsocketclient.h @@ -25,8 +25,6 @@ #include #include -#include - #include "controlwebsocket.h" #include "eventmessage.h" #include "datamessage.h" @@ -43,27 +41,28 @@ public: 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 + callback_receive(const struct ico_uws_context *context, + const ico_uws_evt_e event, const void *id, + const ico_uws_detail *detail, void *user_data); + static void * run(void *arg); static pthread_mutex_t mutex_scenario; static pthread_cond_t cond_scenario; static std::string vehiclename_scenario; + static void *wsi[4]; -private: - libwebsocket_context *context; - libwebsocket* socket; - libwebsocket_protocols protocollist[2]; +protected: enum ControlWebsocket::ServerProtocol type; +private: + ico_uws_context *context; 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]; + char buf[StandardMessage::BUFSIZE]; }; #endif // #ifndef CONTROLWEBSOCKETCLIENT_H_ diff --git a/tests/controlwebsocketclientapp.cc b/tests/controlwebsocketclientapp.cc index 23b13d4..35c1813 100644 --- a/tests/controlwebsocketclientapp.cc +++ b/tests/controlwebsocketclientapp.cc @@ -17,8 +17,10 @@ * */ #include +#include #include +#include #include "debugout.h" @@ -31,11 +33,11 @@ pthread_mutex_t ControlWebsocketClientApp::mutex_scenario = pthread_cond_t ControlWebsocketClientApp::cond_scenario = PTHREAD_COND_INITIALIZER; std::string ControlWebsocketClientApp::vehiclename_scenario = ""; +void *ControlWebsocketClientApp::wsiapp = NULL; ControlWebsocketClientApp::ControlWebsocketClientApp() { mutex = PTHREAD_MUTEX_INITIALIZER; - protocollist[1] = {NULL, NULL, 0}; } ControlWebsocketClientApp::~ControlWebsocketClientApp() @@ -46,24 +48,23 @@ 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); + stringstream address; + address.str(""); + address << "ws://127.0.0.1:" << port; + context = ico_uws_create_context(address.str().c_str(), "http-only"); 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) { + if (ico_uws_set_event_cb(context, + ControlWebsocketClientApp::callback_receive, NULL) + != 0) { + DebugOut() << "ControlWebsocket[" << type << "]" + << " couldn't set callback function." << std::endl; return false; } if (pthread_create(&threadid, NULL, ControlWebsocketClientApp::run, (void*)this) == -1) { - libwebsocket_context_destroy(context); + ico_uws_close(context); return false; } return true; @@ -82,16 +83,12 @@ ControlWebsocketClientApp::send(std::string type, std::string name, jdata.timestamp = timestamp; vector dataarray; dataarray.push_back(jdata); - memcpy(buf + LWS_SEND_BUFFER_PRE_PADDING, - jsonmsg.encode(type, name, "transactionid", dataarray), + memcpy(buf, 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"; + while (buf[(i++)] != '\0') + ; + ico_uws_send(context, wsiapp, reinterpret_cast(buf), i); pthread_mutex_unlock(&mutex); return true; } @@ -106,45 +103,57 @@ ControlWebsocketClientApp::receive(char *keyeventtype, timeval recordtime, void ControlWebsocketClientApp::observation() { - int ret = 0; - while (ret >= 0) { - ret = libwebsocket_service(context, 100); - if (ret != 0) { - break; - } + while (true) { + ico_uws_service(context); + usleep(50); } } -int +void ControlWebsocketClientApp::callback_receive( - libwebsocket_context *context, libwebsocket *wsi, - libwebsocket_callback_reasons reason, void *user, void *in, size_t len) + const struct ico_uws_context *context, const ico_uws_evt_e event, + const void *id, const ico_uws_detail *detail, void *user_data) { - switch (reason) { - case LWS_CALLBACK_CLIENT_RECEIVE: + switch (event) { + case ICO_UWS_EVT_OPEN: + { + ControlWebsocketClientApp::wsiapp = const_cast(id); + break; + } + case ICO_UWS_EVT_ERROR: + break; + case ICO_UWS_EVT_CLOSE: + { + ControlWebsocketClientApp::wsiapp = NULL; + break; + } + case ICO_UWS_EVT_RECEIVE: { JsonMessage jmsg; - jmsg.decode(std::string(reinterpret_cast(in)), len); + char *recvbuf = + reinterpret_cast(detail->_ico_uws_message.recv_data); + jmsg.decode(recvbuf, detail->_ico_uws_message.recv_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)) { + == ControlWebsocketClientApp::vehiclename_scenario) || + (jmsg.getName() + == ControlWebsocketClientApp::vehiclename_scenario)) { pthread_cond_signal(&ControlWebsocketClientApp::cond_scenario); } } break; } + case ICO_UWS_EVT_ADD_FD: + break; + case ICO_UWS_EVT_DEL_FD: + break; default: - { break; } - } - return 0; } void * diff --git a/tests/controlwebsocketclientapp.h b/tests/controlwebsocketclientapp.h index 6fab240..1bd9230 100644 --- a/tests/controlwebsocketclientapp.h +++ b/tests/controlwebsocketclientapp.h @@ -44,25 +44,23 @@ public: 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 + callback_receive(const struct ico_uws_context *context, + const ico_uws_evt_e event, const void *id, + const ico_uws_detail *detail, void *user_data); static void * run(void *arg); static pthread_mutex_t mutex_scenario; static pthread_cond_t cond_scenario; static std::string vehiclename_scenario; + static void *wsiapp; private: - libwebsocket_context *context; - libwebsocket* socket; - libwebsocket_protocols protocollist[2]; + ico_uws_context *context; JsonMessage jsonmsg; pthread_t threadid; pthread_mutex_t mutex; - char buf[LWS_SEND_BUFFER_PRE_PADDING + JsonMessage::BUFSIZE - + LWS_SEND_BUFFER_POST_PADDING]; + char buf[JsonMessage::BUFSIZE]; }; #endif // #ifndef CONTROLWEBSOCKETCLIENTAPP_H_ diff --git a/tests/mwscenario.cc b/tests/mwscenario.cc index 50662ad..a74dcba 100644 --- a/tests/mwscenario.cc +++ b/tests/mwscenario.cc @@ -22,8 +22,6 @@ #include #include -#include - #include "debugout.h" #include "vehicleproperty.h" @@ -32,7 +30,7 @@ extern std::list VehicleProperty::mCapabilities; extern VehicleProperty vehiclePropertyConstruct; -const int sleeptime = 25 * 1000; +const int sleeptime = 50 * 1000; MWScenarioEngine::MWScenarioEngine() { @@ -80,9 +78,8 @@ MWScenarioEngine::start() 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; + << time.tv_sec << "." << time.tv_usec << " , " << eopt.common + << " , " << eopt.sense << " , " << eopt.event_mask << std::endl; ControlWebsocketClient::vehiclename_scenario = vehicleinfomapbeginitr->first; waitcount = vehicleinfomapbeginitr->second.size(); @@ -98,7 +95,7 @@ MWScenarioEngine::start() // Get DebugOut(10) << "=========" << "MW Get" << "=========" << std::endl; for (auto itr = vehicleinfomap.begin(); itr != vehicleinfomap.end(); - itr++) { + itr++) { usleep(sleeptime); memset(status, 0, sizeof(status)); idx = 0; @@ -118,8 +115,8 @@ MWScenarioEngine::start() 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; + << time.tv_usec << " , " << eopt.common << " , " << eopt.sense + << " , " << eopt.event_mask << std::endl; } // Wait Get pthread_mutex_lock(&ControlWebsocketClient::mutex_scenario); @@ -144,8 +141,8 @@ MWScenarioEngine::start() 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; + << time.tv_usec << " , " << eopt.common << " , " << eopt.sense + << " , " << eopt.event_mask << std::endl; usleep(sleeptime); eopt.common = 50; @@ -153,8 +150,8 @@ MWScenarioEngine::start() 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; + << time.tv_usec << " , " << eopt.common << " , " << eopt.sense + << " , " << eopt.event_mask << std::endl; } // Set(1st) DebugOut(10) << "=========" << "MW Set" << "=========" << std::endl; @@ -278,7 +275,6 @@ MWScenarioEngine::initialize() int main() { - g_type_init(); DebugOut::setDebugThreshhold(5); MWScenarioEngine mwengine; if (!mwengine.initialize()) { diff --git a/tests/scenarioengine.h b/tests/scenarioengine.h index f7041be..1bd46f3 100644 --- a/tests/scenarioengine.h +++ b/tests/scenarioengine.h @@ -21,14 +21,14 @@ #include #include "abstractpropertytype.h" -#include "config.h" +#include "ambconfig.h" #include "controlwebsocketclient.h" #include "controlwebsocketclientapp.h" const std::string CONFPATH = "/etc/ambd/AMBformat.conf"; struct MWInfo { - VehicleInfoDefine::Status::DataType type; + DataType type; int typesize; bool isCustom; }; @@ -46,7 +46,7 @@ public: initialize() = 0; protected: - Config conf; + AMBConfig conf; int loadscenario; }; diff --git a/tests/standardjsonmessage.cc b/tests/standardjsonmessage.cc index bf14739..4ab6471 100644 --- a/tests/standardjsonmessage.cc +++ b/tests/standardjsonmessage.cc @@ -1,28 +1,8 @@ -/** - * 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 #include "standardjsonmessage.h" @@ -51,10 +31,11 @@ JsonMessage::encode(std::string type_, std::string name_, } else { sstr << "{\"property\":\"" << (*itr).propertyName - << "\", \"value\":\"" << (*itr).value << "\"}"; + << "\", \"value\":\"" << (*itr).value << "\"}"; } } sstr << "],\"transactionid\":\"" << transactionid_ << "\"}"; + //std::cout << "JsonMessage Encode Messgae is : " << sstr.str() << "[" << sstr.str().length() << "]" << std::endl; memset(encodebuf, 0, sizeof(encodebuf)); memcpy(encodebuf, const_cast(sstr.str().c_str()), sizeof(encodebuf)); return &encodebuf[0]; @@ -64,146 +45,129 @@ void JsonMessage::decode(std::string msg, size_t len) { data.clear(); + //std::cout << "Decode message is " << msg << std::endl; - 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); + json_object *rootobject; + json_tokener *tokener = json_tokener_new(); + enum json_tokener_error err; + do { + rootobject = json_tokener_parse_ex(tokener, msg.c_str(), msg.length()); + } while ((err = json_tokener_get_error(tokener)) == json_tokener_continue); - if (node == nullptr) { - std::cerr << "Unable to get JSON root object\n"; + if (err != json_tokener_success) { + std::cerr << "Error: " << json_tokener_error_desc(err) << "\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 { + json_object *object = json_object_object_get(rootobject, "type"); + if (!object) { std::cerr << "Error Get type\n"; return; } + type = std::string(json_object_get_string(object)); - if (json_reader_read_member(reader, "name")) { - name = std::string(json_reader_get_string_value(reader)); - json_reader_end_member(reader); - } - else { + object = json_object_object_get(rootobject, "name"); + if (!object) { std::cerr << "Error Get name\n"; return; } + name = std::string(json_object_get_string(object)); - if (json_reader_read_member(reader, "transactionid")) { - transactionid = std::string(json_reader_get_string_value(reader)); - json_reader_end_member(reader); - } - else { + object = json_object_object_get(rootobject, "transactionid"); + if (!object) { std::cerr << "Error Get transactionid\n"; return; } + transactionid = std::string(json_object_get_string(object)); - if (json_reader_read_member(reader, "data")) { - if (json_reader_is_array(reader)) { + object = json_object_object_get(rootobject, "data"); + if (json_object_get_type(object) == json_type_array) { + array_list *datalist = json_object_get_array(object); + for (int i = 0; i < array_list_length(datalist); i++) { 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)) { + json_object *dataarrayobject = + reinterpret_cast(array_list_get_idx(datalist, + i)); + if (json_object_get_type(dataarrayobject) == json_type_object) { + json_object *dataobject = json_object_object_get( + dataarrayobject, "property"); + if (dataobject) { 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; + json_object_get_string(dataobject)); } - 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"; + + dataobject = json_object_object_get(dataarrayobject, "value"); + if (!dataobject) { + std::cerr << "Error Get value[" << i << "]\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"; + jdata.value = std::string(json_object_get_string(dataobject)); + + dataobject = json_object_object_get(dataarrayobject, + "timestamp"); + if (!dataobject) { + std::cerr << "Error Get timestamp[" << i << "]\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"; + jdata.timestamp = json_object_get_double(dataobject); + + dataobject = json_object_object_get(dataarrayobject, + "sequence"); + if (!dataobject) { + std::cerr << "Error Get sequence[" << i << "]\n"; return; } + jdata.sequence = json_object_get_int(dataobject); + data.push_back(jdata); } - else if (json_reader_is_value(reader)) { + else if (json_object_get_type(dataarrayobject) + == json_type_string) { jdata.propertyName = std::string( - json_reader_get_string_value(reader)); + json_object_get_string(dataarrayobject)); + data.push_back(jdata); } - data.push_back(jdata); } } else { - std::cerr << "Error Get data\n"; - return; - } - json_reader_end_member(reader); + JsonData jdata; + if (json_object_get_type(object) == json_type_object) { + json_object *dataobject; + if (type == "valuechanged") { + jdata.propertyName = name; + } + else { + dataobject = json_object_object_get(object, "property"); + if (dataobject) { + jdata.propertyName = std::string( + json_object_get_string(dataobject)); + } + } + + dataobject = json_object_object_get(object, "value"); + if (!dataobject) { + std::cerr << "Error Get value\n"; + return; + } + jdata.value = std::string(json_object_get_string(dataobject)); - if (error) - g_error_free(error); + dataobject = json_object_object_get(object, "timestamp"); + if (!dataobject) { + std::cerr << "Error Get timestamp\n"; + return; + } + jdata.timestamp = json_object_get_double(dataobject); - g_object_unref(reader); - g_object_unref(parser); + dataobject = json_object_object_get(object, "sequence"); + if (!dataobject) { + std::cerr << "Error Get sequence\n"; + return; + } + jdata.sequence = json_object_get_int(dataobject); + } + else if (json_object_get_type(object) == json_type_string) { + jdata.propertyName = std::string(json_object_get_string(object)); + } + data.push_back(jdata); + } } std::string diff --git a/tests/standardjsonmessage.h b/tests/standardjsonmessage.h index bf6eb8d..8838b95 100644 --- a/tests/standardjsonmessage.h +++ b/tests/standardjsonmessage.h @@ -1,21 +1,3 @@ -/** - * 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 diff --git a/tests/websocketscenario.cc b/tests/websocketscenario.cc index 1b8d9f1..d202a12 100644 --- a/tests/websocketscenario.cc +++ b/tests/websocketscenario.cc @@ -24,15 +24,13 @@ #include #include -#include - #include "debugout.h" #include "configamb.h" #include "scenarioengine.h" std::string AMBCONFPATH = "/etc/ambd/config"; -const int sleeptime = 100 * 1000; +const int sleeptime = 75 * 1000; WebsocketAppScenarioEngine::WebsocketAppScenarioEngine() { @@ -77,7 +75,8 @@ WebsocketAppScenarioEngine::start() DebugOut(10) << "WebsocketApp Next." << std::endl; } DebugOut(10) << "vehiclename_scenario = " - << ControlWebsocketClientApp::vehiclename_scenario << std::endl; + << ControlWebsocketClientApp::vehiclename_scenario + << std::endl; DebugOut(10) << "=========" << "WebsocketApp Set" << "=========" << std::endl; @@ -107,7 +106,7 @@ WebsocketAppScenarioEngine::start() pthread_mutex_unlock(&ControlWebsocketClientApp::mutex_scenario); DebugOut(10) << "WebsocketApp Next." << std::endl; DebugOut(10) << "=========" << "WebsocketApp Set & Get" << "=========" - << std::endl; + << std::endl; for (auto itr = namelist.begin(); itr != namelist.end(); itr++) { for (auto itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) { @@ -171,7 +170,6 @@ WebsocketAppScenarioEngine::initialize() int main() { - g_type_init(); DebugOut::setDebugThreshhold(5); WebsocketAppScenarioEngine wsengine; if (!wsengine.initialize()) { diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt new file mode 100644 index 0000000..b6e9539 --- /dev/null +++ b/tool/CMakeLists.txt @@ -0,0 +1,6 @@ +include(CheckIncludeFiles) + +set(ico_set_vehicleinfo_sources ico_set_vehicleinfo.c) +include_directories(${CMAKE_SOURCE_DIR}/lib ${include_dirs} /usr/include/ico-util) +add_executable(ico_set_vehicleinfo ${ico_set_vehicleinfo_sources}) +target_link_libraries(ico_set_vehicleinfo websockets -L${CMAKE_CURRENT_BINARY_DIR}/lib ${link_libraries} -lico-util-com) diff --git a/tool/ico_set_vehicleinfo.c b/tool/ico_set_vehicleinfo.c new file mode 100644 index 0000000..9e838aa --- /dev/null +++ b/tool/ico_set_vehicleinfo.c @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2013, TOYOTA MOTOR CORPORATION. + * + * This program is licensed under the terms and conditions of the + * Apache License, version 2.0. The full text of the Apache License is at + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ +/** + * @brief System Test Tool for set VehicleInfo + * + * @date Apr-09-2013 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TYPE_NULL 0 +#define TYPE_BOOL 1 +#define TYPE_BYTE 2 +#define TYPE_INT16 3 +#define TYPE_UINT16 4 +#define TYPE_INT32 5 +#define TYPE_UINT32 6 +#define TYPE_DOUBLE 7 +#define TYPE_STRING 8 +#define TYPE_SHIFT 12 + +#define LWS_DEFAULTIP "127.0.0.1" /* connection default ip(localhost) */ +#define LWS_DEFAULTPORT 25010 /* connection default port */ +#define LWS_PROTOCOLNAME "standarddatamessage-only" + /* connection protocol name */ +static const struct { + char *prop; + char *eventtype; + unsigned char datatype[4]; +} vehicleinfo_key[] = { + { "VehicleSpeed", "VELOCITY", {TYPE_INT32, TYPE_NULL, 0,0} }, + { "Speed", "VELOCITY", {TYPE_INT32, TYPE_NULL, 0,0} }, + { "Velocity", "VELOCITY", {TYPE_INT32, TYPE_NULL, 0,0} }, + { "Location", "LOCATION", {TYPE_DOUBLE, TYPE_DOUBLE, TYPE_DOUBLE, TYPE_NULL} }, + { "Direction", "DIRECTION", {TYPE_DOUBLE, TYPE_NULL, 0,0} }, + { "EngineSpeed", "ENGINE_SPEED", {TYPE_INT32, TYPE_NULL, 0, 0} }, + { "Engine", "ENGINE_SPEED", {TYPE_INT32, TYPE_NULL, 0, 0} }, + { "Shift", "SHIFT", {TYPE_SHIFT, TYPE_BYTE, TYPE_NULL, 0} }, + { "ShiftPosition", "SHIFT", {TYPE_SHIFT, TYPE_BYTE, TYPE_NULL, 0} }, + { "Break_Signal", "BRAKE_SIGNAL", {TYPE_BOOL, TYPE_NULL, 0,0} }, + { "BreakSignal", "BRAKE_SIGNAL", {TYPE_BOOL, TYPE_NULL, 0,0} }, + { "Break", "BRAKE_SIGNAL", {TYPE_BOOL, TYPE_NULL, 0,0} }, + { "Blinker", "TURN_SIGNAL", {TYPE_INT32, TYPE_NULL, 0, 0} }, + { "Winker", "TURN_SIGNAL", {TYPE_INT32, TYPE_NULL, 0, 0} }, + { "TurnSignal", "TURN_SIGNAL", {TYPE_INT32, TYPE_NULL, 0, 0} }, + { "Turn", "TURN_SIGNAL", {TYPE_INT32, TYPE_NULL, 0, 0} }, + { "lightStatus", "LIGHTSTATUS", {TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_BOOL} }, + { "light", "LIGHTSTATUS", {TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_BOOL} }, + { "WATER_TEMP", "WATER_TEMP", {TYPE_INT32, TYPE_NULL, 0, 0} }, + { "\0", "\0", {TYPE_NULL, 0,0,0} } }; + +struct KeyDataMsg_t +{ + char KeyEventType[64]; + struct timeval recordtime; + struct KeyData + { + int common_status; + char status[]; + } data; +}; + +static struct ico_uws_context *context = NULL; + /* connection context */ +static void *connect_id = NULL; + /* connection connection id */ +static int connected = 0; /* connection flag */ + +static void uws_callback(const struct ico_uws_context *context, + const ico_uws_evt_e reason, const void *id, + const ico_uws_detail *detail, void *user_data); + +static void +uws_callback(const struct ico_uws_context *context, const ico_uws_evt_e reason, + const void *id, const ico_uws_detail *detail, void *user_data) +{ + if (reason == ICO_UWS_EVT_OPEN) { + connect_id = (void *)id; + connected = 1; + } + else if (reason == ICO_UWS_EVT_ERROR) { + fprintf(stderr, "Communication Error[%d]\n", detail->_ico_uws_error.code); + } + /* do nothing */ +} + +static void +init_comm(const int port, const char *spadr) +{ + int rep; + char uri_name[128]; + + snprintf(uri_name, sizeof(uri_name), "ws://%s:%d", spadr, port); + connected = 0; + context = ico_uws_create_context(uri_name, LWS_PROTOCOLNAME); + if (context == NULL) { + fprintf(stderr, "Can not create conextion context(uri=%s port=%d)\n", + uri_name, port); + exit(2); + } + ico_uws_set_event_cb(context, uws_callback, NULL); + + /* wait for connection */ + for (rep = 0; rep < (2*1000); rep += 50) { + if (connected) break; + ico_uws_service(context); + } +} + +static void +set_vehicleinfo(const char *cmd) +{ + int i, j; + int idx, key, pt; + int msgsize; + short *sp; + int *ip; + double *dp; + char prop[64]; + char value[128]; + int sec, msec; + struct { + struct KeyDataMsg_t msg; + char dummy[128]; + } msg; + + j = 0; + for (i = 0; cmd[i]; i++) { + if ((cmd[i] == '=') || (cmd[i] == ' ')) break; + if (j < (int)(sizeof(prop)-1)) { + prop[j++] = cmd[i]; + } + } + + prop[j] = 0; + j = 0; + if (cmd[i] != 0) { + for (i++; cmd[i]; i++) { + if (cmd[i] == ' ') continue; + if (j < (int)(sizeof(value)-1)) { + value[j++] = cmd[i]; + } + } + } + value[j] = 0; + + if (strcasecmp(prop, "sleep") == 0) { + sec = 0; + msec = 0; + for (i = 0; value[i]; i++) { + if (value[i] == '.') break; + sec = sec * 10 + (value[i] & 0x0f); + } + if (value[i] == '.') { + i++; + if (value[i] != 0) { + msec = (value[i] & 0x0f) * 100; + i++; + } + if (value[i] != 0) { + msec = msec + (value[i] & 0x0f) * 10; + i++; + } + if (value[i] != 0) { + msec = msec + (value[i] & 0x0f); + } + } + if (sec > 0) sleep(sec); + if (msec > 0) usleep(msec * 1000); + + return; + } + + for (key = 0; vehicleinfo_key[key].prop[0]; key++) { + if (strcasecmp(prop, vehicleinfo_key[key].prop) == 0) break; + } + if (! vehicleinfo_key[key].prop[0]) { + fprintf(stderr, "VehicleInfo UnKnown property[%s]\n", prop); + return; + } + + memset(&msg, 0, sizeof(msg)); + strcpy(msg.msg.KeyEventType, vehicleinfo_key[key].eventtype); + gettimeofday(&(msg.msg.recordtime), NULL); + msgsize = sizeof(msg) - 128; + + i = 0; + pt = 0; + for (idx = 0; idx < 4; idx++) { + if (vehicleinfo_key[key].datatype[idx] == TYPE_NULL) break; + + if (value[i]) { + for (j = i; value[j]; j++) { + if ((value[j] == ',') || (value[j] == ';') || + (value[j] == ':') || (value[j] == ' ')) break; + } + if (value[j] != 0) { + value[j++] = 0; + } + switch (vehicleinfo_key[key].datatype[idx] % 10) { + case TYPE_BOOL: + case TYPE_BYTE: + if (vehicleinfo_key[key].datatype[idx] == TYPE_SHIFT) { + if ((strcasecmp(&value[i], "sp") == 0) || + (strcasecmp(&value[i], "s0") == 0)) { + strcpy(&value[i], "0"); + } + else if (strcasecmp(&value[i], "sr") == 0) { + strcpy(&value[i], "1"); + } + else if (strcasecmp(&value[i], "sn") == 0) { + strcpy(&value[i], "2"); + } + else if ((strcasecmp(&value[i], "sd") == 0) || + (strcasecmp(&value[i], "s4") == 0)) { + strcpy(&value[i], "4"); + } + else if ((strcasecmp(&value[i], "s1") == 0) || + (strcasecmp(&value[i], "sl") == 0)) { + strcpy(&value[i], "5"); + } + else if (strcasecmp(&value[i], "s2") == 0) { + strcpy(&value[i], "6"); + } + else if (strcasecmp(&value[i], "s3") == 0) { + strcpy(&value[i], "7"); + } + } + msg.msg.data.status[pt++] = strtoul(&value[i], (char **)0, 0); + msgsize += 1; + break; + case TYPE_INT16: + case TYPE_UINT16: + sp = (short *)&msg.msg.data.status[pt]; + *sp = strtol(&value[i], (char **)0, 0); + pt += sizeof(short); + msgsize += sizeof(short); + break; + case TYPE_INT32: + case TYPE_UINT32: + ip = (int *)&msg.msg.data.status[pt]; + *ip = strtol(&value[i], (char **)0, 0); + pt += sizeof(int); + msgsize += sizeof(int); + break; + case TYPE_DOUBLE: + dp = (double *)&msg.msg.data.status[pt]; + *dp = strtod(&value[i], (char **)0); + pt += sizeof(double); + msgsize += sizeof(double); + break; + default: + break; + } + i = j; + } + else { + switch (vehicleinfo_key[key].datatype[idx]) { + case TYPE_BOOL: + case TYPE_BYTE: + msgsize += 1; + break; + case TYPE_INT16: + case TYPE_UINT16: + msgsize += sizeof(short); + break; + case TYPE_INT32: + case TYPE_UINT32: + msgsize += sizeof(int); + break; + case TYPE_DOUBLE: + msgsize += sizeof(double); + break; + default: + break; + } + } + } + + ico_uws_send(context, connect_id, (unsigned char *)&msg, msgsize); +} + +static void +usage(const char *prog) +{ + fprintf(stderr, "Usage: %s [-port=port] [-ip=ip_addr] [propaty=value] [propaty=value] ...\n", prog); + exit(0); +} + +int +main(int argc, char *argv[]) +{ + int i, j; + int port = LWS_DEFAULTPORT; + char spadr[64]; + char buf[240]; + + strcpy(spadr, LWS_DEFAULTIP); + + j = 0; + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + if (strncasecmp(argv[i], "-port=", 6) == 0) { + port = strtoul(&argv[i][6], (char **)0, 0); + } + else if (strncasecmp(argv[i], "-ip=", 4) == 0) { + memset(spadr, 0, sizeof(spadr)); + strncpy(spadr, &argv[i][4], sizeof(spadr)-1); + } + else { + usage(argv[0]); + } + } + else { + j++; + } + } + + init_comm(port, spadr); + + if (j <= 0) { + while (fgets(buf, sizeof(buf), stdin)) { + j = -1; + for (i = 0; buf[i]; i++) { + if ((buf[i] == '#') || (buf[i] == '\n') || (buf[i] == '\r')) break; + if (buf[i] == '\t') buf[i] = ' '; + if ((j < 0) && (buf[i] != ' ')) j = i; + } + if (j < 0) continue; + buf[i] = 0; + set_vehicleinfo(&buf[j]); + } + } + else { + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') continue; + set_vehicleinfo(argv[i]); + } + } + if (context) { + ico_uws_unset_event_cb(context); + ico_uws_close(context); + } + + exit(0); +} + -- 2.7.4