summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorasanoaozora <fifitaneki@hotmail.com>2018-05-30 16:40:00 +0200
committerasanoaozora <fifitaneki@hotmail.com>2018-05-30 16:40:00 +0200
commita3fbfa55230fa64d499a6b7a4da6d8b4fa468230 (patch)
tree37d50fd2278d6646447c261ee61d74ba96160da1
parenta4938ffa0e6d15aed58645f57b2645bc0a61527a (diff)
downloadnavigation-a3fbfa55230fa64d499a6b7a4da6d8b4fa468230.tar.gz
some improvements to make it easier to maintain
-rw-r--r--src/.gitignore3
-rw-r--r--src/CMakeLists.txt20
-rw-r--r--src/dead-reckoning/CMakeLists.txt78
-rw-r--r--src/dead-reckoning/configuration.cpp208
-rw-r--r--src/dead-reckoning/configuration.h56
-rw-r--r--src/dead-reckoning/enhanced-position.cpp447
-rw-r--r--src/dead-reckoning/enhanced-position.h65
-rw-r--r--src/dead-reckoning/log.h154
-rw-r--r--src/dead-reckoning/main.cpp118
-rw-r--r--src/dead-reckoning/position-feedback.cpp60
-rw-r--r--src/dead-reckoning/position-feedback.h50
-rw-r--r--src/genivilogreplayer/CMakeLists.txt12
-rw-r--r--src/gnss-service/CMakeLists.txt60
-rw-r--r--src/gnss-service/globals.h49
-rw-r--r--src/gnss-service/gnss-impl.c331
-rw-r--r--src/gnss-service/gnss-meta-data.c41
-rw-r--r--src/gnss-service/gnss-use-replayer.c779
-rw-r--r--src/gnss-service/log.h154
-rw-r--r--src/hmi/config/fsa_giromagny.conf24
-rw-r--r--src/hmi/hmi-launcher/CMakeLists.txt13
-rw-r--r--src/log-replayer-server/CMakeLists.txt53
-rw-r--r--src/log-replayer-server/log-replayer-server.cpp202
-rw-r--r--src/log-replayer-server/log.h154
-rwxr-xr-xsrc/run65
-rw-r--r--src/sensors-service/CMakeLists.txt77
-rw-r--r--src/sensors-service/acceleration.c220
-rw-r--r--src/sensors-service/globals.h67
-rw-r--r--src/sensors-service/gyroscope.c217
-rw-r--r--src/sensors-service/log.h154
-rw-r--r--src/sensors-service/sns-meta-data.c48
-rw-r--r--src/sensors-service/sns-use-replayer.c517
-rw-r--r--src/sensors-service/vehicle-data.c68
-rw-r--r--src/sensors-service/vehicle-speed.c181
-rw-r--r--src/sensors-service/wheeltick.c172
-rwxr-xr-xsrc/set_window_location4
-rwxr-xr-xsrc/update_third_party.sh4
-rw-r--r--test/resource/high-tank-level.log2
-rw-r--r--test/resource/initialization.log2
-rw-r--r--test/resource/low-tank-level.log2
-rw-r--r--test/resource/start.log2
-rw-r--r--test/resource/test-positioning.log2
-rwxr-xr-xtest/script/configTests.py4
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",
+ &timestamp,
+ &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",
+ &timestamp,
+ &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",
+ &timestamp,
+ &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",
+ &timestamp, &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", &timestamp, &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", &timestamp, &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",
+ &timestamp, &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", &timestamp, &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", &timestamp))
+ {
+ 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 */
diff --git a/src/run b/src/run
index 2f352dc..97f906a 100755
--- a/src/run
+++ b/src/run
@@ -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",
+ &timestamp, &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",
+ &timestamp, &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"
+ ,&timestamp, &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"
+ ,&timestamp, &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"
+ ,&timestamp
+ ,&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"
+ ,&timestamp
+ ,&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])