diff options
author | asanoaozora <fifitaneki@hotmail.com> | 2018-05-30 16:40:00 +0200 |
---|---|---|
committer | asanoaozora <fifitaneki@hotmail.com> | 2018-05-30 16:40:00 +0200 |
commit | a3fbfa55230fa64d499a6b7a4da6d8b4fa468230 (patch) | |
tree | 37d50fd2278d6646447c261ee61d74ba96160da1 | |
parent | a4938ffa0e6d15aed58645f57b2645bc0a61527a (diff) | |
download | navigation-a3fbfa55230fa64d499a6b7a4da6d8b4fa468230.tar.gz |
some improvements to make it easier to maintain
42 files changed, 4891 insertions, 48 deletions
diff --git a/src/.gitignore b/src/.gitignore index 0283a54..0aea0a0 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,6 @@ automotive-message-broker navigation build +bin +lib + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3f1941c..49729a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,7 +7,8 @@ # Author: Philippe Colliot # # Copyright (C) 2014, PCA Peugeot Citroën -# +# Copyright (C) 2018, PSA Groupe +# # License: # This Source Code Form is subject to the terms of the # Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with @@ -42,6 +43,7 @@ message(STATUS "WITH_HTML_MIGRATION = ${WITH_HTML_MIGRATION}") message(STATUS "WITH_VEHICLE_GATEWAY = ${WITH_VEHICLE_GATEWAY}") message(STATUS "WITH_DLT = ${WITH_DLT}") +set(TOP_DIR "${CMAKE_CURRENT_SOURCE_DIR}") set(NAVIGATION_API_DIR "${CMAKE_CURRENT_SOURCE_DIR}/navigation/api") set(POSITIONING_API_DIR "${CMAKE_CURRENT_SOURCE_DIR}/navigation/src/navigation/positioning/enhanced-position-service/dbus/api") set(FUEL_STOP_ADVISOR_API_DIR "${CMAKE_CURRENT_SOURCE_DIR}/fuel-stop-advisor") @@ -97,6 +99,22 @@ else() add_subdirectory(fuel-stop-advisor) endif() +set(ENHANCED_POSITION_SERVICE_GEN_DIR "${CMAKE_BINARY_DIR}/enhanced-position-service/dbus/api") +set(GNSS_SERVICE_API_DIR "${PROJECT_SOURCE_DIR}/navigation/src/navigation/positioning/gnss-service/api") +set(GNSS_SERVICE_LIBRARY_DIR "${TOP_DIR}/lib") +set(GNSS_SERVICE_LIBRARIES "gnss-service") +set(SENSORS_SERVICE_API_DIR "${PROJECT_SOURCE_DIR}/navigation/src/navigation/positioning/sensors-service/api") +set(SENSORS_SERVICE_LIBRARY_DIR "${TOP_DIR}/lib") +set(SENSORS_SERVICE_LIBRARIES "sensors-service") + +add_subdirectory(sensors-service) + +add_subdirectory(gnss-service) + +add_subdirectory(dead-reckoning) + +add_subdirectory(log-replayer-server) + add_subdirectory(genivilogreplayer) add_subdirectory(hmi) diff --git a/src/dead-reckoning/CMakeLists.txt b/src/dead-reckoning/CMakeLists.txt new file mode 100644 index 0000000..4f5eb18 --- /dev/null +++ b/src/dead-reckoning/CMakeLists.txt @@ -0,0 +1,78 @@ +########################################################################### +# @licence app begin@ +# SPDX-License-Identifier: MPL-2.0 +# +# Component Name: EnhancedPositionService +# +# Author: Marco Residori +# +# Copyright (C) 2014, XS Embedded GmbH +# Copyright (C) 2018, PSA Groupe +# +# License: +# This Source Code Form is subject to the terms of the +# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +# this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# Update (2014/12/02) : Philippe Colliot <philippe.colliot@mpsa.com>, +# PSA Peugeot Citroen +# - introduce debug flag to disable verbosity +# Update (2018/05/30) : Philippe Colliot <philippe.colliot@mpsa.com>, +# PSA Groupe +# - adaptation of former version to introduce dead reckoning +# @licence end@ +########################################################################### +project(dead-reckoning) + +message(STATUS ${PROJECT_NAME}) + +add_definitions("-std=gnu++11") + +find_package(PkgConfig REQUIRED) + +pkg_check_modules(DBUS_CPP dbus-c++-1) + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${TOP_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${TOP_DIR}/bin) + +include_directories( + ${ENHANCED_POSITION_SERVICE_GEN_DIR} + ${DBUS_CPP_INCLUDE_DIRS} + ${GNSS_SERVICE_API_DIR} + ${SENSORS_SERVICE_API_DIR}) + +link_directories( + ${DBUS_CPP_LIBRARY_DIRS} + ${GNSS_SERVICE_LIBRARY_DIR} + ${SENSORS_SERVICE_LIBRARY_DIR}) + +add_executable(${PROJECT_NAME} + main.cpp + enhanced-position.cpp + enhanced-position.h + position-feedback.cpp + position-feedback.h + configuration.cpp + configuration.h +) + +set(LIBRARIES + ${DBUS_CPP_LIBRARIES} + ${GNSS_SERVICE_LIBRARIES} + ${SENSORS_SERVICE_LIBRARIES} +) + +if(WITH_DLT) + add_definitions("-DDLT_ENABLED=1") + pkg_check_modules(DLT REQUIRED automotive-dlt) + include_directories( ${DLT_INCLUDE_DIRS} ) + set(LIBRARIES ${LIBRARIES} ${DLT_LIBRARIES}) +endif() + +if(WITH_DEBUG) + add_definitions("-DDEBUG_ENABLED=1") +endif() + +target_link_libraries(${PROJECT_NAME} ${LIBRARIES}) + +install(TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/src/dead-reckoning/configuration.cpp b/src/dead-reckoning/configuration.cpp new file mode 100644 index 0000000..1316a5f --- /dev/null +++ b/src/dead-reckoning/configuration.cpp @@ -0,0 +1,208 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup EnhancedPositionService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2014, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "configuration.h" +#include "positioning-constants.h" +#include "log.h" +#include "gnss.h" + +DLT_IMPORT_CONTEXT(gCtx); + +static DBus::Variant variant_uint16(uint16_t i) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << i; + return variant; +} + +static DBus::Variant variant_int32(int32_t i) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << i; + return variant; +} + +static DBus::Variant variant_uint32(uint32_t i) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << i; + return variant; +} + +static DBus::Variant variant_array_uint16(std::vector< uint16_t > i) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << i; + return variant; +} + +static DBus::Variant variant_array_int32(std::vector< int32_t > i) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << i; + return variant; +} + +static DBus::Variant variant_array_uint32(std::vector< uint32_t > i) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << i; + return variant; +} + +Configuration::Configuration(DBus::Connection &connection, const char * path) +: DBus::ObjectAdaptor(connection, path) +, mUpdateInterval(1000) +, mSatelliteSystem(GENIVI_ENHANCEDPOSITIONSERVICE_GPS) +{ +} + +Configuration::~Configuration() +{ +} + +::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > Configuration::GetVersion() +{ + ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > Version; + + Version._1 = 4; + Version._2 = 0; + Version._3 = 0; + Version._4 = std::string("28-10-2015alpha"); + + return Version; +} + +std::map< std::string, ::DBus::Variant > Configuration::GetProperties() +{ + std::map< std::string, ::DBus::Variant > Properties; + + Properties["UpdateInterval"] = variant_int32(mUpdateInterval); + Properties["SatelliteSystem"] = variant_uint32(mSatelliteSystem); + + return Properties; +} + +void Configuration::SetProperty(const std::string& name, const ::DBus::Variant& value) +{ + if(name == "UpdateInterval") + { + mUpdateInterval = value; + + LOG_INFO(gCtx,"UpdateInterval = %d", mUpdateInterval); + + PropertyChanged("UpdateInterval", value); + } + + if(name == "SatelliteSystem") + { + uint32_t requestedSystems = value; //magic conversion variant -> uint32_t + uint32_t activateSystems = 0; + if (requestedSystems & GENIVI_ENHANCEDPOSITIONSERVICE_GPS) + { + activateSystems |= GNSS_SYSTEM_GPS; + } + if (requestedSystems & GENIVI_ENHANCEDPOSITIONSERVICE_GLONASS) + { + activateSystems |= GNSS_SYSTEM_GLONASS; + } + if (requestedSystems & GENIVI_ENHANCEDPOSITIONSERVICE_GALILEO) + { + activateSystems |= GNSS_SYSTEM_GALILEO; + } + if (requestedSystems & GENIVI_ENHANCEDPOSITIONSERVICE_GPS) + { + activateSystems |= GNSS_SYSTEM_BEIDOU; + } + gnssSetGNSSSystems(activateSystems); + + //For a real implementation the property should only be changed + //when the the configuration request has become effective as reported + //by the TGNSSPosition.activatedSystems from the GNSSPositionCallback. + //As currently the GNSS PoC has only dummy implementations of + //gnssConfigGNSSSystems(), the property change is triggered immediately + //for demonstration purposes. + mSatelliteSystem = value; + LOG_INFO(gCtx,"SatelliteSystem = %d", mSatelliteSystem); + PropertyChanged("SatelliteSystem", value); + } + +} + +std::map< std::string, ::DBus::Variant > Configuration::GetSupportedProperties() +{ + std::map< std::string, ::DBus::Variant > SupportedProperties; + + std::vector< int32_t > updateIntervals; + updateIntervals.push_back(1000); + updateIntervals.push_back(1500); + + uint32_t supportedSystems; + TGNSSConfiguration gnssConfig = {0}; + + if (gnssGetConfiguration(&gnssConfig) && (gnssConfig.validityBits & GNSS_CONFIG_SATSYS_VALID)) + { //assume GPS at least + supportedSystems = gnssConfig.supportedSystems; + } + else + { //assume GPS at least + supportedSystems = GNSS_SYSTEM_GPS; + } + + //test hack: add GLONASS to have 2 systems + supportedSystems = supportedSystems|GNSS_SYSTEM_GLONASS; + + std::vector< uint32_t > satelliteSystems; + if (supportedSystems & GNSS_SYSTEM_GPS) + { + satelliteSystems.push_back(GENIVI_ENHANCEDPOSITIONSERVICE_GPS); + } + if (supportedSystems & GNSS_SYSTEM_GLONASS) + { + satelliteSystems.push_back(GENIVI_ENHANCEDPOSITIONSERVICE_GLONASS); + } + if (supportedSystems & GNSS_SYSTEM_GALILEO) + { + satelliteSystems.push_back(GENIVI_ENHANCEDPOSITIONSERVICE_GALILEO); + } + if (supportedSystems & GNSS_SYSTEM_BEIDOU) + { + satelliteSystems.push_back(GENIVI_ENHANCEDPOSITIONSERVICE_COMPASS); + } + + SupportedProperties["UpdateInterval"] = variant_array_int32(updateIntervals); + SupportedProperties["SatelliteSystem"] = variant_array_uint32(satelliteSystems); + + return SupportedProperties; +} + +void Configuration::run() +{ + LOG_INFO_MSG(gCtx,"Starting Configuration dispatcher..."); +} + +void Configuration::shutdown() +{ + LOG_INFO_MSG(gCtx,"Shutting down Configuration dispatcher..."); +} diff --git a/src/dead-reckoning/configuration.h b/src/dead-reckoning/configuration.h new file mode 100644 index 0000000..e9f23f8 --- /dev/null +++ b/src/dead-reckoning/configuration.h @@ -0,0 +1,56 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup EnhancedPositionService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2014, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ +#ifndef ___CONFIGURATION_H +#define ___CONFIGURATION_H + +#ifndef DBUS_HAS_RECURSIVE_MUTEX +#define DBUS_HAS_RECURSIVE_MUTEX +#endif +#include <dbus-c++/dbus.h> +#include "configuration-adaptor.h" + +class Configuration + : public org::genivi::positioning::Configuration_adaptor + , public DBus::IntrospectableAdaptor + , public DBus::ObjectAdaptor +{ +public: + + Configuration(DBus::Connection &connection, const char * path); + + ~Configuration(); + + ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > GetVersion(); + + std::map< std::string, ::DBus::Variant > GetProperties(); + + void SetProperty(const std::string& name, const ::DBus::Variant& value); + + std::map< std::string, ::DBus::Variant > GetSupportedProperties(); + + void run(); + + void shutdown(); + +private: + + int32_t mUpdateInterval; + uint32_t mSatelliteSystem; +}; + +#endif//__CONFIGURATION_H diff --git a/src/dead-reckoning/enhanced-position.cpp b/src/dead-reckoning/enhanced-position.cpp new file mode 100644 index 0000000..ab9c34d --- /dev/null +++ b/src/dead-reckoning/enhanced-position.cpp @@ -0,0 +1,447 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup EnhancedPositionService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2014, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include "enhanced-position.h" +#include "positioning-constants.h" +#include "log.h" + +DLT_IMPORT_CONTEXT(gCtx); + +EnhancedPosition* EnhancedPosition::mpSelf = 0; + +static DBus::Variant variant_double(double d) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << d; + return variant; +} + +static DBus::Variant variant_uint16(uint16_t i) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << i; + return variant; +} + +static DBus::Variant variant_int32(int32_t i) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << i; + return variant; +} + +static DBus::Variant variant_uint32(uint32_t i) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << i; + return variant; +} + +static DBus::Variant variant_string(std::string s) +{ + DBus::Variant variant; + DBus::MessageIter iter=variant.writer(); + iter << s; + return variant; +} + +EnhancedPosition::EnhancedPosition(DBus::Connection & connection, const char * path) + : DBus::ObjectAdaptor(connection, path) +{ + mpSelf = this; +} + +EnhancedPosition::~EnhancedPosition() +{ + mpSelf = 0; +} + +::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > EnhancedPosition::GetVersion() +{ + ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > Version; + + Version._1 = 4; + Version._2 = 0; + Version._3 = 0; + Version._4 = std::string("25-04-2016"); + + return Version; +} + + + +void EnhancedPosition::GetPositionInfo(const uint64_t& valuesToReturn, uint64_t& timestamp, std::map< uint64_t, ::DBus::Variant >& data) +{ + //std::map< uint64_t, ::DBus::Variant > Data; + + TGNSSPosition position; + + bool isPosRequested = false; + bool isCourseRequested = false; + + if ((valuesToReturn & GENIVI_ENHANCEDPOSITIONSERVICE_LATITUDE) || + (valuesToReturn & GENIVI_ENHANCEDPOSITIONSERVICE_LONGITUDE) || + (valuesToReturn & GENIVI_ENHANCEDPOSITIONSERVICE_ALTITUDE)) + { + isPosRequested = true; + } + + if ((valuesToReturn & GENIVI_ENHANCEDPOSITIONSERVICE_HEADING) || + (valuesToReturn & GENIVI_ENHANCEDPOSITIONSERVICE_SPEED) || + (valuesToReturn & GENIVI_ENHANCEDPOSITIONSERVICE_CLIMB )) + { + isCourseRequested = true; + } + + if(gnssGetPosition(&position)) + { + + timestamp = position.timestamp; + + if(isPosRequested) + { + if (position.validityBits & GNSS_POSITION_LATITUDE_VALID) + { + data[GENIVI_ENHANCEDPOSITIONSERVICE_LATITUDE] = variant_double(position.latitude); + } + + if (position.validityBits & GNSS_POSITION_LONGITUDE_VALID) + { + data[GENIVI_ENHANCEDPOSITIONSERVICE_LONGITUDE] = variant_double(position.longitude); + } + + if (position.validityBits & GNSS_POSITION_ALTITUDEMSL_VALID) + { + data[GENIVI_ENHANCEDPOSITIONSERVICE_ALTITUDE] = variant_double(position.altitudeMSL); + } + } + + if(isCourseRequested) + { + if (position.validityBits & GNSS_POSITION_HEADING_VALID) + { + data[GENIVI_ENHANCEDPOSITIONSERVICE_HEADING] = variant_double(position.heading); + } + + if (position.validityBits & GNSS_POSITION_HSPEED_VALID) + { + data[GENIVI_ENHANCEDPOSITIONSERVICE_SPEED] = variant_double(position.hSpeed); + } + + if (position.validityBits & GNSS_POSITION_VSPEED_VALID) + { + data[GENIVI_ENHANCEDPOSITIONSERVICE_CLIMB] = variant_double(position.vSpeed); + } + } + } + + //always provide some status information + if (position.validityBits & GNSS_POSITION_STAT_VALID) + { + data[GENIVI_ENHANCEDPOSITIONSERVICE_GNSS_FIX_STATUS] = variant_uint16(position.fixStatus); + } + if (position.validityBits & GNSS_POSITION_USYS_VALID) + { + data[GENIVI_ENHANCEDPOSITIONSERVICE_USED_SATELLITESYSTEMS] = variant_uint32(position.usedSystems); + } + + +} + + + +void EnhancedPosition::GetSatelliteInfo(uint64_t& timestamp, std::vector< ::DBus::Struct< uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, bool > >& satelliteInfo) +{ + throw DBus::ErrorNotSupported("Method not supported yet"); +} + +void EnhancedPosition::GetTime(uint64_t& timestamp, std::map< uint64_t, ::DBus::Variant >& time) +{ + throw DBus::ErrorNotSupported("Method not supported yet"); +} + +void EnhancedPosition::sigPositionUpdate(const TGNSSPosition position[], uint16_t numElements) +{ + bool latChanged = false; + bool lonChanged = false; + bool altChanged = false; + bool speedChanged = false; + bool headingChanged = false; + bool climbChanged = false; + bool pdopChanged = false; + bool hdopChanged = false; + bool vdopChanged = false; + bool usatChanged = false; //used satellites + bool fixStatusChanged = false; + bool fixTypeBitsChanged = false; + bool usedSystemsChanged = false; + + uint64_t changedValues = 0; + + if (position == NULL || numElements < 1) + { + LOG_ERROR_MSG(gCtx,"sigPositionUpdate failed!"); + return; + } + + for (int i = 0; i< numElements; i++) + { + + if (latChanged == false) + { + latChanged = (position[i].validityBits & GNSS_POSITION_LATITUDE_VALID); + } + + if (lonChanged == false) + { + lonChanged = (position[i].validityBits & GNSS_POSITION_LONGITUDE_VALID); + } + + if (altChanged == false) + { + altChanged = (position[i].validityBits & GNSS_POSITION_ALTITUDEMSL_VALID); + } + + if (speedChanged == false) + { + speedChanged = (position[i].validityBits & GNSS_POSITION_HSPEED_VALID); + } + + if (headingChanged == false) + { + headingChanged = (position[i].validityBits & GNSS_POSITION_HEADING_VALID); + } + + if (climbChanged == false) + { + climbChanged = (position[i].validityBits & GNSS_POSITION_VSPEED_VALID); + } + + if (pdopChanged == false) + { + pdopChanged = (position[i].validityBits & GNSS_POSITION_PDOP_VALID); + } + + if (hdopChanged == false) + { + hdopChanged = (position[i].validityBits & GNSS_POSITION_HDOP_VALID); + } + + if (vdopChanged == false) + { + vdopChanged = (position[i].validityBits & GNSS_POSITION_VDOP_VALID); + } + + if (usatChanged == false) + { + usatChanged = (position[i].validityBits & GNSS_POSITION_USAT_VALID); + } + + if (fixStatusChanged == false) + { + fixStatusChanged = (position[i].validityBits & GNSS_POSITION_STAT_VALID); + } + + if (fixTypeBitsChanged == false) + { + fixTypeBitsChanged = (position[i].validityBits & GNSS_POSITION_TYPE_VALID); + } + + if (usedSystemsChanged == false) + { + usedSystemsChanged = (position[i].validityBits & GNSS_POSITION_USYS_VALID); + } + } + + + //in a real product, the coordinates would be used for dead-reckoning. + //in this proof of concept, the client application is simply notified + //about changes of latitude, longitude and/or altitude + + if (latChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_LATITUDE; + } + + if (lonChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_LONGITUDE; + } + + if (altChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_ALTITUDE; + } + + if (speedChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_SPEED; + } + + if (headingChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_HEADING; + } + + if (climbChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_CLIMB; + } + + if (pdopChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_PDOP; + } + + if (hdopChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_HDOP; + } + + if (vdopChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_VDOP; + } + + if (usatChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_USED_SATELLITES; + } + + if (fixStatusChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_GNSS_FIX_STATUS; + } + + if (usedSystemsChanged) + { + changedValues |= GENIVI_ENHANCEDPOSITIONSERVICE_USED_SATELLITESYSTEMS; + } + + if (!mpSelf) + { + LOG_ERROR_MSG(gCtx,"Null pointer!"); + return; + } + + //notify clients + mpSelf->PositionUpdate(changedValues); + +} + + +void EnhancedPosition::cbPosition(const TGNSSPosition position[], uint16_t numElements) +{ + sigPositionUpdate(position, numElements); +} + + +void EnhancedPosition::cbSatelliteDetail(const TGNSSSatelliteDetail satelliteDetail[], uint16_t numElements) +{ + if (satelliteDetail == NULL || numElements < 1) + { + LOG_ERROR_MSG(gCtx,"cbSatelliteDetail failed!"); + return; + } + + for (int i = 0; i<numElements; i++) + { + LOG_INFO(gCtx,"SatelliteDetail Update[%d/%d]: satelliteId=%d azimuth=%d elevation=%d CNo=%d", + i+1, + numElements, + satelliteDetail[i].satelliteId, + satelliteDetail[i].azimuth, + satelliteDetail[i].elevation, + satelliteDetail[i].CNo); + } + + if (!mpSelf) + { + LOG_ERROR_MSG(gCtx,"Null pointer!"); + return; + } + + //todo: notify clients + //mpSelf->SatelliteInfoUpdate(changedValues); +} + +void EnhancedPosition::cbAcceleration(const TAccelerationData accelerationData[], uint16_t numElements) +{ + LOG_INFO_MSG(gCtx,"Acceleration..."); + for (int i = 0; i<numElements; i++) + { + LOG_INFO(gCtx,"Acceleration Update[%d/%d]: x=%d y=%d z=%d temperature=%d measurementInterval=%d validityBits=%d", + i+1, + numElements, + accelerationData[i].x, + accelerationData[i].y, + accelerationData[i].z, + accelerationData[i].temperature, + accelerationData[i].measurementInterval, + accelerationData[i].validityBits); + } +} + +void EnhancedPosition::cbGyroscope(const TGyroscopeData gyroData[], uint16_t numElements) +{ + LOG_INFO_MSG(gCtx,"Gyroscope..."); + for (int i = 0; i<numElements; i++) + { + LOG_INFO(gCtx,"Gyroscope Update[%d/%d]: yawRate=%d pitchRate=%d rollRate=%d temperature=%d measurementInterval=%d validityBits=%d", + i+1, + numElements, + gyroData[i].yawRate, + gyroData[i].pitchRate, + gyroData[i].rollRate, + gyroData[i].temperature, + gyroData[i].measurementInterval, + gyroData[i].validityBits); + } +} + +void EnhancedPosition::run() +{ + LOG_INFO_MSG(gCtx,"Starting EnhancedPosition dispatcher..."); + + if (!gnssRegisterPositionCallback(&cbPosition)) + LOG_ERROR_MSG(gCtx,"Position Callback not registered"); + if (!gnssRegisterSatelliteDetailCallback(&cbSatelliteDetail)) + LOG_ERROR_MSG(gCtx,"SatelliteDetail Callback not registered"); + if (!snsGyroscopeRegisterCallback(&cbGyroscope)) + LOG_ERROR_MSG(gCtx,"Gyroscope Callback not registered"); + if (!snsAccelerationRegisterCallback(&cbAcceleration)) + LOG_ERROR_MSG(gCtx,"Acceleration Callback not registered"); +} + +void EnhancedPosition::shutdown() +{ + LOG_INFO_MSG(gCtx,"Shutting down EnhancedPosition dispatcher..."); + + gnssDeregisterPositionCallback(&cbPosition); + gnssDeregisterSatelliteDetailCallback(&cbSatelliteDetail); + snsGyroscopeDeregisterCallback(&cbGyroscope); + snsAccelerationDeregisterCallback(&cbAcceleration); +} + + diff --git a/src/dead-reckoning/enhanced-position.h b/src/dead-reckoning/enhanced-position.h new file mode 100644 index 0000000..8dabe7e --- /dev/null +++ b/src/dead-reckoning/enhanced-position.h @@ -0,0 +1,65 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup EnhancedPositionService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2014, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ +#ifndef ___ENHANCED_POSITION_H +#define ___ENHANCED_POSITION_H + +#ifndef DBUS_HAS_RECURSIVE_MUTEX +#define DBUS_HAS_RECURSIVE_MUTEX +#endif +#include <dbus-c++/dbus.h> + +#include "enhanced-position-adaptor.h" +#include "gnss-init.h" +#include "gnss.h" +#include "acceleration.h" +#include "gyroscope.h" + +class EnhancedPosition + : public org::genivi::positioning::EnhancedPosition_adaptor + , public DBus::IntrospectableAdaptor + , public DBus::ObjectAdaptor +{ +public: + + EnhancedPosition(DBus::Connection & connection, const char * path); + + ~EnhancedPosition(); + + ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > GetVersion(); + + void GetPositionInfo(const uint64_t& valuesToReturn, uint64_t& timestamp, std::map< uint64_t, ::DBus::Variant >& data); + void GetSatelliteInfo(uint64_t& timestamp, std::vector< ::DBus::Struct< uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, bool > >& satelliteInfo); + void GetTime(uint64_t& timestamp, std::map< uint64_t, ::DBus::Variant >& time); + + void run(); + + void shutdown(); + +private: + + static void cbSatelliteDetail(const TGNSSSatelliteDetail satelliteDetail[], uint16_t numElements); + static void cbPosition(const TGNSSPosition position[], uint16_t numElements); + static void cbAcceleration(const TAccelerationData accelerationData[], uint16_t numElements); + static void cbGyroscope(const TGyroscopeData gyroData[], uint16_t numElements); + + static void sigPositionUpdate(const TGNSSPosition position[], uint16_t numElements); + + static EnhancedPosition* mpSelf; +}; + +#endif//__ENHANCED_POSITION_H diff --git a/src/dead-reckoning/log.h b/src/dead-reckoning/log.h new file mode 100644 index 0000000..4d946fb --- /dev/null +++ b/src/dead-reckoning/log.h @@ -0,0 +1,154 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup GNSSService +* +* \copyright Copyright (C) BMW Car IT GmbH 2011 +* Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#ifndef INCLUDE_LOG +#define INCLUDE_LOG + +// turn-on via cmake define: +// $ cmake -DWITH_DLT=1 -DDEBUG_ENABLED=1 .. + +#if (!DLT_ENABLED) +/*****************************************************************************/ +// use printf +#include <stdio.h> + +// some type-name used instead of DLT context +typedef const char* NoDltContext; + +#define DLT_DECLARE_CONTEXT(CONTEXT) \ + NoDltContext CONTEXT; + +#define DLT_IMPORT_CONTEXT(CONTEXT) \ + extern NoDltContext CONTEXT; + +#define DLT_REGISTER_CONTEXT(CONTEXT, CONTEXT_ID, DESC) \ + CONTEXT = CONTEXT_ID; + +#define DLT_REGISTER_APP(CONTEXT, DESC) ; + +#define DLT_UNREGISTER_CONTEXT(CONTEXT) ; +#define DLT_UNREGISTER_APP() ; +#define dlt_free() ; + +// log calls +#if (!DEBUG_ENABLED) + +#define LOG_VERBOSE_MSG(context, msg) ; +#define LOG_VERBOSE(context, fmt, ...) ; + +#define LOG_DEBUG_MSG(context, msg) ; +#define LOG_DEBUG(context, fmt, ...) ; + +#define LOG_INFO_MSG(context, msg) ; +#define LOG_INFO(context, fmt, ...) ; + +#define LOG_WARNING_MSG(context, msg) ; +#define LOG_WARNING(context, fmt, ...) ; + +#else + +#define LOG_VERBOSE_MSG(context, msg) \ + fprintf(stderr, "[VERBO][%4s] " msg "\n", context) +#define LOG_VERBOSE(context, fmt, ...) \ + fprintf(stderr, "[VERBO][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_DEBUG_MSG(context, msg) \ + fprintf(stderr, "[DEBUG][%4s] " msg "\n", context) +#define LOG_DEBUG(context, fmt, ...) \ + fprintf(stderr, "[DEBUG][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_INFO_MSG(context, msg) \ + fprintf(stderr, "[INFO ][%4s] " msg "\n", context) +#define LOG_INFO(context, fmt, ...) \ + fprintf(stderr, "[INFO ][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_WARNING_MSG(context, msg) \ + fprintf(stderr, "[WARN ][%4s] " msg "\n", context) +#define LOG_WARNING(context, fmt, ...) \ + fprintf(stderr, "[WARN ][%4s] " fmt "\n", context, __VA_ARGS__) +#endif + +#define LOG_ERROR_MSG(context, msg) \ + fprintf(stderr, "[ERROR][%4s] " msg "\n", context) +#define LOG_ERROR(context, fmt, ...) \ + fprintf(stderr, "[ERROR][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_FATAL_MSG(context, msg) \ + fprintf(stderr, "[FATAL][%4s] " msg "\n", context) +#define LOG_FATAL(context, fmt, ...) \ + fprintf(stderr, "[FATAL][%4s] " fmt "\n", context, __VA_ARGS__) + +#else /* DLT_ENABLED */ +/*****************************************************************************/ +// use DLT +#include "dlt.h" + +typedef const char* Context; + +#define LOG_VERBOSE_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_VERBOSE, DLT_STRING(msg)); +#define LOG_VERBOSE(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_VERBOSE, DLT_STRING(logBuffer)); \ + } +#define LOG_DEBUG_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_DEBUG, DLT_STRING(msg)); +#define LOG_DEBUG(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_DEBUG, DLT_STRING(logBuffer)); \ + } +#define LOG_INFO_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_INFO, DLT_STRING(msg)); +#define LOG_INFO(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_INFO, DLT_STRING(logBuffer)); \ + } +#define LOG_WARNING_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_WARN, DLT_STRING(msg)); +#define LOG_WARNING(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_WARN, DLT_STRING(logBuffer)); \ + } +#define LOG_ERROR_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_ERROR, DLT_STRING(msg)); +#define LOG_ERROR(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_ERROR, DLT_STRING(logBuffer)); \ + } +#define LOG_FATAL_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_FATAL, DLT_STRING(msg)); +#define LOG_FATAL(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_FATAL, DLT_STRING(logBuffer)); \ + } + +#endif /* DLT_ENABLED */ + +#endif /* INCLUDE_LOG */ diff --git a/src/dead-reckoning/main.cpp b/src/dead-reckoning/main.cpp new file mode 100644 index 0000000..173f299 --- /dev/null +++ b/src/dead-reckoning/main.cpp @@ -0,0 +1,118 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup EnhancedPositionService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2014, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include <signal.h> +#ifndef DBUS_HAS_RECURSIVE_MUTEX +#define DBUS_HAS_RECURSIVE_MUTEX +#endif +#include <dbus-c++/dbus.h> + +#include "enhanced-position.h" +#include "position-feedback.h" +#include "configuration.h" +#include "log.h" +#include "gnss.h" +#include "gnss-init.h" + +const char* ENHANCED_POSITION_SERVICE_NAME = "org.genivi.positioning.EnhancedPosition"; +const char* ENHANCED_POSITION_OBJECT_PATH = "/org/genivi/positioning/EnhancedPosition"; +const char* POSITION_FEEDBACK_OBJECT_PATH = "/org/genivi/positioning/PositionFeedback"; +const char* CONFIGURATION_OBJECT_PATH = "/org/genivi/positioning/Configuration"; + +DLT_DECLARE_CONTEXT(gCtx); + +DBus::BusDispatcher dispatcher; + +static DBus::Connection *conn; + +void sighandler(int sig) +{ + LOG_INFO_MSG(gCtx,"Signal received"); + + dispatcher.leave(); +} + +bool checkGNSSMajorVersion(int expectedMajor) +{ + int major = -1; + + gnssGetVersion(&major, 0, 0); + + if (major != expectedMajor) + { + LOG_ERROR(gCtx,"Wrong API version: gnssGetVersion returned unexpected value %d != %d", + major, + expectedMajor); + + return false; + } + + return true; +} + +int main() +{ + DLT_REGISTER_APP("ENHP", "EnhancedPositionService"); + DLT_REGISTER_CONTEXT(gCtx,"EPSR", "Global Context"); // EPSR = EnhancedPositionService Server Application + LOG_INFO_MSG(gCtx,"Starting EnhancedPositionService..."); + + signal(SIGTERM, sighandler); + signal(SIGINT, sighandler); + + DBus::default_dispatcher = &dispatcher; + + conn = new DBus::Connection(DBus::Connection::SessionBus()); + + if (conn == NULL) + { + LOG_ERROR_MSG(gCtx,"Null pointer!"); + } + + if(!checkGNSSMajorVersion(GENIVI_GNSS_API_MAJOR)) + { + LOG_ERROR_MSG(gCtx,"Wrong GNSS version - exiting!"); + exit(EXIT_FAILURE); + } + + if(!gnssInit()) + { + LOG_ERROR_MSG(gCtx,"gnssInit failure - exiting!"); + exit(EXIT_FAILURE); + } + + conn->setup(&dispatcher); + conn->request_name(ENHANCED_POSITION_SERVICE_NAME); + + EnhancedPosition EnhancedPositionServer(*conn, ENHANCED_POSITION_OBJECT_PATH); + PositionFeedback PositionFeedbackServer(*conn, POSITION_FEEDBACK_OBJECT_PATH); + Configuration ConfigurationServer(*conn, CONFIGURATION_OBJECT_PATH); + + EnhancedPositionServer.run(); + PositionFeedbackServer.run(); + ConfigurationServer.run(); + + dispatcher.enter(); + + ConfigurationServer.shutdown(); + PositionFeedbackServer.shutdown(); + EnhancedPositionServer.shutdown(); + + gnssDestroy(); + + return 0; +} diff --git a/src/dead-reckoning/position-feedback.cpp b/src/dead-reckoning/position-feedback.cpp new file mode 100644 index 0000000..0538c0c --- /dev/null +++ b/src/dead-reckoning/position-feedback.cpp @@ -0,0 +1,60 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup EnhancedPositionService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2014, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "position-feedback.h" +#include "log.h" + +DLT_IMPORT_CONTEXT(gCtx); + +PositionFeedback::PositionFeedback(DBus::Connection & connection, const char * path) + : DBus::ObjectAdaptor(connection, path) +{ +} + +PositionFeedback::~PositionFeedback() +{ +} + +::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > PositionFeedback::GetVersion() +{ + ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > Version; + + Version._1 = 3; + Version._2 = 0; + Version._3 = 0; + Version._4 = std::string("05-08-2014"); + + return Version; +} + +void PositionFeedback::SetPositionFeedback(const std::vector< std::map< uint64_t, ::DBus::Variant > >& feedback, const uint64_t& timestamp, const uint16_t& feedbackType) +{ + throw DBus::ErrorNotSupported("Method not supported yet"); +} + +void PositionFeedback::run() +{ + LOG_INFO_MSG(gCtx,"Starting PositionFeedback dispatcher..."); +} + +void PositionFeedback::shutdown() +{ + LOG_INFO_MSG(gCtx,"Shutting down PositionFeedback dispatcher..."); +} + + diff --git a/src/dead-reckoning/position-feedback.h b/src/dead-reckoning/position-feedback.h new file mode 100644 index 0000000..5b089a8 --- /dev/null +++ b/src/dead-reckoning/position-feedback.h @@ -0,0 +1,50 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup EnhancedPositionService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2014, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#ifndef ___POSITION_FEEDBACK_H +#define ___POSITION_FEEDBACK_H + +#ifndef DBUS_HAS_RECURSIVE_MUTEX +#define DBUS_HAS_RECURSIVE_MUTEX +#endif +#include <dbus-c++/dbus.h> +#include "position-feedback-adaptor.h" + +class PositionFeedback + : public org::genivi::positioning::PositionFeedback_adaptor + , public DBus::IntrospectableAdaptor + , public DBus::ObjectAdaptor +{ + +public: + + PositionFeedback(DBus::Connection & connection, const char * path); + + ~PositionFeedback(); + + ::DBus::Struct< uint16_t, uint16_t, uint16_t, std::string > GetVersion(); + + void SetPositionFeedback(const std::vector< std::map< uint64_t, ::DBus::Variant > >& feedback, const uint64_t& timestamp, const uint16_t& feedbackType); + + void run(); + + void shutdown(); + +}; + +#endif//___POSITION_FEEDBACK_H diff --git a/src/genivilogreplayer/CMakeLists.txt b/src/genivilogreplayer/CMakeLists.txt index fc871bf..d716c43 100644 --- a/src/genivilogreplayer/CMakeLists.txt +++ b/src/genivilogreplayer/CMakeLists.txt @@ -15,6 +15,10 @@ # # @licence end@ ########################################################################### +project(genivilogreplayerplugin) + +message(STATUS ${PROJECT_NAME}) + cmake_minimum_required(VERSION 2.8) add_definitions("-std=gnu++11") @@ -25,9 +29,9 @@ pkg_search_module(GLIB glib-2.0) set(genivilogreplayer_headers genivilogreplayerplugin.h) set(genivilogreplayer_sources genivilogreplayerplugin.cpp) -add_library(genivilogreplayerplugin MODULE ${genivilogreplayer_sources}) -set_target_properties(genivilogreplayerplugin PROPERTIES PREFIX "") +add_library(${PROJECT_NAME} MODULE ${genivilogreplayer_sources}) +set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") include_directories(${AUTOMOTIVE_MESSAGE_BROKER_SRC_DIR}/lib ${GLIB_INCLUDE_DIRS}) -target_link_libraries(genivilogreplayerplugin amb -L${AUTOMOTIVE_MESSAGE_BROKER_LIB_DIR}) +target_link_libraries(${PROJECT_NAME} amb -L${AUTOMOTIVE_MESSAGE_BROKER_LIB_DIR}) -install(TARGETS genivilogreplayerplugin LIBRARY DESTINATION lib/automotive-message-broker) +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/automotive-message-broker) diff --git a/src/gnss-service/CMakeLists.txt b/src/gnss-service/CMakeLists.txt new file mode 100644 index 0000000..f536a30 --- /dev/null +++ b/src/gnss-service/CMakeLists.txt @@ -0,0 +1,60 @@ +########################################################################### +# @licence app begin@ +# SPDX-License-Identifier: MPL-2.0 +# +# Component Name: GNSSService +# +# Author: Marco Residori +# +# Copyright (C) 2013, XS Embedded GmbH +# Copyright (C) 2018, PSA Groupe +# +# License: +# This Source Code Form is subject to the terms of the +# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +# this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# Update (2014/12/02) : Philippe Colliot <philippe.colliot@mpsa.com>, +# PSA Peugeot Citroen +# - introduce debug flag to disable verbosity +# Update (2018/05/30) : Philippe Colliot <philippe.colliot@mpsa.com>, +# PSA Groupe +# - adaptation of former version to introduce dead reckoning +# @licence end@ +########################################################################### +project(gnss-service) + +message(STATUS ${PROJECT_NAME}) + +add_definitions("-std=gnu++11") + +find_package(PkgConfig REQUIRED) + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${TOP_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${TOP_DIR}/bin) + +include_directories("${GNSS_SERVICE_API_DIR}") + +set(LIBRARIES pthread) + +if(WITH_DLT) + add_definitions("-DDLT_ENABLED=1") + pkg_check_modules(DLT REQUIRED automotive-dlt) + include_directories( ${DLT_INCLUDE_DIRS} ) + set(LIBRARIES ${LIBRARIES} ${DLT_LIBRARIES}) +endif() + +if(WITH_DEBUG) + add_definitions("-DDEBUG_ENABLED=1") +endif() + +#generate library using replayer as input +set(SRC ${CMAKE_CURRENT_SOURCE_DIR}/gnss-use-replayer.c + ${CMAKE_CURRENT_SOURCE_DIR}/gnss-impl.c + ${CMAKE_CURRENT_SOURCE_DIR}/gnss-meta-data.c +) + +add_library(${PROJECT_NAME} SHARED ${SRC}) +target_link_libraries(${PROJECT_NAME} ${LIBRARIES}) +install(TARGETS ${PROJECT_NAME} DESTINATION lib) + diff --git a/src/gnss-service/globals.h b/src/gnss-service/globals.h new file mode 100644 index 0000000..47a233a --- /dev/null +++ b/src/gnss-service/globals.h @@ -0,0 +1,49 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup GNSSService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#ifndef GLOBALS_H +#define GLOBALS_H + +#include <stdbool.h> +#include <pthread.h> +#include <time.h> + +#include "gnss-init.h" +#include "gnss.h" +#include "gnss-meta-data.h" +#include "gnss-status.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const TGnssMetaData gMetaData; + +bool iGnssInit(); +bool iGnssDestroy(); + +void updateGNSSTime(const TGNSSTime time[], uint16_t numElements); +void updateGNSSPosition(const TGNSSPosition position[], uint16_t numElements); +void updateGNSSSatelliteDetail(const TGNSSSatelliteDetail satelliteDetail[], uint16_t numElements); +void updateGNSSStatus(const TGNSSStatus* status); + +#ifdef __cplusplus +} +#endif + +#endif /* GLOBALS_H */ diff --git a/src/gnss-service/gnss-impl.c b/src/gnss-service/gnss-impl.c new file mode 100644 index 0000000..1469be8 --- /dev/null +++ b/src/gnss-service/gnss-impl.c @@ -0,0 +1,331 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup GNSSService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "globals.h" +#include "gnss.h" +#include "gnss-status.h" + + +static pthread_mutex_t mutexCb = PTHREAD_MUTEX_INITIALIZER; //protects the callbacks +static pthread_mutex_t mutexData = PTHREAD_MUTEX_INITIALIZER; //protects the data + +TGNSSConfiguration gGNSSConfiguration = {0}; + +static TGNSSSatelliteDetail gSatelliteDetail = {0}; //TODO: buffer full set of satellite details for one point in time +static GNSSSatelliteDetailCallback cbSatelliteDetail = 0; + +static TGNSSPosition gPosition = {0}; +static volatile GNSSPositionCallback cbPosition = 0; + +static TGNSSTime gTime = {0}; +static volatile GNSSTimeCallback cbTime = 0; + +static TGNSSStatus gStatus = {0}; +static volatile GNSSStatusCallback cbStatus = 0; + +bool iGnssInit() +{ + pthread_mutex_lock(&mutexData); + //example GNSS configuration + gGNSSConfiguration.antennaPosition.x = 0.3; + gGNSSConfiguration.antennaPosition.y = 0.0; + gGNSSConfiguration.antennaPosition.z = 1.2; + gGNSSConfiguration.supportedSystems = GNSS_SYSTEM_GPS | GNSS_SYSTEM_GLONASS; + gGNSSConfiguration.validityBits = + GNSS_CONFIG_ANTPOS_VALID | + GNSS_CONFIG_SATSYS_VALID; + pthread_mutex_unlock(&mutexData); + + return true; +} + +bool iGnssDestroy() +{ + return true; +} + +bool gnssGetConfiguration(TGNSSConfiguration* gnssConfig) +{ + bool retval = false; + + if(gnssConfig) + { + pthread_mutex_lock(&mutexData); + *gnssConfig = gGNSSConfiguration; + pthread_mutex_unlock(&mutexData); + retval = true; + } + + return retval; +} + +bool gnssRegisterSatelliteDetailCallback(GNSSSatelliteDetailCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbSatelliteDetail) + { + cbSatelliteDetail = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool gnssDeregisterSatelliteDetailCallback(GNSSSatelliteDetailCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbSatelliteDetail == callback) && callback) + { + cbSatelliteDetail = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool gnssGetSatelliteDetails(TGNSSSatelliteDetail* satelliteDetails, uint16_t count, uint16_t* numSatelliteDetails) +{ + bool retval = false; + + if(satelliteDetails && count) + { +//TODO: return full set of satellite details for one point in time + pthread_mutex_lock(&mutexData); + *satelliteDetails = gSatelliteDetail; + *numSatelliteDetails = 1; + pthread_mutex_unlock(&mutexData); + retval = true; + } + + return retval; +} + +bool gnssRegisterPositionCallback(GNSSPositionCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbPosition) + { + cbPosition = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool gnssDeregisterPositionCallback(GNSSPositionCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbPosition == callback) && callback) + { + cbPosition = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool gnssGetPosition(TGNSSPosition* position) +{ + bool retval = false; + if(position) + { + pthread_mutex_lock(&mutexData); + *position = gPosition; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + + +bool gnssRegisterTimeCallback(GNSSTimeCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbTime) + { + cbTime = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + + +bool gnssDeregisterTimeCallback(GNSSTimeCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbTime == callback) && callback) + { + cbTime = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool gnssGetTime(TGNSSTime* time) +{ + bool retval = false; + if(time) + { + pthread_mutex_lock(&mutexData); + *time = gTime; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + +bool gnssGetPrecisionTimingOffset(int32_t *delta) +{ + //Dummy implementation + return false; +} + + +bool gnssRegisterStatusCallback(GNSSStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbStatus) + { + cbStatus = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + + +bool gnssDeregisterStatusCallback(GNSSStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbStatus == callback) && callback) + { + cbStatus = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool gnssGetStatus(TGNSSStatus* status) +{ + bool retval = false; + if(status) + { + pthread_mutex_lock(&mutexData); + *status = gStatus; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + + +void updateGNSSTime(const TGNSSTime time[], uint16_t numElements) +{ + if (time != NULL && numElements > 0) + { + pthread_mutex_lock(&mutexData); + gTime = time[numElements-1]; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbTime) + { + cbTime(time, numElements); + } + pthread_mutex_unlock(&mutexCb); + } +} + +void updateGNSSPosition(const TGNSSPosition position[], uint16_t numElements) +{ + if (position != NULL && numElements > 0) + { + pthread_mutex_lock(&mutexData); + gPosition = position[numElements-1]; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbPosition) + { + cbPosition(position, numElements); + } + pthread_mutex_unlock(&mutexCb); + } +} + +void updateGNSSSatelliteDetail(const TGNSSSatelliteDetail satelliteDetail[], uint16_t numElements) +{ + if (satelliteDetail != NULL && numElements > 0) + { + pthread_mutex_lock(&mutexData); + gSatelliteDetail = satelliteDetail[numElements-1]; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbSatelliteDetail) + { + cbSatelliteDetail(satelliteDetail, numElements); + } + pthread_mutex_unlock(&mutexCb); + } +} + + +void updateGNSSStatus(const TGNSSStatus* status) +{ + if (status) + { + pthread_mutex_lock(&mutexData); + gStatus = *status; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbStatus) + { + cbStatus(status); + } + pthread_mutex_unlock(&mutexCb); + } +}
\ No newline at end of file diff --git a/src/gnss-service/gnss-meta-data.c b/src/gnss-service/gnss-meta-data.c new file mode 100644 index 0000000..26e7f26 --- /dev/null +++ b/src/gnss-service/gnss-meta-data.c @@ -0,0 +1,41 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup GNSSService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "globals.h" +#include "gnss-meta-data.h" +#include "gnss.h" + +const TGnssMetaData gGnssMetaData = { + GENIVI_GNSS_API_MAJOR, //version + GNSS_CATEGORY_PHYSICAL, //category + GNSS_TYPE_GNSS, //typeBits + 1000, //cycleTime in ms + 4 //number of channels +}; + +bool gnssGetMetaData(TGnssMetaData *data) +{ + if(!data) + { + return false; + } + + *data = gGnssMetaData; + + return true; +} diff --git a/src/gnss-service/gnss-use-replayer.c b/src/gnss-service/gnss-use-replayer.c new file mode 100644 index 0000000..77510f9 --- /dev/null +++ b/src/gnss-service/gnss-use-replayer.c @@ -0,0 +1,779 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup GNSSService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#define __STDC_FORMAT_MACROS +#include <inttypes.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> +#include <time.h> +#include <errno.h> +#include <pthread.h> +#include <assert.h> +#include <math.h> + +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <memory.h> + +#include "globals.h" +#include "gnss-init.h" +#include "log.h" + +#define STRINGIFY2( x) #x +#define STRINGIFY(x) STRINGIFY2(x) + +#define BUFLEN 256 +#define MSGIDLEN 20 +#define PORT 9930 + +#define MAX_BUF_MSG 16 + +//Listener thread +static pthread_t listenerThread; +//Listener thread loop control variale +static volatile bool isRunning = false; +//Socket file descriptor used by listener thread. +//Global so we can shutdown() it to release listener thread immediately from waiting +static int s = 0; +//Note: we do not mutex-protect the above globals because for this proof-of-concept +//implementation we expect that the client does not ake overlapping calls. +//For a real-world fool-proof implementation you would have to add more checks. + +static void *listenForMessages( void *ptr ); + +DLT_DECLARE_CONTEXT(gContext); + +bool gnssInit() +{ + iGnssInit(); + + isRunning = true; + + if(pthread_create(&listenerThread, NULL, listenForMessages, NULL) != 0) + { + isRunning = false; + return false; + } + + return true; +} + +bool gnssDestroy() +{ + isRunning = false; + + //shut down the socket + shutdown(s,2); + + if(listenerThread) + { + pthread_join(listenerThread, NULL); + } + + iGnssDestroy(); + + return true; +} + +void gnssGetVersion(int *major, int *minor, int *micro) +{ + if(major) + { + *major = GENIVI_GNSS_API_MAJOR; + } + + if (minor) + { + *minor = GENIVI_GNSS_API_MINOR; + } + + if (micro) + { + *micro = GENIVI_GNSS_API_MICRO; + } +} + +bool gnssSetGNSSSystems(uint32_t activate_systems) +{ + return false; //satellite system configuration request not supported for replay +} + + +static bool processGVGNSPOS(const char* data) +{ + //parse data like: 555854,0,$GVGNSPOS,555804,49.0437988,12.1011773, 337.8, 383.8,13.3,9999.0,195.85,2.3,1.4,1.9,06,9999,9999, 2.6, 2.5,9999.0,9999.0,9999.0,3,0X00000001,0X00000001,0X00000001,0X003C67DF + + //storage for buffered data + static TGNSSPosition buf_pos[MAX_BUF_MSG]; + static uint16_t buf_size = 0; + static uint16_t last_countdown = 0; + + uint64_t timestamp; + uint16_t countdown; + TGNSSPosition pos = { 0 }; + int n = 0; + + if(!data) + { + LOG_ERROR_MSG(gContext,"wrong parameter!"); + return false; + } + + n = sscanf(data, + "%"SCNu64",%"SCNu16",$GVGNSPOS,%"SCNu64",%lf,%lf,%f,%f,%f,%f,%f,%f,%f,%f,%"SCNu16",%"SCNu16",%"SCNu16",%f,%f,%f,%f,%f,%u,%x,%x,%x,%"SCNu16",%x", + ×tamp, + &countdown, + &pos.timestamp, + &pos.latitude, + &pos.longitude, + &pos.altitudeMSL, + &pos.altitudeEll, + &pos.hSpeed, + &pos.vSpeed, + &pos.heading, + &pos.pdop, + &pos.hdop, + &pos.vdop, + &pos.usedSatellites, + &pos.trackedSatellites, + &pos.visibleSatellites, + &pos.sigmaHPosition, + &pos.sigmaAltitude, + &pos.sigmaHSpeed, + &pos.sigmaVSpeed, + &pos.sigmaHeading, + &pos.fixStatus, + &pos.fixTypeBits, + &pos.activatedSystems, + &pos.usedSystems, + &pos.correctionAge, + &pos.validityBits + ); + + if (n != 27) //27 fields to parse + { + //try old version without correctionAge + n = sscanf(data, + "%"SCNu64",%"SCNu16",$GVGNSPOS,%"SCNu64",%lf,%lf,%f,%f,%f,%f,%f,%f,%f,%f,%"SCNu16",%"SCNu16",%"SCNu16",%f,%f,%f,%f,%f,%u,%x,%x,%x,%x", + ×tamp, + &countdown, + &pos.timestamp, + &pos.latitude, + &pos.longitude, + &pos.altitudeMSL, + &pos.altitudeEll, + &pos.hSpeed, + &pos.vSpeed, + &pos.heading, + &pos.pdop, + &pos.hdop, + &pos.vdop, + &pos.usedSatellites, + &pos.trackedSatellites, + &pos.visibleSatellites, + &pos.sigmaHPosition, + &pos.sigmaAltitude, + &pos.sigmaHSpeed, + &pos.sigmaVSpeed, + &pos.sigmaHeading, + &pos.fixStatus, + &pos.fixTypeBits, + &pos.activatedSystems, + &pos.usedSystems, + &pos.validityBits + ); + pos.validityBits &= ~GNSS_POSITION_CORRAGE_VALID; //just to be safe + if (n != 26) //26 fields to parse + { + LOG_ERROR_MSG(gContext,"replayer: processGVGNSPOS failed!"); + return false; + } + } + + //buffered data handling + if (countdown < MAX_BUF_MSG) //enough space in buffer? + { + if (buf_size == 0) //a new sequence starts + { + buf_size = countdown+1; + last_countdown = countdown; + buf_pos[buf_size-countdown-1] = pos; + } + else if ((last_countdown-countdown) == 1) //sequence continued + { + last_countdown = countdown; + buf_pos[buf_size-countdown-1] = pos; + } + else //sequence interrupted: clear buffer + { + buf_size = 0; + last_countdown = 0; + } + } + else //clear buffer + { + buf_size = 0; + last_countdown = 0; + } + + if((countdown == 0) && (buf_size >0) ) + { + updateGNSSPosition(buf_pos,buf_size); + buf_size = 0; + last_countdown = 0; + } + + return true; +} + +static bool processGVGNSTIM(const char* data) +{ + //parse data like: 555854,0,$GVGNSTIM,555804,2016,01,23,20,49,00,000,00,0,0X00000003 + + //storage for buffered data + static TGNSSTime buf_tim[MAX_BUF_MSG]; + static uint16_t buf_size = 0; + static uint16_t last_countdown = 0; + + uint64_t timestamp; + uint16_t countdown; + TGNSSTime tim = { 0 }; + int n = 0; + + if(!data) + { + LOG_ERROR_MSG(gContext,"wrong parameter!"); + return false; + } + + n = sscanf(data, + "%"SCNu64",%"SCNu16",$GVGNSTIM,%"SCNu64",%04"SCNu16",%02"SCNu8",%02"SCNu8",%02"SCNu8",%02"SCNu8",%02"SCNu8",%03"SCNu16",%u,%02"SCNi8",0X%08X", + ×tamp, + &countdown, + &tim.timestamp, + &tim.year, + &tim.month, + &tim.day, + &tim.hour, + &tim.minute, + &tim.second, + &tim.ms, + &tim.scale, + &tim.leapSeconds, + &tim.validityBits + ); + + if (n != 13) //13 fields to parse + { + LOG_ERROR_MSG(gContext,"replayer: processGVGNSPOS failed!"); + return false; + } + + //buffered data handling + if (countdown < MAX_BUF_MSG) //enough space in buffer? + { + if (buf_size == 0) //a new sequence starts + { + buf_size = countdown+1; + last_countdown = countdown; + buf_tim[buf_size-countdown-1] = tim; + } + else if ((last_countdown-countdown) == 1) //sequence continued + { + last_countdown = countdown; + buf_tim[buf_size-countdown-1] = tim; + } + else //sequence interrupted: clear buffer + { + buf_size = 0; + last_countdown = 0; + } + } + else //clear buffer + { + buf_size = 0; + last_countdown = 0; + } + + if((countdown == 0) && (buf_size >0) ) + { + updateGNSSTime(buf_tim, buf_size); + buf_size = 0; + last_countdown = 0; + } + + return true; +} + + + +//backward compatible processing of GVGNSAC to the new TGNSSPosition +static bool processGVGNSAC(const char* data) +{ + //parse data like: 047434000,0$GVGNSAC,047434000,0,1.0,0,07,0,0,0,0,0,2,0X00000001,0X60A + + //storage for buffered data + static TGNSSPosition buf_acc[MAX_BUF_MSG]; + static uint16_t buf_size = 0; + static uint16_t last_countdown = 0; + + uint64_t timestamp; + uint16_t countdown; + TGNSSPosition pos = { 0 }; + uint16_t fixStatus; + float sigmaLatitude; + float sigmaLongitude; + uint32_t GVGNSAC_validityBits; + int n = 0; + + if(!data) + { + LOG_ERROR_MSG(gContext,"wrong parameter!"); + return false; + } + + n = sscanf(data, "%llu,%hu$GVGNSAC,%llu,%f,%f,%f,%hu,%hu,%hu,%f,%f,%f,%hu,%x,%x", + ×tamp, &countdown, &pos.timestamp, + &pos.pdop, &pos.hdop, &pos.vdop, + &pos.usedSatellites, &pos.trackedSatellites, &pos.visibleSatellites, + &sigmaLatitude, &sigmaLongitude, &pos.sigmaAltitude, + &fixStatus, &pos.fixTypeBits, &GVGNSAC_validityBits); + + if (n != 15) //15 fields to parse + { + LOG_ERROR_MSG(gContext,"replayer: processGVGNSAC failed!"); + return false; + } + + //fix status: order in enum has changed + if (fixStatus == 0) { pos.fixStatus = GNSS_FIX_STATUS_NO; } + if (fixStatus == 1) { pos.fixStatus = GNSS_FIX_STATUS_2D; } + if (fixStatus == 2) { pos.fixStatus = GNSS_FIX_STATUS_3D; } + if (fixStatus == 3) { pos.fixStatus = GNSS_FIX_STATUS_TIME; } + //calculate sigmaHPosition from sigmaLatitude, sigmaLongitude*sigmaLongitude); + pos.sigmaHPosition = sqrt(sigmaLatitude*sigmaLatitude); + //map the old validity bits to the new validity bits + pos.validityBits = 0; + if (GVGNSAC_validityBits&0x00000001) { pos.validityBits |= GNSS_POSITION_PDOP_VALID; } + if (GVGNSAC_validityBits&0x00000002) { pos.validityBits |= GNSS_POSITION_HDOP_VALID; } + if (GVGNSAC_validityBits&0x00000004) { pos.validityBits |= GNSS_POSITION_VDOP_VALID; } + if (GVGNSAC_validityBits&0x00000008) { pos.validityBits |= GNSS_POSITION_USAT_VALID; } + if (GVGNSAC_validityBits&0x00000010) { pos.validityBits |= GNSS_POSITION_TSAT_VALID; } + if (GVGNSAC_validityBits&0x00000020) { pos.validityBits |= GNSS_POSITION_VSAT_VALID; } + if (GVGNSAC_validityBits&0x00000040) { pos.validityBits |= GNSS_POSITION_SHPOS_VALID; } + if (GVGNSAC_validityBits&0x00000100) { pos.validityBits |= GNSS_POSITION_SALT_VALID; } + if (GVGNSAC_validityBits&0x00000200) { pos.validityBits |= GNSS_POSITION_STAT_VALID; } + if (GVGNSAC_validityBits&0x00000400) { pos.validityBits |= GNSS_POSITION_TYPE_VALID; } + + + //global Position: update the changed fields, retain the existing fields from other callbacks + TGNSSPosition upd_pos; + if (gnssGetPosition(&upd_pos)) + { + upd_pos.timestamp = pos.timestamp; + upd_pos.pdop = pos.pdop; + upd_pos.hdop = pos.hdop; + upd_pos.vdop = pos.vdop; + upd_pos.usedSatellites = pos.usedSatellites; + upd_pos.trackedSatellites = pos.trackedSatellites; + upd_pos.visibleSatellites = pos.visibleSatellites; + upd_pos.sigmaHPosition = pos.sigmaHPosition; + upd_pos.sigmaAltitude = pos.sigmaAltitude; + upd_pos.fixStatus = pos.fixStatus; + upd_pos.fixTypeBits = pos.fixTypeBits; + upd_pos.validityBits |= pos.validityBits; + pos = upd_pos; + } + + //buffered data handling + if (countdown < MAX_BUF_MSG) //enough space in buffer? + { + if (buf_size == 0) //a new sequence starts + { + buf_size = countdown+1; + last_countdown = countdown; + buf_acc[buf_size-countdown-1] = pos; + } + else if ((last_countdown-countdown) == 1) //sequence continued + { + last_countdown = countdown; + buf_acc[buf_size-countdown-1] = pos; + } + else //sequence interrupted: clear buffer + { + buf_size = 0; + last_countdown = 0; + } + } + else //clear buffer + { + buf_size = 0; + last_countdown = 0; + } + + if((countdown == 0) && (buf_size >0) ) + { + updateGNSSPosition(buf_acc,buf_size); + buf_size = 0; + last_countdown = 0; + } + + return true; +} + +//backward compatible processing of GVGNSP to the new TGNSSPosition +static bool processGVGNSP(const char* data) +{ + //parse data like: 061064000,0$GVGNSP,061064000,49.02657,12.06527,336.70000,0X07 + + //storage for buffered data + static TGNSSPosition buf_pos[MAX_BUF_MSG]; + static uint16_t buf_size = 0; + static uint16_t last_countdown = 0; + + uint64_t timestamp; + uint16_t countdown; + TGNSSPosition pos = { 0 }; + uint32_t GVGNSP_validityBits; + int n = 0; + + if(!data) + { + LOG_ERROR_MSG(gContext,"wrong parameter!"); + return false; + } + + n = sscanf(data, "%llu,%hu$GVGNSP,%llu,%lf,%lf,%f,%x", ×tamp, &countdown, &pos.timestamp, &pos.latitude, &pos.longitude, &pos.altitudeMSL, &GVGNSP_validityBits); + + if (n != 7) //7 fields to parse + { + LOG_ERROR_MSG(gContext,"replayer: processGVGNSP failed!"); + return false; + } + + //map the old validity bits to the new validity bits + pos.validityBits = 0; + if (GVGNSP_validityBits&0x00000001) { pos.validityBits |= GNSS_POSITION_LATITUDE_VALID; } + if (GVGNSP_validityBits&0x00000002) { pos.validityBits |= GNSS_POSITION_LONGITUDE_VALID; } + if (GVGNSP_validityBits&0x00000004) { pos.validityBits |= GNSS_POSITION_ALTITUDEMSL_VALID; } + + //buffered data handling + if (countdown < MAX_BUF_MSG) //enough space in buffer? + { + if (buf_size == 0) //a new sequence starts + { + buf_size = countdown+1; + last_countdown = countdown; + buf_pos[buf_size-countdown-1] = pos; + } + else if ((last_countdown-countdown) == 1) //sequence continued + { + last_countdown = countdown; + buf_pos[buf_size-countdown-1] = pos; + } + else //sequence interrupted: clear buffer + { + buf_size = 0; + last_countdown = 0; + } + } + else //clear buffer + { + buf_size = 0; + last_countdown = 0; + } + + if((countdown == 0) && (buf_size >0) ) + { + updateGNSSPosition(buf_pos,buf_size); + buf_size = 0; + last_countdown = 0; + } + + return true; +} + +//backward compatible processing of GVGNSC to the new TGNSSPosition +static bool processGVGNSC(const char* data) +{ + //parse data like: 061064000,0$GVGNSC,061064000,0.00,0,131.90000,0X05 + + //storage for buffered data + static TGNSSPosition buf_course[MAX_BUF_MSG]; + static uint16_t buf_size = 0; + static uint16_t last_countdown = 0; + + uint64_t timestamp; + uint16_t countdown; + TGNSSPosition pos = { 0 }; + uint32_t GVGNSC_validityBits; + int n = 0; + + if(!data) + { + LOG_ERROR_MSG(gContext,"wrong parameter!"); + return false; + } + + n = sscanf(data, "%llu,%hu$GVGNSC,%llu,%f,%f,%f,%x", ×tamp, &countdown, &pos.timestamp, &pos.hSpeed, &pos.vSpeed, &pos.heading, &GVGNSC_validityBits); + + if (n != 7) //7 fields to parse + { + LOG_ERROR_MSG(gContext,"replayer: processGVGNSC failed!"); + return false; + } + + //map the old validity bits to the new validity bits + pos.validityBits = 0; + if (GVGNSC_validityBits&0x00000001) { pos.validityBits |= GNSS_POSITION_HSPEED_VALID; } + if (GVGNSC_validityBits&0x00000002) { pos.validityBits |= GNSS_POSITION_VSPEED_VALID; } + if (GVGNSC_validityBits&0x00000004) { pos.validityBits |= GNSS_POSITION_HEADING_VALID; } + + + //global Position: update the changed fields, retain the existing fields from other callbacks + TGNSSPosition upd_pos; + if (gnssGetPosition(&upd_pos)) + { + upd_pos.timestamp = pos.timestamp; + upd_pos.hSpeed = pos.hSpeed; + upd_pos.vSpeed = pos.vSpeed; + upd_pos.heading = pos.heading; + upd_pos.validityBits |= pos.validityBits; + pos = upd_pos; + } + + //buffered data handling + if (countdown < MAX_BUF_MSG) //enough space in buffer? + { + if (buf_size == 0) //a new sequence starts + { + buf_size = countdown+1; + last_countdown = countdown; + buf_course[buf_size-countdown-1] = pos; + } + else if ((last_countdown-countdown) == 1) //sequence continued + { + last_countdown = countdown; + buf_course[buf_size-countdown-1] = pos; + } + else //sequence interrupted: clear buffer + { + buf_size = 0; + last_countdown = 0; + } + } + else //clear buffer + { + buf_size = 0; + last_countdown = 0; + } + + if((countdown == 0) && (buf_size >0) ) + { + updateGNSSPosition(buf_course,buf_size); + buf_size = 0; + last_countdown = 0; + } + + return true; +} + +static bool processGVGNSSAT(const char* data) +{ + //parse data like: 061064000,05$GVGNSSAT,061064000,1,18,314.0,22.0,39,0X00,0X1F + + //storage for buffered data + static TGNSSSatelliteDetail buf_sat[MAX_BUF_MSG]; + static uint16_t buf_size = 0; + static uint16_t last_countdown = 0; + + uint64_t timestamp; + uint16_t countdown; + TGNSSSatelliteDetail sat = { 0 }; + uint16_t system = 0; + int n = 0; + + if(!data) + { + LOG_ERROR_MSG(gContext,"wrong parameter!"); + return false; + } + + n = sscanf(data, "%llu,%hu,$GVGNSSAT,%llu,%hu,%hu,%hu,%hu,%hu,%x,%hu,%x", + ×tamp, &countdown, + &sat.timestamp, &system, &sat.satelliteId, + &sat.azimuth, &sat.elevation, &sat.CNo, + &sat.statusBits, &sat.posResidual, &sat.validityBits); + + if (n != 11) //11 fields to parse + { + //try old version without posResidual and without comma befroe $ + n = sscanf(data, "%llu,%hu$GVGNSSAT,%llu,%hu,%hu,%hu,%hu,%hu,%x,%x", ×tamp, &countdown, &sat.timestamp,&system,&sat.satelliteId,&sat.azimuth,&sat.elevation,&sat.CNo,&sat.statusBits,&sat.validityBits); + sat.validityBits &= ~GNSS_SATELLITE_RESIDUAL_VALID; //just to be safe + + if (n != 10) //10 fields to parse + { + LOG_ERROR_MSG(gContext,"replayer: processGVGNSSAT failed!"); + return false; + } + } + + //map integer to enum + sat.system = system; + //LOG_DEBUG(gContext,"Decoded: %llu,%hu$GVGNSSAT,%llu,%d,%hu,%hu,%hu,%hu,0X%X,0X%X ", timestamp, countdown, sat.timestamp, sat.system, sat.satelliteId, sat.azimuth, sat.elevation, sat.CNo, sat.statusBits, sat.validityBits); + + + //buffered data handling + if (countdown < MAX_BUF_MSG) //enough space in buffer? + { + if (buf_size == 0) //a new sequence starts + { + buf_size = countdown+1; + last_countdown = countdown; + buf_sat[buf_size-countdown-1] = sat; + } + else if ((last_countdown-countdown) == 1) //sequence continued + { + last_countdown = countdown; + buf_sat[buf_size-countdown-1] = sat; + } + else //sequence interrupted: clear buffer + { + buf_size = 0; + last_countdown = 0; + } + } + else //clear buffer + { + buf_size = 0; + last_countdown = 0; + } + + if((countdown == 0) && (buf_size >0) ) + { + updateGNSSSatelliteDetail(buf_sat,buf_size); + buf_size = 0; + last_countdown = 0; + } + + return true; +} + +static void *listenForMessages( void *ptr ) +{ + struct sockaddr_in si_me; + struct sockaddr_in si_other; + socklen_t slen = sizeof(si_other); + ssize_t readBytes = 0; + char buf[BUFLEN+1]; //add space fer terminating \0 + char msgId[MSGIDLEN+1]; //add space fer terminating \0 + int port = PORT; + + DLT_REGISTER_APP("GNSS", "GNSS-SERVICE"); + DLT_REGISTER_CONTEXT(gContext,"GSRV", "Global Context"); + + LOG_DEBUG(gContext,"GNSSService listening on port %d...",port); + + if((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) + { + LOG_ERROR_MSG(gContext,"socket() failed!"); + exit(EXIT_FAILURE); + } + + memset((char *) &si_me, 0, sizeof(si_me)); + si_me.sin_family = AF_INET; + + si_me.sin_port = htons(port); + si_me.sin_addr.s_addr = htonl(INADDR_ANY); + if(bind(s, (struct sockaddr *)&si_me, (socklen_t)sizeof(si_me)) == -1) + { + LOG_ERROR_MSG(gContext,"bind() failed!"); + exit(EXIT_FAILURE); + } + + while(isRunning == true) + { + //use select to introduce a timeout - alloy shutdown even when no data are received + fd_set readfs; /* file descriptor set */ + int maxfd; /* maximum file desciptor used */ + int res; + struct timeval Timeout; + /* set timeout value within input loop */ + Timeout.tv_usec = 0; /* milliseconds */ + Timeout.tv_sec = 1; /* seconds */ + FD_SET(s, &readfs); + maxfd = s+1; + /* block until input becomes available */ + res = select(maxfd, &readfs, NULL, NULL, &Timeout); + + if (res > 0) + { + + readBytes = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, (socklen_t *)&slen); + + if(readBytes < 0) + { + LOG_ERROR_MSG(gContext,"recvfrom() failed!"); + exit(EXIT_FAILURE); + } + buf[readBytes] = '\0'; + + sscanf(buf, "%*[^'$']$%" STRINGIFY(MSGIDLEN) "[^',']", msgId); + + LOG_DEBUG(gContext,"Data:%s", buf); + + if(strcmp("GVGNSPOS", msgId) == 0) + { + processGVGNSPOS(buf); + } + else if(strcmp("GVGNSTIM", msgId) == 0) + { + processGVGNSTIM(buf); + } + else if(strcmp("GVGNSSAT", msgId) == 0) + { + processGVGNSSAT(buf); + } + //handling of old logs for backward compatibility + else if(strcmp("GVGNSP", msgId) == 0) + { + processGVGNSP(buf); + } + else if(strcmp("GVGNSC", msgId) == 0) + { + processGVGNSC(buf); + } + else if(strcmp("GVGNSAC", msgId) == 0) + { + processGVGNSAC(buf); + } + } + + } + + close(s); + + return EXIT_SUCCESS; +} + diff --git a/src/gnss-service/log.h b/src/gnss-service/log.h new file mode 100644 index 0000000..4d946fb --- /dev/null +++ b/src/gnss-service/log.h @@ -0,0 +1,154 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup GNSSService +* +* \copyright Copyright (C) BMW Car IT GmbH 2011 +* Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#ifndef INCLUDE_LOG +#define INCLUDE_LOG + +// turn-on via cmake define: +// $ cmake -DWITH_DLT=1 -DDEBUG_ENABLED=1 .. + +#if (!DLT_ENABLED) +/*****************************************************************************/ +// use printf +#include <stdio.h> + +// some type-name used instead of DLT context +typedef const char* NoDltContext; + +#define DLT_DECLARE_CONTEXT(CONTEXT) \ + NoDltContext CONTEXT; + +#define DLT_IMPORT_CONTEXT(CONTEXT) \ + extern NoDltContext CONTEXT; + +#define DLT_REGISTER_CONTEXT(CONTEXT, CONTEXT_ID, DESC) \ + CONTEXT = CONTEXT_ID; + +#define DLT_REGISTER_APP(CONTEXT, DESC) ; + +#define DLT_UNREGISTER_CONTEXT(CONTEXT) ; +#define DLT_UNREGISTER_APP() ; +#define dlt_free() ; + +// log calls +#if (!DEBUG_ENABLED) + +#define LOG_VERBOSE_MSG(context, msg) ; +#define LOG_VERBOSE(context, fmt, ...) ; + +#define LOG_DEBUG_MSG(context, msg) ; +#define LOG_DEBUG(context, fmt, ...) ; + +#define LOG_INFO_MSG(context, msg) ; +#define LOG_INFO(context, fmt, ...) ; + +#define LOG_WARNING_MSG(context, msg) ; +#define LOG_WARNING(context, fmt, ...) ; + +#else + +#define LOG_VERBOSE_MSG(context, msg) \ + fprintf(stderr, "[VERBO][%4s] " msg "\n", context) +#define LOG_VERBOSE(context, fmt, ...) \ + fprintf(stderr, "[VERBO][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_DEBUG_MSG(context, msg) \ + fprintf(stderr, "[DEBUG][%4s] " msg "\n", context) +#define LOG_DEBUG(context, fmt, ...) \ + fprintf(stderr, "[DEBUG][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_INFO_MSG(context, msg) \ + fprintf(stderr, "[INFO ][%4s] " msg "\n", context) +#define LOG_INFO(context, fmt, ...) \ + fprintf(stderr, "[INFO ][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_WARNING_MSG(context, msg) \ + fprintf(stderr, "[WARN ][%4s] " msg "\n", context) +#define LOG_WARNING(context, fmt, ...) \ + fprintf(stderr, "[WARN ][%4s] " fmt "\n", context, __VA_ARGS__) +#endif + +#define LOG_ERROR_MSG(context, msg) \ + fprintf(stderr, "[ERROR][%4s] " msg "\n", context) +#define LOG_ERROR(context, fmt, ...) \ + fprintf(stderr, "[ERROR][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_FATAL_MSG(context, msg) \ + fprintf(stderr, "[FATAL][%4s] " msg "\n", context) +#define LOG_FATAL(context, fmt, ...) \ + fprintf(stderr, "[FATAL][%4s] " fmt "\n", context, __VA_ARGS__) + +#else /* DLT_ENABLED */ +/*****************************************************************************/ +// use DLT +#include "dlt.h" + +typedef const char* Context; + +#define LOG_VERBOSE_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_VERBOSE, DLT_STRING(msg)); +#define LOG_VERBOSE(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_VERBOSE, DLT_STRING(logBuffer)); \ + } +#define LOG_DEBUG_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_DEBUG, DLT_STRING(msg)); +#define LOG_DEBUG(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_DEBUG, DLT_STRING(logBuffer)); \ + } +#define LOG_INFO_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_INFO, DLT_STRING(msg)); +#define LOG_INFO(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_INFO, DLT_STRING(logBuffer)); \ + } +#define LOG_WARNING_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_WARN, DLT_STRING(msg)); +#define LOG_WARNING(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_WARN, DLT_STRING(logBuffer)); \ + } +#define LOG_ERROR_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_ERROR, DLT_STRING(msg)); +#define LOG_ERROR(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_ERROR, DLT_STRING(logBuffer)); \ + } +#define LOG_FATAL_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_FATAL, DLT_STRING(msg)); +#define LOG_FATAL(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_FATAL, DLT_STRING(logBuffer)); \ + } + +#endif /* DLT_ENABLED */ + +#endif /* INCLUDE_LOG */ diff --git a/src/hmi/config/fsa_giromagny.conf b/src/hmi/config/fsa_giromagny.conf new file mode 100644 index 0000000..1963bc2 --- /dev/null +++ b/src/hmi/config/fsa_giromagny.conf @@ -0,0 +1,24 @@ +[Locale] +language=eng +country=USA +script=Latn +[DefaultPosition] +latitude=47.741416 +longitude=6.826746 +altitude=392 +[DefaultAddress] +country=France +city=Giromagny +street=Place des Mineurs +number=46 +[Settings] +simulationMode=false +showroom=false +autoguidance=false +radius=10000 +maxResultListSize=10 +defaultCategoryName=fuel +[Log] +verbose=true +dlt=true + diff --git a/src/hmi/hmi-launcher/CMakeLists.txt b/src/hmi/hmi-launcher/CMakeLists.txt index 34d69d7..ee36150 100644 --- a/src/hmi/hmi-launcher/CMakeLists.txt +++ b/src/hmi/hmi-launcher/CMakeLists.txt @@ -19,13 +19,15 @@ # @licence end@ ########################################################################### project(hmi-launcher) + +message(STATUS ${PROJECT_NAME}) + cmake_minimum_required(VERSION 2.8.11) add_definitions("-std=gnu++11") add_definitions("-fPIC") -message(STATUS "hmi-launcher") find_program(XSLTPROC xsltproc REQUIRED) find_program(QT_MOC_EXECUTABLE moc) find_program(QT_LRELEASE lrelease) @@ -33,6 +35,9 @@ find_program(QT_LUPDATE lupdate) find_package(PkgConfig REQUIRED) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${TOP_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${TOP_DIR}/bin) + pkg_check_modules(DBUS dbus-1) pkg_check_modules(QT5_CORE REQUIRED Qt5Core) pkg_check_modules(QT5_QML REQUIRED Qt5Qml) @@ -204,7 +209,7 @@ if(${WITH_DLT}) set(LIBRARIES ${LIBRARIES} ${DLT_LIBRARIES}) endif() -add_executable(hmi-launcher +add_executable(${PROJECT_NAME} ${MOC_SOURCES} main.cpp dltif.cpp @@ -213,7 +218,9 @@ add_executable(hmi-launcher preference.cpp ) -target_link_libraries(hmi-launcher ${LIBRARIES}) +target_link_libraries(${PROJECT_NAME} ${LIBRARIES}) + +install(TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/src/log-replayer-server/CMakeLists.txt b/src/log-replayer-server/CMakeLists.txt new file mode 100644 index 0000000..f586888 --- /dev/null +++ b/src/log-replayer-server/CMakeLists.txt @@ -0,0 +1,53 @@ +########################################################################### +# @licence app begin@ +# SPDX-License-Identifier: MPL-2.0 +# +# Component Name: log-replayer-server +# +# Author: Philippe Colliot +# +# Copyright (C) 2018, Groupe PSA +# +# License: +# This Source Code Form is subject to the terms of the +# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +# this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# @licence end@ +########################################################################### +project(log-replayer-server) +cmake_minimum_required(VERSION 2.8) + +message(STATUS ${PROJECT_NAME}) + +set(CMAKE_VERBOSE_MAKEFILE on) +set(CMAKE_CXX_FLAGS "-Wall -std=c++0x") + +# Source Files +FILE(GLOB PRJ_LOCAL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + +set(PRJ_SRCS ${PRJ_LOCAL_SRCS}) + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${TOP_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${TOP_DIR}/bin) + +include_directories( + ${GOBJECT_INCLUDE_DIRS} + ${GLIB_INCLUDE_DIRS} +) + +link_directories( + ${GOBJECT_LIBRARY_DIRS} + ${GLIB_LIBRARY_DIRS} +) + +set(LIBRARIES + ${LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GLIB_LIBRARIES} +) + +# Build service +add_executable(${PROJECT_NAME} ${PRJ_SRCS}) +target_link_libraries(${PROJECT_NAME} ${LIBRARIES}) +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) diff --git a/src/log-replayer-server/log-replayer-server.cpp b/src/log-replayer-server/log-replayer-server.cpp new file mode 100644 index 0000000..3a8976d --- /dev/null +++ b/src/log-replayer-server/log-replayer-server.cpp @@ -0,0 +1,202 @@ +#include <arpa/inet.h> +#include <netinet/in.h> +#include <stdio.h> +#include <signal.h> +#include <stdlib.h> +#include <stdbool.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <memory.h> + +#include "log.h" + +DLT_DECLARE_CONTEXT(gCtxENGI); + +#define MSGIDLEN 20 +#define BUFLEN 256 +#define PORT1 9930 //port used for GNSS data +#define PORT2 9931 //port used for sensor data +#define PORT3 9932 //port used for vehicle data +#define IPADDR_DEFAULT "127.0.0.1" +#define MAXDELTA 1000 //max value to avoid overflow +#define MINLINESIZE 3 +#define STRINGIFY2( x) #x +#define STRINGIFY(x) STRINGIFY2(x) + +bool running = true; + +void sighandler(int sig) +{ + running = false; +} + +bool getStrToSend(FILE* file, char* line, int dim) +{ + static long unsigned int lastTimestamp = 0; + long unsigned int timestamp = 0; + long signed int delta = 0; + + if(dim <= 0) + { + return false; + } + + char* ptrStr = fgets(line, dim, file); + + line[dim -1] = '\0'; + + if(ptrStr == NULL || feof(file)) + { + //error or end of file + return false; + } + + if(strchr(line, '#') != 0) + { + line[0] = '\0'; + return true; //skip comment line + } + + if (!sscanf(line, "%lu", ×tamp)) + { + line[0] = '\0'; + return true; //skip lines without timestamp + } + + if(!lastTimestamp) + { + delta = 0; + } + else + { + delta = timestamp - lastTimestamp; + } + + lastTimestamp = timestamp; + + if(delta < 0) + { + return true; + } + + if(delta > MAXDELTA) + { + delta = MAXDELTA; + } + + if(usleep(delta*1000) != 0) // TODO time drift issues + { + return true; + } + + return true; +} + + +int main(int argc, char* argv[]) { + DLT_REGISTER_APP("LRPS","LOG REPLAYER SERVER"); + DLT_REGISTER_CONTEXT(gCtxENGI,"ENGI","Engineering mode"); + + struct sockaddr_in si_other; + socklen_t slen = sizeof(si_other); + int s; + FILE * logfile = 0; + char * filename = 0; + char buf[BUFLEN]; + char msgId[MSGIDLEN]; + char * ipaddr = 0; + + signal(SIGTERM, sighandler); + signal(SIGINT, sighandler); + + if(argc < 2) + { + return EXIT_FAILURE; + } + else + { + filename = argv[1]; + if(argc < 3) + ipaddr = IPADDR_DEFAULT; + else + ipaddr = argv[2]; + } + + if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + { + return EXIT_FAILURE; + } + + memset((char *) &si_other, 0, sizeof(si_other)); + si_other.sin_family = AF_INET; + //si_other.sin_port = htons(<port number>); + if(inet_aton(ipaddr, &si_other.sin_addr) == 0) + { + return EXIT_FAILURE; + } + + logfile = fopen(filename, "r"); + + if(logfile == NULL) + { + return EXIT_FAILURE; + } + + LOG_INFO_MSG(gCtxENGI,"Log replayer server started"); + + while(running) + { + if(!getStrToSend(logfile,buf,BUFLEN)) + { + //error or end of file + return EXIT_FAILURE; + } + + if (strlen(buf) < 3) + { + //skip empty lines (includes comments) + continue; + } + + sscanf(buf, "%*[^'$']$%[^',']", msgId); + + //GVGNS: list of supported message IDs + //GVGNSPOS,GVGNSTIM + if (strncmp ("GVGNS", msgId, strlen("GVGNS")) == 0) + { + si_other.sin_port = htons(PORT1); + if(sendto(s, buf, strlen(buf)+1, 0, (struct sockaddr *)&si_other, slen) == -1) + { + return EXIT_FAILURE; + } + } + + //GVSNS: list of supported message IDs + //GVSNSVSP,GVSNSWHECNF,GVSNSWHE,GVSNSODO,GVSNSDRVDIR,GVSNSGYR, + if(strncmp ("GVSNS", msgId, strlen("GVSNS")) == 0) + { + si_other.sin_port = htons(PORT2); + if(sendto(s, buf, strlen(buf)+1, 0, (struct sockaddr *)&si_other, slen) == -1) + { + return EXIT_FAILURE; + } + } + //GVVEH: list of supported message IDs + //GVVEHVER,GVVEHENGSPEED,GVVEHFUELLEVEL,GVVEHFUELCONS,GVVEHTOTALODO; + if(strncmp ("GVVEH", msgId, strlen("GVVEH")) == 0) + { + si_other.sin_port = htons(PORT3); + if(sendto(s, buf, strlen(buf)+1, 0, (struct sockaddr *)&si_other, slen) == -1) + { + return EXIT_FAILURE; + } + } + } + + close(s); + + LOG_INFO_MSG(gCtxENGI,"Log replayer server stopped"); + + return EXIT_SUCCESS; +} diff --git a/src/log-replayer-server/log.h b/src/log-replayer-server/log.h new file mode 100644 index 0000000..4d946fb --- /dev/null +++ b/src/log-replayer-server/log.h @@ -0,0 +1,154 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup GNSSService +* +* \copyright Copyright (C) BMW Car IT GmbH 2011 +* Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#ifndef INCLUDE_LOG +#define INCLUDE_LOG + +// turn-on via cmake define: +// $ cmake -DWITH_DLT=1 -DDEBUG_ENABLED=1 .. + +#if (!DLT_ENABLED) +/*****************************************************************************/ +// use printf +#include <stdio.h> + +// some type-name used instead of DLT context +typedef const char* NoDltContext; + +#define DLT_DECLARE_CONTEXT(CONTEXT) \ + NoDltContext CONTEXT; + +#define DLT_IMPORT_CONTEXT(CONTEXT) \ + extern NoDltContext CONTEXT; + +#define DLT_REGISTER_CONTEXT(CONTEXT, CONTEXT_ID, DESC) \ + CONTEXT = CONTEXT_ID; + +#define DLT_REGISTER_APP(CONTEXT, DESC) ; + +#define DLT_UNREGISTER_CONTEXT(CONTEXT) ; +#define DLT_UNREGISTER_APP() ; +#define dlt_free() ; + +// log calls +#if (!DEBUG_ENABLED) + +#define LOG_VERBOSE_MSG(context, msg) ; +#define LOG_VERBOSE(context, fmt, ...) ; + +#define LOG_DEBUG_MSG(context, msg) ; +#define LOG_DEBUG(context, fmt, ...) ; + +#define LOG_INFO_MSG(context, msg) ; +#define LOG_INFO(context, fmt, ...) ; + +#define LOG_WARNING_MSG(context, msg) ; +#define LOG_WARNING(context, fmt, ...) ; + +#else + +#define LOG_VERBOSE_MSG(context, msg) \ + fprintf(stderr, "[VERBO][%4s] " msg "\n", context) +#define LOG_VERBOSE(context, fmt, ...) \ + fprintf(stderr, "[VERBO][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_DEBUG_MSG(context, msg) \ + fprintf(stderr, "[DEBUG][%4s] " msg "\n", context) +#define LOG_DEBUG(context, fmt, ...) \ + fprintf(stderr, "[DEBUG][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_INFO_MSG(context, msg) \ + fprintf(stderr, "[INFO ][%4s] " msg "\n", context) +#define LOG_INFO(context, fmt, ...) \ + fprintf(stderr, "[INFO ][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_WARNING_MSG(context, msg) \ + fprintf(stderr, "[WARN ][%4s] " msg "\n", context) +#define LOG_WARNING(context, fmt, ...) \ + fprintf(stderr, "[WARN ][%4s] " fmt "\n", context, __VA_ARGS__) +#endif + +#define LOG_ERROR_MSG(context, msg) \ + fprintf(stderr, "[ERROR][%4s] " msg "\n", context) +#define LOG_ERROR(context, fmt, ...) \ + fprintf(stderr, "[ERROR][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_FATAL_MSG(context, msg) \ + fprintf(stderr, "[FATAL][%4s] " msg "\n", context) +#define LOG_FATAL(context, fmt, ...) \ + fprintf(stderr, "[FATAL][%4s] " fmt "\n", context, __VA_ARGS__) + +#else /* DLT_ENABLED */ +/*****************************************************************************/ +// use DLT +#include "dlt.h" + +typedef const char* Context; + +#define LOG_VERBOSE_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_VERBOSE, DLT_STRING(msg)); +#define LOG_VERBOSE(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_VERBOSE, DLT_STRING(logBuffer)); \ + } +#define LOG_DEBUG_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_DEBUG, DLT_STRING(msg)); +#define LOG_DEBUG(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_DEBUG, DLT_STRING(logBuffer)); \ + } +#define LOG_INFO_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_INFO, DLT_STRING(msg)); +#define LOG_INFO(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_INFO, DLT_STRING(logBuffer)); \ + } +#define LOG_WARNING_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_WARN, DLT_STRING(msg)); +#define LOG_WARNING(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_WARN, DLT_STRING(logBuffer)); \ + } +#define LOG_ERROR_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_ERROR, DLT_STRING(msg)); +#define LOG_ERROR(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_ERROR, DLT_STRING(logBuffer)); \ + } +#define LOG_FATAL_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_FATAL, DLT_STRING(msg)); +#define LOG_FATAL(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_FATAL, DLT_STRING(logBuffer)); \ + } + +#endif /* DLT_ENABLED */ + +#endif /* INCLUDE_LOG */ @@ -101,7 +101,7 @@ gdb=0 #no debug xterm=0 #no subprocess into a separate xterm log=0 #no log file enhpos=1 #enhanced position server enabled -replayer=1 #replayer enabled +replayer=0 #replayer disabled gateway=0 #vehicle gateway disabled lm=0 #layer manager disabled wm="" #to store the current window manager (in case of start with the layer manager) @@ -113,11 +113,12 @@ speech=0 CUR_DIR=$PWD BIN_DIR=$CUR_DIR/build -SRC_DIR=$CUR_DIR +TOP_DIR=$CUR_DIR -SCRIPT_DIR=$SRC_DIR/script -HMI_DIR=$SRC_DIR/hmi +SCRIPT_DIR=$TOP_DIR/script +HMI_DIR=$TOP_DIR/hmi app=$HMI_DIR/qml/NavigationApp.qml # hmi panel launched by default +repl="" STYLE_SHEETS_GENERATED_INDICATOR=$HMI_DIR/style-sheets/the-style-sheets-have-been-generated-css.js CONFIG_DIR=$HMI_DIR/config REPLAYER_LOG_FILE=none @@ -125,52 +126,52 @@ export REPLAYER_LOG_FILE # location of exe, lib and config files AUTOMOTIVE_MESSAGE_BROKER=automotive-message-broker -AUTOMOTIVE_MESSAGE_BROKER_SRC_DIR=$SRC_DIR/$AUTOMOTIVE_MESSAGE_BROKER +AUTOMOTIVE_MESSAGE_BROKER_SRC_DIR=$TOP_DIR/$AUTOMOTIVE_MESSAGE_BROKER AUTOMOTIVE_MESSAGE_BROKER_BIN_DIR=$AUTOMOTIVE_MESSAGE_BROKER_SRC_DIR/src/$AUTOMOTIVE_MESSAGE_BROKER-build GENIVI_LOGREPLAYER=genivilogreplayer -GENIVI_LOGREPLAYER_SRC_DIR=$SRC_DIR/$GENIVI_LOGREPLAYER +GENIVI_LOGREPLAYER_SRC_DIR=$TOP_DIR/$GENIVI_LOGREPLAYER GENIVI_LOGREPLAYER_BIN_DIR=$BIN_DIR/$GENIVI_LOGREPLAYER NAVIGATION=navigation -NAVIGATION_SRC_DIR=$SRC_DIR/$NAVIGATION/src/navigation +NAVIGATION_SRC_DIR=$TOP_DIR/$NAVIGATION/src/navigation NAVIGATION_BIN_DIR=$BIN_DIR/$NAVIGATION NAVIT=navit NAVIT_BIN_DIR=$NAVIGATION_BIN_DIR/navit/navit POI_SERVER=poi-server -POI_SERVER_SRC_DIR=$SRC_DIR/$NAVIGATION/src/poi-service/$POI_SERVER -POI_SERVER_BIN_DIR=$SRC_DIR/$NAVIGATION/src/poi-service/bin -POI_SERVER_RESOURCE_DIR=$SRC_DIR/$NAVIGATION/src/poi-service/resource +POI_SERVER_SRC_DIR=$TOP_DIR/$NAVIGATION/src/poi-service/$POI_SERVER +POI_SERVER_BIN_DIR=$TOP_DIR/$NAVIGATION/src/poi-service/bin +POI_SERVER_RESOURCE_DIR=$TOP_DIR/$NAVIGATION/src/poi-service/resource poidatabase=$POI_SERVER_RESOURCE_DIR/empty.db # empty poi database by default -LOG_REPLAYER=log-replayer -LOG_REPLAYER_SRC_DIR=$NAVIGATION_SRC_DIR/positioning/$LOG_REPLAYER -LOG_REPLAYER_BIN_DIR=$NAVIGATION_SRC_DIR/bin +LOG_REPLAYER=log-replayer-server +LOG_REPLAYER_SRC_DIR=$TOP_DIR/$LOG_REPLAYER +LOG_REPLAYER_BIN_DIR=$TOP_DIR/bin -ENHANCED_POSITION_SERVICE=enhanced-position-service -ENHANCED_POSITION_SERVICE_SRC_DIR=$NAVIGATION_SRC_DIR/positioning/$ENHANCED_POSITION_SERVICE -ENHANCED_POSITION_SERVICE_BIN_DIR=$NAVIGATION_SRC_DIR/bin +ENHANCED_POSITION_SERVICE=dead-reckoning +ENHANCED_POSITION_SERVICE_SRC_DIR=$TOP_DIR/$ENHANCED_POSITION_SERVICE +ENHANCED_POSITION_SERVICE_BIN_DIR=$TOP_DIR/bin FUEL_STOP_ADVISOR=fuel-stop-advisor -FUEL_STOP_ADVISOR_SRC_DIR=$SRC_DIR/$FUEL_STOP_ADVISOR +FUEL_STOP_ADVISOR_SRC_DIR=$TOP_DIR/$FUEL_STOP_ADVISOR FUEL_STOP_ADVISOR_BIN_DIR=$BIN_DIR/$FUEL_STOP_ADVISOR HMI_LAUNCHER=hmi-launcher -HMI_LAUNCHER_SRC_DIR=$SRC_DIR/hmi/$HMI_LAUNCHER -HMI_LAUNCHER_BIN_DIR=$BIN_DIR/hmi/$HMI_LAUNCHER +HMI_LAUNCHER_SRC_DIR=$TOP_DIR/hmi/$HMI_LAUNCHER +HMI_LAUNCHER_BIN_DIR=$TOP_DIR/bin VEHICLE_GATEWAY=vehicle-gateway -VEHICLE_GATEWAY_SRC_DIR=$SRC_DIR/$VEHICLE_GATEWAY +VEHICLE_GATEWAY_SRC_DIR=$TOP_DIR/$VEHICLE_GATEWAY VEHICLE_GATEWAY_BIN_DIR=$BIN_DIR/$VEHICLE_GATEWAY devices="/dev/ttyUSB0 /dev/ttyACM0" SPEECH_SERVER=speech-server -SPEECH_OUTPUT_BIN_DIR=$SRC_DIR/$NAVIGATION/src/speech-service/bin/ +SPEECH_OUTPUT_BIN_DIR=$TOP_DIR/$NAVIGATION/src/speech-service/bin/ # options analysis -while getopts a:c:df:g:hlnoprsvx opt +while getopts a:c:df:g:hlnopr:svx opt do case $opt in a) #select another hmi panel @@ -194,6 +195,10 @@ do center="126.99 37.54" config_file=fsa_seoul.conf ;; + giromagny) + center="47.74 6.83" + config_file=fsa_giromagny.conf + ;; [0-9-]*) center=$OPTARG ;; @@ -225,8 +230,9 @@ do p) #enable the reuse of persistent data persistent=1 ;; - r) #disable the log replayer - replayer=0 + r) #enable the log replayer and set the file + replayer=1 + repl=$(readlink -f $OPTARG) ;; s) speech=1 @@ -239,9 +245,9 @@ do ;; h) echo "Usage:" - echo "$0 [-a application][-c center][-ghlnoprsvx]" + echo "$0 [-a application][-c center][-r replayerfile][-ghlnopsvx]" echo "-a: Set application (default application.qml)" - echo "-c: Set center (supported values: paris,tokyo,london,seoul,longitude latitude). Default is geneve" + echo "-c: Set center (supported values: paris,tokyo,london,seoul,giromagny longitude latitude). Default is geneve" echo "-d: Run subprocesses within gdb (only with -x)" echo "-f: Load another database (for poi)" echo "-g: Run the vehicle gateway (only with -r) -g \"<ELM327device> <GNSSdevice>\"" @@ -250,7 +256,7 @@ do echo "-n: Don't start enhanced positioning service" echo "-o: Create log file of subprocess output" echo "-p: Reuse of persistent data (i.e. in $HOME, so don't reinit it with default file)" - echo "-r: Don't start replayer" + echo "-r: Start replayer" echo "-s: Launch the speech server" echo "-v: Enable the output of log or debug messages" echo "-x: Run subprocesses in own xterm to get separated log messages (doesn't make sense with -l)" @@ -344,8 +350,9 @@ wait_for_service org.genivi.navigationcore.Routing /org/genivi/navigationcore wait_for_service org.genivi.navigationcore.Session /org/genivi/navigationcore if [ "$replayer" = 1 ] -then # start the log replayer (of the fsa) with a sample log file - run "Log Replayer" $LOG_REPLAYER_BIN_DIR/$LOG_REPLAYER $LOG_REPLAYER_SRC_DIR/logs/geneve-cologny.log +then # start the log replayer (of the fsa) with the log file +echo "$repl" + run "Log Replayer" $LOG_REPLAYER_BIN_DIR/$LOG_REPLAYER $repl else if [ "$gateway" = 1 ] then diff --git a/src/sensors-service/CMakeLists.txt b/src/sensors-service/CMakeLists.txt new file mode 100644 index 0000000..129a509 --- /dev/null +++ b/src/sensors-service/CMakeLists.txt @@ -0,0 +1,77 @@ +########################################################################### +# @licence app begin@ +# SPDX-License-Identifier: MPL-2.0 +# +# Component Name: SensorsService +# +# Author: Marco Residori +# +# Copyright (C) 2013, XS Embedded GmbH +# Copyright (C) 2018, PSA Groupe +# +# License: +# This Source Code Form is subject to the terms of the +# Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +# this file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# Update (2014/12/02) : Philippe Colliot <philippe.colliot@mpsa.com>, +# PSA Peugeot Citroen +# - introduce debug flag to disable verbosity +# Update (2018/05/30) : Philippe Colliot <philippe.colliot@mpsa.com>, +# PSA Groupe +# - adaptation of former version to introduce dead reckoning +# @licence end@ +########################################################################### +project(sensors-service) + +message(STATUS ${PROJECT_NAME}) + +add_definitions("-std=gnu++11") + +find_package(PkgConfig REQUIRED) + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${TOP_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${TOP_DIR}/bin) + +include_directories("${SENSORS_SERVICE_API_DIR}") + +set(LIBRARIES pthread) + +if(WITH_DLT) + add_definitions("-DDLT_ENABLED=1") + pkg_check_modules(DLT REQUIRED automotive-dlt) + include_directories( ${DLT_INCLUDE_DIRS} ) + set(LIBRARIES ${LIBRARIES} ${DLT_LIBRARIES}) +endif() + +if(WITH_DEBUG) + add_definitions("-DDEBUG_ENABLED=1") +endif() + +#generate library using replayer as input +set(SRC ${CMAKE_CURRENT_SOURCE_DIR}/sns-use-replayer.c + ${CMAKE_CURRENT_SOURCE_DIR}/wheeltick.c + ${CMAKE_CURRENT_SOURCE_DIR}/gyroscope.c + ${CMAKE_CURRENT_SOURCE_DIR}/acceleration.c + ${CMAKE_CURRENT_SOURCE_DIR}/vehicle-data.c + ${CMAKE_CURRENT_SOURCE_DIR}/vehicle-speed.c + ${CMAKE_CURRENT_SOURCE_DIR}/sns-meta-data.c) + +add_library(${PROJECT_NAME} SHARED ${SRC}) +target_link_libraries(${PROJECT_NAME} ${LIBRARIES}) +install(TARGETS ${PROJECT_NAME} DESTINATION lib) + + + + + + + + + + + + + + + diff --git a/src/sensors-service/acceleration.c b/src/sensors-service/acceleration.c new file mode 100644 index 0000000..bbb2bcc --- /dev/null +++ b/src/sensors-service/acceleration.c @@ -0,0 +1,220 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup SensorsService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "globals.h" +#include "acceleration.h" +#include "sns-meta-data.h" + +static pthread_mutex_t mutexCb = PTHREAD_MUTEX_INITIALIZER; //protects the callbacks +static pthread_mutex_t mutexData = PTHREAD_MUTEX_INITIALIZER; //protects the data + +static volatile AccelerationCallback cbAcceleration = 0; +static TAccelerationData gAccelerationData = {0}; +TAccelerationConfiguration gAccelerationConfiguration; + +static TSensorStatus gStatus = {0}; +static volatile SensorStatusCallback cbStatus = 0; + +bool iAccelerationInit() +{ + pthread_mutex_lock(&mutexCb); + cbAcceleration = 0; + pthread_mutex_unlock(&mutexCb); + + pthread_mutex_lock(&mutexData); + gAccelerationData.validityBits = 0; + //example accelerometer configuration for a 3-axis accelerometer + gAccelerationConfiguration.dist2RefPointX = 0; + gAccelerationConfiguration.dist2RefPointY = 0; + gAccelerationConfiguration.dist2RefPointZ = 0; + gAccelerationConfiguration.angleYaw = 0; + gAccelerationConfiguration.anglePitch = 0; + gAccelerationConfiguration.angleRoll = 0; + gAccelerationConfiguration.sigmaX = 0; + gAccelerationConfiguration.sigmaY = 0; + gAccelerationConfiguration.sigmaZ = 0; + gAccelerationConfiguration.typeBits = + ACCELERATION_X_PROVIDED | + ACCELERATION_Y_PROVIDED | + ACCELERATION_Z_PROVIDED; + gAccelerationConfiguration.validityBits = + ACCELERATION_CONFIG_ANGLEYAW_VALID | + ACCELERATION_CONFIG_ANGLEPITCH_VALID | + ACCELERATION_CONFIG_ANGLEROLL_VALID | + ACCELERATION_CONFIG_TYPE_VALID; + pthread_mutex_unlock(&mutexData); + + return true; +} + +bool iAccelerationDestroy() +{ + pthread_mutex_lock(&mutexCb); + cbAcceleration = 0; + pthread_mutex_unlock(&mutexCb); + + return true; +} + +bool snsAccelerationGetAccelerationData(TAccelerationData * accelerationData) +{ + bool retval = false; + if(accelerationData) + { + pthread_mutex_lock(&mutexData); + *accelerationData = gAccelerationData; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + +bool snsAccelerationRegisterCallback(AccelerationCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbAcceleration) + { + cbAcceleration = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsAccelerationDeregisterCallback(AccelerationCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbAcceleration == callback) && callback) + { + cbAcceleration = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsAccelerationGetMetaData(TSensorMetaData *data) +{ + bool retval = false; + + if(data) + { + pthread_mutex_lock(&mutexData); + *data = gSensorsMetaData[3]; + pthread_mutex_unlock(&mutexData); + retval = true; + } + + return retval; +} + +bool snsAccelerationGetAccelerationConfiguration(TAccelerationConfiguration* config) +{ + bool retval = false; + if(config) + { + pthread_mutex_lock(&mutexData); + *config = gAccelerationConfiguration; + pthread_mutex_unlock(&mutexData); + retval = true; + } + + return retval; +} + +void updateAccelerationData(const TAccelerationData accelerationData[], uint16_t numElements) +{ + if (accelerationData != NULL && numElements > 0) + { + pthread_mutex_lock(&mutexData); + gAccelerationData = accelerationData[numElements-1]; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbAcceleration) + { + cbAcceleration(accelerationData, numElements); + } + pthread_mutex_unlock(&mutexCb); + } +} + +bool snsAccelerationGetStatus(TSensorStatus* status){ + bool retval = false; + if(status) + { + pthread_mutex_lock(&mutexData); + *status = gStatus; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + +bool snsAccelerationRegisterStatusCallback(SensorStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbStatus) + { + cbStatus = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsAccelerationDeregisterStatusCallback(SensorStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbStatus == callback) && callback) + { + cbStatus = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +void updateAccelerationStatus(const TSensorStatus* status) +{ + if (status) + { + pthread_mutex_lock(&mutexData); + gStatus = *status; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbStatus) + { + cbStatus(status); + } + pthread_mutex_unlock(&mutexCb); + } +}
\ No newline at end of file diff --git a/src/sensors-service/globals.h b/src/sensors-service/globals.h new file mode 100644 index 0000000..7c2f9d0 --- /dev/null +++ b/src/sensors-service/globals.h @@ -0,0 +1,67 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup SensorsService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#ifndef GLOBALS_H +#define GLOBALS_H + +#include <stdbool.h> +#include <pthread.h> +#include <time.h> + +#include "sns-init.h" +#include "wheel.h" +#include "acceleration.h" +#include "gyroscope.h" +#include "vehicle-speed.h" +#include "sns-meta-data.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const TSensorMetaData gSensorsMetaData[]; + +bool iAccelerationInit(); +bool iAccelerationDestroy(); +void updateAccelerationData(const TAccelerationData accelerationData[], uint16_t numElements); +void updateAccelerationStatus(const TSensorStatus* status); + +bool iGyroscopeInit(); +bool iGyroscopeDestroy(); +void updateGyroscopeData(const TGyroscopeData gyroData[], uint16_t numElements); +void updateGyroscopeStatus(const TSensorStatus* status); + + +bool iWheelInit(); +bool iWheelDestroy(); +void updateWheelData(const TWheelData wheelData[], uint16_t numElements); +void updateWheelStatus(const TSensorStatus* status); + +bool iVehicleSpeedInit(); +bool iVehicleSpeedDestroy(); +void updateVehicleSpeedData(const TVehicleSpeedData vehicleSpeedData[], uint16_t numElements); +void updateVehicleSpeedStatus(const TSensorStatus* status); + +bool iVehicleDataInit(); +bool iVehicleDataDestroy(); + +#ifdef __cplusplus +} +#endif + +#endif /* GLOBALS_H */ diff --git a/src/sensors-service/gyroscope.c b/src/sensors-service/gyroscope.c new file mode 100644 index 0000000..a0bf7b6 --- /dev/null +++ b/src/sensors-service/gyroscope.c @@ -0,0 +1,217 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup SensorsService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "globals.h" +#include "gyroscope.h" +#include "sns-meta-data.h" + +static pthread_mutex_t mutexCb = PTHREAD_MUTEX_INITIALIZER; //protects the callbacks +static pthread_mutex_t mutexData = PTHREAD_MUTEX_INITIALIZER; //protects the data + +static volatile GyroscopeCallback cbGyroscope = 0; +static TGyroscopeData gGyroscopeData = {0}; +TGyroscopeConfiguration gGyroscopeConfiguration; + +static TSensorStatus gStatus = {0}; +static volatile SensorStatusCallback cbStatus = 0; + + +bool iGyroscopeInit() +{ + pthread_mutex_lock(&mutexCb); + cbGyroscope = 0; + pthread_mutex_unlock(&mutexCb); + + pthread_mutex_lock(&mutexData); + gGyroscopeData.validityBits = 0; + //example gyroscope configuration for a 3-axis gyro + gGyroscopeConfiguration.angleYaw = 0; + gGyroscopeConfiguration.anglePitch = 0; + gGyroscopeConfiguration.angleRoll = 0; + gGyroscopeConfiguration.momentOfYawInertia = 0; + gGyroscopeConfiguration.sigmaGyroscope = 0; + gGyroscopeConfiguration.typeBits = + GYROSCOPE_YAWRATE_PROVIDED | + GYROSCOPE_PITCHRATE_PROVIDED | + GYROSCOPE_ROLLRATE_PROVIDED; + gGyroscopeConfiguration.validityBits = + GYROSCOPE_CONFIG_ANGLEYAW_VALID | + GYROSCOPE_CONFIG_ANGLEPITCH_VALID | + GYROSCOPE_CONFIG_ANGLEROLL_VALID | + GYROSCOPE_CONFIG_TYPE_VALID; + pthread_mutex_unlock(&mutexData); + + return true; +} + +bool iGyroscopeDestroy() +{ + pthread_mutex_lock(&mutexCb); + cbGyroscope = 0; + pthread_mutex_unlock(&mutexCb); + + return true; +} + +bool snsGyroscopeGetGyroscopeData(TGyroscopeData * gyroData) +{ + bool retval = false; + if(gyroData) + { + pthread_mutex_lock(&mutexData); + *gyroData = gGyroscopeData; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + +bool snsGyroscopeRegisterCallback(GyroscopeCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbGyroscope) + { + cbGyroscope = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsGyroscopeDeregisterCallback(GyroscopeCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbGyroscope == callback) && callback) + { + cbGyroscope = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsGyroscopeGetMetaData(TSensorMetaData *data) +{ + bool retval = false; + + if(data) + { + pthread_mutex_lock(&mutexData); + *data = gSensorsMetaData[1]; + pthread_mutex_unlock(&mutexData); + retval = true; + } + + return retval; +} + +bool snsGyroscopeGetConfiguration(TGyroscopeConfiguration* gyroConfig) +{ + bool retval = false; + if(gyroConfig) + { + pthread_mutex_lock(&mutexData); + *gyroConfig = gGyroscopeConfiguration; + pthread_mutex_unlock(&mutexData); + retval = true; + } + + return retval; +} + +void updateGyroscopeData(const TGyroscopeData gyroData[], uint16_t numElements) +{ + if (gyroData != NULL && numElements > 0) + { + pthread_mutex_lock(&mutexData); + gGyroscopeData = gyroData[numElements-1]; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbGyroscope) + { + cbGyroscope(gyroData, numElements); + } + pthread_mutex_unlock(&mutexCb); + } +} + +bool snsGyroscopeGetStatus(TSensorStatus* status){ + bool retval = false; + if(status) + { + pthread_mutex_lock(&mutexData); + *status = gStatus; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + +bool snsGyroscopeRegisterStatusCallback(SensorStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbStatus) + { + cbStatus = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsGyroscopeDeregisterStatusCallback(SensorStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbStatus == callback) && callback) + { + cbStatus = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +void updateGyroscopeStatus(const TSensorStatus* status) +{ + if (status) + { + pthread_mutex_lock(&mutexData); + gStatus = *status; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbStatus) + { + cbStatus(status); + } + pthread_mutex_unlock(&mutexCb); + } +}
\ No newline at end of file diff --git a/src/sensors-service/log.h b/src/sensors-service/log.h new file mode 100644 index 0000000..fa5c3ca --- /dev/null +++ b/src/sensors-service/log.h @@ -0,0 +1,154 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup SensorsService +* +* \copyright Copyright (C) BMW Car IT GmbH 2011 +* Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#ifndef INCLUDE_LOG +#define INCLUDE_LOG + +// turn-on via cmake define: +// $ cmake -DWITH_DLT=1 -DDEBUG_ENABLED=1 .. + +#if (!DLT_ENABLED) +/*****************************************************************************/ +// use printf +#include <stdio.h> + +// some type-name used instead of DLT context +typedef const char* NoDltContext; + +#define DLT_DECLARE_CONTEXT(CONTEXT) \ + NoDltContext CONTEXT; + +#define DLT_IMPORT_CONTEXT(CONTEXT) \ + extern NoDltContext CONTEXT; + +#define DLT_REGISTER_CONTEXT(CONTEXT, CONTEXT_ID, DESC) \ + CONTEXT = CONTEXT_ID; + +#define DLT_REGISTER_APP(CONTEXT, DESC) ; + +#define DLT_UNREGISTER_CONTEXT(CONTEXT) ; +#define DLT_UNREGISTER_APP() ; +#define dlt_free() ; + +// log calls +#if (!DEBUG_ENABLED) + +#define LOG_VERBOSE_MSG(context, msg) ; +#define LOG_VERBOSE(context, fmt, ...) ; + +#define LOG_DEBUG_MSG(context, msg) ; +#define LOG_DEBUG(context, fmt, ...) ; + +#define LOG_INFO_MSG(context, msg) ; +#define LOG_INFO(context, fmt, ...) ; + +#define LOG_WARNING_MSG(context, msg) ; +#define LOG_WARNING(context, fmt, ...) ; + +#else + +#define LOG_VERBOSE_MSG(context, msg) \ + fprintf(stderr, "[VERBO][%4s] " msg "\n", context) +#define LOG_VERBOSE(context, fmt, ...) \ + fprintf(stderr, "[VERBO][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_DEBUG_MSG(context, msg) \ + fprintf(stderr, "[DEBUG][%4s] " msg "\n", context) +#define LOG_DEBUG(context, fmt, ...) \ + fprintf(stderr, "[DEBUG][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_INFO_MSG(context, msg) \ + fprintf(stderr, "[INFO ][%4s] " msg "\n", context) +#define LOG_INFO(context, fmt, ...) \ + fprintf(stderr, "[INFO ][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_WARNING_MSG(context, msg) \ + fprintf(stderr, "[WARN ][%4s] " msg "\n", context) +#define LOG_WARNING(context, fmt, ...) \ + fprintf(stderr, "[WARN ][%4s] " fmt "\n", context, __VA_ARGS__) +#endif + +#define LOG_ERROR_MSG(context, msg) \ + fprintf(stderr, "[ERROR][%4s] " msg "\n", context) +#define LOG_ERROR(context, fmt, ...) \ + fprintf(stderr, "[ERROR][%4s] " fmt "\n", context, __VA_ARGS__) + +#define LOG_FATAL_MSG(context, msg) \ + fprintf(stderr, "[FATAL][%4s] " msg "\n", context) +#define LOG_FATAL(context, fmt, ...) \ + fprintf(stderr, "[FATAL][%4s] " fmt "\n", context, __VA_ARGS__) + +#else /* DLT_ENABLED */ +/*****************************************************************************/ +// use DLT +#include "dlt.h" + +typedef const char* Context; + +#define LOG_VERBOSE_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_VERBOSE, DLT_STRING(msg)); +#define LOG_VERBOSE(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_VERBOSE, DLT_STRING(logBuffer)); \ + } +#define LOG_DEBUG_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_DEBUG, DLT_STRING(msg)); +#define LOG_DEBUG(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_DEBUG, DLT_STRING(logBuffer)); \ + } +#define LOG_INFO_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_INFO, DLT_STRING(msg)); +#define LOG_INFO(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_INFO, DLT_STRING(logBuffer)); \ + } +#define LOG_WARNING_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_WARN, DLT_STRING(msg)); +#define LOG_WARNING(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_WARN, DLT_STRING(logBuffer)); \ + } +#define LOG_ERROR_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_ERROR, DLT_STRING(msg)); +#define LOG_ERROR(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_ERROR, DLT_STRING(logBuffer)); \ + } +#define LOG_FATAL_MSG(context, msg) \ + DLT_LOG(context, DLT_LOG_FATAL, DLT_STRING(msg)); +#define LOG_FATAL(context, fmt, ...) \ + { \ + char logBuffer[256]; \ + sprintf(logBuffer, fmt, __VA_ARGS__); \ + DLT_LOG(context, DLT_LOG_FATAL, DLT_STRING(logBuffer)); \ + } + +#endif /* DLT_ENABLED */ + +#endif /* INCLUDE_LOG */ diff --git a/src/sensors-service/sns-meta-data.c b/src/sensors-service/sns-meta-data.c new file mode 100644 index 0000000..2b218d1 --- /dev/null +++ b/src/sensors-service/sns-meta-data.c @@ -0,0 +1,48 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup SensorsService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "globals.h" +#include "sns-meta-data.h" + +#define NUM_SENSORS 4 + +const TSensorMetaData gSensorsMetaData[NUM_SENSORS] = { + {GENIVI_SNS_API_MAJOR, //version + SENSOR_CATEGORY_PHYSICAL, //category + SENSOR_TYPE_WHEELTICK, //type + 100}, //cycleTime in ms + {GENIVI_SNS_API_MAJOR, //version + SENSOR_CATEGORY_PHYSICAL, //category + SENSOR_TYPE_GYROSCOPE, //type + 100}, //cycleTime in ms + {GENIVI_SNS_API_MAJOR, //version + SENSOR_CATEGORY_PHYSICAL, //category + SENSOR_TYPE_VEHICLE_SPEED, //type + 100}, //cycleTime in ms + {GENIVI_SNS_API_MAJOR, //version + SENSOR_CATEGORY_PHYSICAL, //category + SENSOR_TYPE_ACCELERATION, //type + 100} //cycleTime in ms +}; + +int32_t getSensorMetaDataList(const TSensorMetaData** metadata) +{ + *metadata = gSensorsMetaData; + + return NUM_SENSORS; +} diff --git a/src/sensors-service/sns-use-replayer.c b/src/sensors-service/sns-use-replayer.c new file mode 100644 index 0000000..a628453 --- /dev/null +++ b/src/sensors-service/sns-use-replayer.c @@ -0,0 +1,517 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup SensorsService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "sns-init.h" +#include "acceleration.h" +#include "gyroscope.h" +#include "inclination.h" +#include "odometer.h" +#include "reverse-gear.h" +#include "slip-angle.h" +#include "steering-angle.h" +#include "vehicle-data.h" +#include "vehicle-speed.h" +#include "vehicle-state.h" +#include "wheel.h" + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> +#include <time.h> +#include <errno.h> +#include <pthread.h> +#include <assert.h> + +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <memory.h> + +#include "globals.h" +#include "log.h" + +#define STRINGIFY2( x) #x +#define STRINGIFY(x) STRINGIFY2(x) + +#define BUFLEN 256 +#define MSGIDLEN 20 +#define PORT 9931 + +#define MAX_BUF_MSG 16 + +DLT_DECLARE_CONTEXT(gContext); + +//Listener thread +static pthread_t listenerThread; +//Listener thread loop control variale +static volatile bool isRunning = false; +//Socket file descriptor used by listener thread. +//Global so we can shutdown() it to release listener thread immediately from waiting +static int s = 0; +//Note: we do not mutex-protect the above globals because for this proof-of-concept +//implementation we expect that the client does not ake overlapping calls. +//For a real-world fool-proof implementation you would have to add more checks. + + +static void *listenForMessages( void *ptr ); + +bool snsInit() +{ + isRunning = true; + + if(pthread_create( &listenerThread, NULL, listenForMessages, NULL) != 0) + { + isRunning = false; + return false; + } + + return true; +} + +bool snsDestroy() +{ + isRunning = false; + + //shut down the socket + shutdown(s,2); + + if(listenerThread) + { + pthread_join( listenerThread, NULL); + } + + return true; +} + +void snsGetVersion(int *major, int *minor, int *micro) +{ + if(major) + { + *major = GENIVI_SNS_API_MAJOR; + } + + if(minor) + { + *minor = GENIVI_SNS_API_MINOR; + } + + if(micro) + { + *micro = GENIVI_SNS_API_MICRO; + } +} + +bool snsAccelerationInit() +{ + return iAccelerationInit(); +} + +bool snsAccelerationDestroy() +{ + return iAccelerationDestroy(); +} + +bool snsGyroscopeInit() +{ + return iGyroscopeInit(); +} + +bool snsGyroscopeDestroy() +{ + return iGyroscopeDestroy(); +} + +bool snsVehicleSpeedInit() +{ + return iVehicleSpeedInit(); +} + +bool snsVehicleSpeedDestroy() +{ + return iVehicleSpeedDestroy(); +} + +bool snsWheelInit() +{ + return iWheelInit(); +} + +bool snsWheelDestroy() +{ + return iWheelDestroy(); +} + +bool snsVehicleDataInit() +{ + return iVehicleDataInit(); +} + +bool snsVehicleDataDestroy() +{ + return iVehicleDataDestroy(); +} + +bool processGVSNSWHE(const char* data) +{ + //parse data like: 15259,0,$GVSNSWHE,15200,35,45,0,0,0,0,0,0,0X0001,100,0X03 + + //storage for buffered data + static TWheelData buf_whtk[MAX_BUF_MSG]; + static uint16_t buf_size = 0; + static uint16_t last_countdown = 0; + + uint64_t timestamp; + uint16_t countdown; + TWheelData whtk = { 0 }; + int n = 0; + + if(!data) + { + LOG_ERROR_MSG(gContext,"wrong parameter!"); + return false; + } + + //First try to read in new format with measurementInterval + n = sscanf(data, "%llu,%hu,$GVSNSWHE,%llu,%f,%f,%f,%f,%f,%f,%f,%f,%x,%u,%x", + ×tamp, &countdown, &whtk.timestamp + ,&whtk.data[0], &whtk.data[1] + ,&whtk.data[2], &whtk.data[3] + ,&whtk.data[4], &whtk.data[5] + ,&whtk.data[6], &whtk.data[7] + ,&whtk.statusBits + ,&whtk.measurementInterval + ,&whtk.validityBits + ); + + if (n != 14) //14 fields to parse + { + //Else try to read in old format without measurementInterval + n = sscanf(data, "%llu,%hu,$GVSNSWHE,%llu,%f,%f,%f,%f,%f,%f,%f,%f,%x,%x", + ×tamp, &countdown, &whtk.timestamp + ,&whtk.data[0], &whtk.data[1] + ,&whtk.data[2], &whtk.data[3] + ,&whtk.data[4], &whtk.data[5] + ,&whtk.data[6], &whtk.data[7] + ,&whtk.statusBits + ,&whtk.validityBits + ); + + if (n != 13) //13 fields to parse + { + LOG_ERROR_MSG(gContext,"replayer: processGVSNSWHE failed!"); + return false; + } + } + + //buffered data handling + if (countdown < MAX_BUF_MSG) //enough space in buffer? + { + if (buf_size == 0) //a new sequence starts + { + buf_size = countdown+1; + last_countdown = countdown; + buf_whtk[buf_size-countdown-1] = whtk; + } + else if ((last_countdown-countdown) == 1) //sequence continued + { + last_countdown = countdown; + buf_whtk[buf_size-countdown-1] = whtk; + } + else //sequence interrupted: clear buffer + { + buf_size = 0; + last_countdown = 0; + } + } + else //clear buffer + { + buf_size = 0; + last_countdown = 0; + } + + if((countdown == 0) && (buf_size >0) ) + { + updateWheelData(buf_whtk, buf_size); + buf_size = 0; + last_countdown = 0; + } + + return true; +} + +static bool processGVSNSGYR(const char* data) +{ + //parse data like: 061074000,0$GVSNSGYR,061074000,-38.75,0,0,0,0X01 + + //storage for buffered data + static TGyroscopeData buf_gyro[MAX_BUF_MSG]; + static uint16_t buf_size = 0; + static uint16_t last_countdown = 0; + + uint64_t timestamp; + uint16_t countdown; + TGyroscopeData gyro = { 0 }; + int n = 0; + + if(!data ) + { + LOG_ERROR_MSG(gContext,"wrong parameter!"); + return false; + } + + //First try to read in new format with measurementInterval + n = sscanf(data, "%llu,%hu,$GVSNSGYR,%llu,%f,%f,%f,%f,%u,%x" + ,×tamp, &countdown, &gyro.timestamp + ,&gyro.yawRate + ,&gyro.pitchRate + ,&gyro.rollRate + ,&gyro.temperature + ,&gyro.measurementInterval + ,&gyro.validityBits + ); + if (n != 9) //9 fields to parse + { + //Else try to read in old format without measurementInterval + n = sscanf(data, "%llu,%hu,$GVSNSGYR,%llu,%f,%f,%f,%f,%x" + ,×tamp, &countdown, &gyro.timestamp + ,&gyro.yawRate + ,&gyro.pitchRate + ,&gyro.rollRate + ,&gyro.temperature + ,&gyro.validityBits + ); + + if (n != 8) //8 fields to parse + { + LOG_ERROR_MSG(gContext,"replayer: processGVSNSGYR failed!"); + return false; + } + } + + //buffered data handling + if (countdown < MAX_BUF_MSG) //enough space in buffer? + { + if (buf_size == 0) //a new sequence starts + { + buf_size = countdown+1; + last_countdown = countdown; + buf_gyro[buf_size-countdown-1] = gyro; + } + else if ((last_countdown-countdown) == 1) //sequence continued + { + last_countdown = countdown; + buf_gyro[buf_size-countdown-1] = gyro; + } + else //sequence interrupted: clear buffer + { + buf_size = 0; + last_countdown = 0; + } + } + else //clear buffer + { + buf_size = 0; + last_countdown = 0; + } + + if((countdown == 0) && (buf_size >0) ) + { + updateGyroscopeData(buf_gyro,buf_size); + buf_size = 0; + last_countdown = 0; + } + + return true; +} + + + +static bool processGVSNSVSP(const char* data) +{ + //parse data like: 061074000,0$GVSNSVSP,061074000,0.51,0X01 + + //storage for buffered data + static TVehicleSpeedData buf_vehsp[MAX_BUF_MSG]; + static uint16_t buf_size = 0; + static uint16_t last_countdown = 0; + + uint64_t timestamp; + uint16_t countdown; + TVehicleSpeedData vehsp = { 0 }; + int n = 0; + + if(!data) + { + LOG_ERROR_MSG(gContext,"wrong parameter!"); + return false; + } + + //First try to read in new format with measurementInterval + n = sscanf(data, "%llu,%hu,$GVSNSVSP,%llu,%f,%u,%x" + ,×tamp + ,&countdown + ,&vehsp.timestamp + ,&vehsp.vehicleSpeed + ,&vehsp.measurementInterval + ,&vehsp.validityBits + ); + + if (n != 6) //6 fields to parse + { + //Else try to read in old format without measurementInterval + n = sscanf(data, "%llu,%hu,$GVSNSVSP,%llu,%f,%x" + ,×tamp + ,&countdown + ,&vehsp.timestamp + ,&vehsp.vehicleSpeed + ,&vehsp.validityBits + ); + + if (n != 5) //5 fields to parse + { + LOG_ERROR_MSG(gContext,"replayer: processGVSNSVSP failed!"); + return false; + } + } + + //buffered data handling + if (countdown < MAX_BUF_MSG) //enough space in buffer? + { + if (buf_size == 0) //a new sequence starts + { + buf_size = countdown+1; + last_countdown = countdown; + buf_vehsp[buf_size-countdown-1] = vehsp; + } + else if ((last_countdown-countdown) == 1) //sequence continued + { + last_countdown = countdown; + buf_vehsp[buf_size-countdown-1] = vehsp; + } + else //sequence interrupted: clear buffer + { + buf_size = 0; + last_countdown = 0; + } + } + else //clear buffer + { + buf_size = 0; + last_countdown = 0; + } + + if((countdown == 0) && (buf_size >0) ) + { + updateVehicleSpeedData(buf_vehsp,buf_size); + buf_size = 0; + last_countdown = 0; + } + + return true; +} + +static void *listenForMessages( void *ptr ) +{ + struct sockaddr_in si_me; + struct sockaddr_in si_other; + socklen_t slen = sizeof(si_other); + ssize_t readBytes = 0; + char buf[BUFLEN+1]; //add space fer terminating \0 + char msgId[MSGIDLEN+1]; //add space fer terminating \0 + int port = PORT; + + DLT_REGISTER_APP("SNSS", "SENSOSRS-SERVICE"); + DLT_REGISTER_CONTEXT(gContext,"SSRV", "Global Context"); + + LOG_INFO(gContext,"SensorsService listening on port %d...",port); + + if((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) + { + LOG_ERROR_MSG(gContext,"socket() failed!"); + exit(EXIT_FAILURE); + } + + memset((char *) &si_me, 0, sizeof(si_me)); + si_me.sin_family = AF_INET; + + si_me.sin_port = htons(port); + si_me.sin_addr.s_addr = htonl(INADDR_ANY); + if(bind(s, (struct sockaddr *)&si_me, sizeof(si_me)) == -1) + { + LOG_ERROR_MSG(gContext,"socket() failed!"); + exit(EXIT_FAILURE); + } + + while(isRunning == true) + { + //use select to introduce a timeout - alloy shutdown even when no data are received + fd_set readfs; /* file descriptor set */ + int maxfd; /* maximum file desciptor used */ + int res; + struct timeval Timeout; + /* set timeout value within input loop */ + Timeout.tv_usec = 0; /* milliseconds */ + Timeout.tv_sec = 1; /* seconds */ + FD_SET(s, &readfs); + maxfd = s+1; + /* block until input becomes available */ + res = select(maxfd, &readfs, NULL, NULL, &Timeout); + + if (res > 0) + { + + readBytes = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen); + + if(readBytes < 0) + { + LOG_ERROR_MSG(gContext,"recvfrom() failed!"); + exit(EXIT_FAILURE); + } + + buf[readBytes] = '\0'; + + sscanf(buf, "%*[^'$']$%" STRINGIFY(MSGIDLEN) "[^',']", msgId); + + LOG_DEBUG(gContext,"Data:%s", buf); + + if(strcmp("GVSNSGYR", msgId) == 0) + { + processGVSNSGYR(buf); + } + else if(strcmp("GVSNSWHE", msgId) == 0) + { + processGVSNSWHE(buf); + } + else if(strcmp("GVSNSVSP", msgId) == 0) + { + processGVSNSVSP(buf); + } + } + } + + close(s); + + return EXIT_SUCCESS; +} + + + + diff --git a/src/sensors-service/vehicle-data.c b/src/sensors-service/vehicle-data.c new file mode 100644 index 0000000..fc6ea2b --- /dev/null +++ b/src/sensors-service/vehicle-data.c @@ -0,0 +1,68 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup SensorsService +* \author Helmut Schmidt <Helmut.3.Schmidt@continental-corporation.com> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "globals.h" +#include "vehicle-data.h" +#include "sns-meta-data.h" + +static pthread_mutex_t mutexCb = PTHREAD_MUTEX_INITIALIZER; //protects the callbacks +static pthread_mutex_t mutexData = PTHREAD_MUTEX_INITIALIZER; //protects the data + +TVehicleDataConfiguration gVehicleDataConfiguration = {0}; + + +bool iVehicleDataInit() +{ + + pthread_mutex_lock(&mutexData); + //example vehicle data configuration + gVehicleDataConfiguration.vehicleType = SNS_CAR; + gVehicleDataConfiguration.drivenAxles = SNS_AXLE_FRONT; + gVehicleDataConfiguration.trackWidth = 1.52; + gVehicleDataConfiguration.wheelBase = 2.31; + gVehicleDataConfiguration.validityBits = + VEHICLESTATUS_VEHICLETYPE_VALID | + VEHICLESTATUS_DRIVENAXLES_VALID | + VEHICLESTATUS_TRACKWIDTH_VALID | + VEHICLESTATUS_WHELLBASE_VALID; + pthread_mutex_unlock(&mutexData); + + return true; +} + +bool iVehicleDataDestroy() +{ + return true; +} + + +bool snsVehicleDataGetConfiguration(TVehicleDataConfiguration* vehicleDataConfiguration) +{ + bool retval = false; + + if(vehicleDataConfiguration) + { + pthread_mutex_lock(&mutexData); + *vehicleDataConfiguration = gVehicleDataConfiguration; + pthread_mutex_unlock(&mutexData); + retval = true; + } + + return retval; +} + diff --git a/src/sensors-service/vehicle-speed.c b/src/sensors-service/vehicle-speed.c new file mode 100644 index 0000000..994d69c --- /dev/null +++ b/src/sensors-service/vehicle-speed.c @@ -0,0 +1,181 @@ +/************************************************************************** +* Component Name: SensorsService +* Author: Marco Residori <marco.residori@xse.de> +* +* Copyright (C) 2013, XS Embedded GmbH +* +* License: +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +**************************************************************************/ + +#include "globals.h" +#include "vehicle-speed.h" +#include "sns-meta-data.h" + +static pthread_mutex_t mutexCb = PTHREAD_MUTEX_INITIALIZER; //protects the callbacks +static pthread_mutex_t mutexData = PTHREAD_MUTEX_INITIALIZER; //protects the data + +static volatile VehicleSpeedCallback cbVehicleSpeed = 0; +static TVehicleSpeedData gVehicleSpeedData = {0}; + +static TSensorStatus gStatus = {0}; +static volatile SensorStatusCallback cbStatus = 0; + +bool iVehicleSpeedInit() +{ + pthread_mutex_lock(&mutexCb); + cbVehicleSpeed = 0; + pthread_mutex_unlock(&mutexCb); + + pthread_mutex_lock(&mutexData); + gVehicleSpeedData.validityBits = 0; + pthread_mutex_unlock(&mutexData); + + return true; +} + +bool iVehicleSpeedDestroy() +{ + pthread_mutex_lock(&mutexCb); + cbVehicleSpeed = 0; + pthread_mutex_unlock(&mutexCb); + + return true; +} + +bool snsVehicleSpeedGetVehicleSpeedData(TVehicleSpeedData* vehicleSpeed) +{ + bool retval = false; + if(vehicleSpeed) + { + pthread_mutex_lock(&mutexData); + *vehicleSpeed = gVehicleSpeedData; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + +bool snsVehicleSpeedRegisterCallback(VehicleSpeedCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbVehicleSpeed) + { + cbVehicleSpeed = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsVehicleSpeedDeregisterCallback(VehicleSpeedCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbVehicleSpeed == callback) && callback) + { + cbVehicleSpeed = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsVehicleSpeedGetMetaData(TSensorMetaData *data) +{ + bool retval = false; + + if(data) + { + pthread_mutex_lock(&mutexData); + *data = gSensorsMetaData[2]; + pthread_mutex_unlock(&mutexData); + retval = true; + } + + return retval; +} + +void updateVehicleSpeedData(const TVehicleSpeedData vehicleSpeedData[], uint16_t numElements) +{ + if (vehicleSpeedData != NULL && numElements > 0) + { + pthread_mutex_lock(&mutexData); + gVehicleSpeedData = vehicleSpeedData[numElements-1]; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbVehicleSpeed) + { + cbVehicleSpeed(vehicleSpeedData, numElements); + } + pthread_mutex_unlock(&mutexCb); + } +} + +bool snsVehicleSpeedGetStatus(TSensorStatus* status){ + bool retval = false; + if(status) + { + pthread_mutex_lock(&mutexData); + *status = gStatus; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + +bool snsVehicleSpeedRegisterStatusCallback(SensorStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbStatus) + { + cbStatus = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsVehicleSpeedDeregisterStatusCallback(SensorStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbStatus == callback) && callback) + { + cbStatus = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +void updateVehicleSpeedStatus(const TSensorStatus* status) +{ + if (status) + { + pthread_mutex_lock(&mutexData); + gStatus = *status; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbStatus) + { + cbStatus(status); + } + pthread_mutex_unlock(&mutexCb); + } +}
\ No newline at end of file diff --git a/src/sensors-service/wheeltick.c b/src/sensors-service/wheeltick.c new file mode 100644 index 0000000..d582d92 --- /dev/null +++ b/src/sensors-service/wheeltick.c @@ -0,0 +1,172 @@ +/************************************************************************** +* @licence app begin@ +* +* SPDX-License-Identifier: MPL-2.0 +* +* \ingroup SensorsService +* \author Marco Residori <marco.residori@xse.de> +* +* \copyright Copyright (C) 2013, XS Embedded GmbH +* +* \license +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* @licence end@ +**************************************************************************/ + +#include "globals.h" +#include "wheel.h" + +static pthread_mutex_t mutexCb = PTHREAD_MUTEX_INITIALIZER; //protects the callbacks +static pthread_mutex_t mutexData = PTHREAD_MUTEX_INITIALIZER; //protects the data + +static volatile WheelCallback cbWheel = 0; +static TWheelData gWheelData = {0}; + +static TSensorStatus gStatus = {0}; +static volatile SensorStatusCallback cbStatus = 0; + +bool iWheelInit() +{ + int i; + + pthread_mutex_lock(&mutexCb); + cbWheel = 0; + pthread_mutex_unlock(&mutexCb); + + pthread_mutex_lock(&mutexData); + gWheelData.validityBits = 0; + pthread_mutex_unlock(&mutexData); + + return true; +} + +bool iWheelDestroy() +{ + pthread_mutex_lock(&mutexCb); + cbWheel = 0; + pthread_mutex_unlock(&mutexCb); + + return true; +} + +bool snsWheelGetWheelData(TWheelData *wheelData) +{ + bool retval = false; + if(wheelData) + { + pthread_mutex_lock(&mutexData); + *wheelData = gWheelData; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + +bool snsWheelRegisterCallback(WheelCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbWheel) + { + cbWheel = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsWheelDeregisterCallback(WheelCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbWheel == callback) && callback) + { + cbWheel = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +void updateWheelData(const TWheelData wheelData[], uint16_t numElements) +{ + if (wheelData != NULL && numElements > 0) + { + pthread_mutex_lock(&mutexData); + gWheelData = wheelData[numElements-1]; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbWheel) + { + cbWheel(wheelData, numElements); + } + pthread_mutex_unlock(&mutexCb); + } +} + +bool snsWheelGetStatus(TSensorStatus* status){ + bool retval = false; + if(status) + { + pthread_mutex_lock(&mutexData); + *status = gStatus; + pthread_mutex_unlock(&mutexData); + retval = true; + } + return retval; +} + +bool snsWheelRegisterStatusCallback(SensorStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + //only if valid callback and not already registered + if(callback && !cbStatus) + { + cbStatus = callback; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +bool snsWheelDeregisterStatusCallback(SensorStatusCallback callback) +{ + bool retval = false; + + pthread_mutex_lock(&mutexCb); + if((cbStatus == callback) && callback) + { + cbStatus = 0; + retval = true; + } + pthread_mutex_unlock(&mutexCb); + + return retval; +} + +void updateWheelStatus(const TSensorStatus* status) +{ + if (status) + { + pthread_mutex_lock(&mutexData); + gStatus = *status; + pthread_mutex_unlock(&mutexData); + pthread_mutex_lock(&mutexCb); + if (cbStatus) + { + cbStatus(status); + } + pthread_mutex_unlock(&mutexCb); + } +}
\ No newline at end of file diff --git a/src/set_window_location b/src/set_window_location index d43fd1b..67fdf3a 100755 --- a/src/set_window_location +++ b/src/set_window_location @@ -7,10 +7,10 @@ function get_window_id() } get_window_id "fsa" -wmctrl -i -r "$window_id" -e 0,100,100,800,480 +wmctrl -i -r "$window_id" -e 0,50,50,800,480 get_window_id "navit" -wmctrl -i -r "$window_id" -e 0,100,72,800,480 +wmctrl -i -r "$window_id" -e 0,50,22,800,480 wmctrl -a "fsa" diff --git a/src/update_third_party.sh b/src/update_third_party.sh index 0e34bc4..0325475 100755 --- a/src/update_third_party.sh +++ b/src/update_third_party.sh @@ -1,8 +1,8 @@ #!/bin/bash -navigation_version='03a340b57c464301689f39e7d11e7833a9c4d87d' +navigation_version='95468b727e3f6c2f5ddfed7e682a2e3e5edc81f4' positioning_version='d4c46f13019aefb11aebd0fc1210a29a46f0b521' -navit_version='77b0b67935ae90d4fcb8f2cf4a07cd6dc1bed9b7' +navit_version='03f3aa8637fff3e8e09d3bde21b28654454011fd' echo "version of navigation is: $navigation_version" echo "version of positioning is: $positioning_version" diff --git a/test/resource/high-tank-level.log b/test/resource/high-tank-level.log index 28e8c12..fcc6b63 100644 --- a/test/resource/high-tank-level.log +++ b/test/resource/high-tank-level.log @@ -15,7 +15,7 @@ 0,0$GVSNSVER,2,0,0 0,0$GVVEHVER,0,0,0 1000,0$GVGNSP,1000,46.202038, 6.146845,0,0X03 -1000,0$GVSNSVEHSP,1000,90.00,0X01 +1000,0$GVSNSVSP,1000,90.00,0X01 1000,0$GVVEHENGSPEED,2000,0X01 1000,0$GVVEHFUELLEVEL,30,0X01 1000,0$GVVEHFUELCONS,1500,0X01 diff --git a/test/resource/initialization.log b/test/resource/initialization.log index a9f9485..f63dbd1 100644 --- a/test/resource/initialization.log +++ b/test/resource/initialization.log @@ -15,7 +15,7 @@ 0,0$GVSNSVER,2,0,0 0,0$GVVEHVER,0,0,0 1000,0$GVGNSP,1000,46.202038, 6.146845,0,0X03 -1000,0$GVSNSVEHSP,1000,0.00,0X01 +1000,0$GVSNSVSP,1000,0.00,0X01 1000,0$GVVEHENGSPEED,800,0X01 1000,0$GVVEHFUELLEVEL,30,0X01 1000,0$GVVEHFUELCONS,100,0X01 diff --git a/test/resource/low-tank-level.log b/test/resource/low-tank-level.log index c0bd98e..27b7ade 100644 --- a/test/resource/low-tank-level.log +++ b/test/resource/low-tank-level.log @@ -15,7 +15,7 @@ 0,0$GVSNSVER,2,0,0 0,0$GVVEHVER,0,0,0 1000,0$GVGNSP,1000,46.202038, 6.146845,0,0X03 -1000,0$GVSNSVEHSP,1000,90.00,0X01 +1000,0$GVSNSVSP,1000,90.00,0X01 1000,0$GVVEHENGSPEED,2000,0X01 1000,0$GVVEHFUELLEVEL,4,0X01 1000,0$GVVEHFUELCONS,1500,0X01 diff --git a/test/resource/start.log b/test/resource/start.log index aeda148..f8b05cb 100644 --- a/test/resource/start.log +++ b/test/resource/start.log @@ -15,7 +15,7 @@ 0,0$GVSNSVER,2,0,0 0,0$GVVEHVER,0,0,0 1000,0$GVGNSP,1000,46.202038, 6.146845,0,0X03 -1000,0$GVSNSVEHSP,1000,0.00,0X01 +1000,0$GVSNSVSP,1000,0.00,0X01 1000,0$GVVEHENGSPEED,0,0X01 1000,0$GVVEHFUELLEVEL,30,0X01 1000,0$GVVEHFUELCONS,0,0X01 diff --git a/test/resource/test-positioning.log b/test/resource/test-positioning.log index a92b8bc..324cf1c 100644 --- a/test/resource/test-positioning.log +++ b/test/resource/test-positioning.log @@ -8,5 +8,5 @@ 0,0$GVGNSVER,2,0,0 0,0$GVSNSVER,2,0,0 1000,0$GVGNSP,1000,46.202038, 6.146845,0,0X03 -1000,0$GVSNSVEHSP,1000,0.00,0X01 +1000,0$GVSNSVSP,1000,0.00,0X01 diff --git a/test/script/configTests.py b/test/script/configTests.py index 5ac190c..a3d312c 100755 --- a/test/script/configTests.py +++ b/test/script/configTests.py @@ -29,12 +29,12 @@ import subprocess,os from subprocess import call -PATH_LOGREPLAYER='../../src/navigation/src/navigation/bin/' +PATH_LOGREPLAYER='../../src/log-replayer-server/bin/' PATH_LOGFILES='../resource/' def launch(file,host): FNULL = open(os.devnull,'w') - logreplayer=PATH_LOGREPLAYER + 'log-replayer' + logreplayer=PATH_LOGREPLAYER + 'log-replayer-server' file=PATH_LOGFILES + file call([logreplayer, file, host]) |