summaryrefslogtreecommitdiff
path: root/src/gnss-service
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 /src/gnss-service
parenta4938ffa0e6d15aed58645f57b2645bc0a61527a (diff)
downloadnavigation-a3fbfa55230fa64d499a6b7a4da6d8b4fa468230.tar.gz
some improvements to make it easier to maintain
Diffstat (limited to 'src/gnss-service')
-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
6 files changed, 1414 insertions, 0 deletions
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 */