Skip to content

Commit

Permalink
Upstream fixes for daemon and others
Browse files Browse the repository at this point in the history
doc: Use DLT in library

common:Fix dlt.conf parse

unittest: Use env var in gateway gtest

qnx: timer pipes could be invalid

daemon: Print errno on failure

daemon: Remove unnecessary semaphore

daemon: Handle partial message parsing in receiver buffer

daemon: overflow message should be sent one

system: zero initialize configuration variables

Signed-off-by: LUU QUANG MINH <[email protected]>
  • Loading branch information
LUU QUANG MINH authored and LUU QUANG MINH committed Jul 24, 2023
1 parent b142823 commit ffc46c5
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 65 deletions.
34 changes: 34 additions & 0 deletions doc/dlt_for_developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Table of Contents
5. [DLT API Usage](#DLT-API-Usage)
6. [DLT injection messages](#DLT-Injection-Messages)
7. [Log level changed callback](#Log-level-changed-callback)
8. [Disable injection messages](#Disable-injection-messages)
9. [Use DLT in library](#Use-DLT-in-library)

## DLT Example Application

Expand Down Expand Up @@ -989,6 +991,7 @@ context changed. The usage is similar to DLT\_REGISTER\_INJECTION\_CALLBACK.
```
DLT_REGISTER_LOG_LEVEL_CHANGED_CALLBACK(CONTEXT, CALLBACK)
```

## Disable injection messages

An environment variable named `DLT_DISABLE_INJECTION_MSG_AT_USER` could be used in case
Expand All @@ -1005,3 +1008,34 @@ To clear:
```
unset DLT_DISABLE_INJECTION_MSG_AT_USER
```

## Use DLT in library

There are cases where a library wants to use DLT interface to output its log message.
In such case, applications and contexts can be registered using following way.

### Application registration

The library can check if an application is already registered or not by
`DLT_GET_APPID()` API. If returned application ID is not NULL, it can be considered
that application was already registered previously. If it's NULL, then application
can be registered.

```Example
// Check if an application is already registered in this process
char appid[DLT_ID_SIZE];
DLT_GET_APPID(&appid);
if (appid[0] != '\0')
{
printf("Application is already registered with AppID=[%s]\n", appid);
}
else
{
DLT_REGISTER_APP("APP", "Application for library xxx");
}
```

### Context registration

The same context ID can be used among different applications, so context can be
registered as usual.
8 changes: 6 additions & 2 deletions src/console/dlt-control-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@

#define DLT_CTRL_APID "DLTC"
#define DLT_CTRL_CTID "DLTC"
#define DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH "/tmp/dlt-ctrl.sock"

/** @brief Analyze the daemon answer
*
Expand All @@ -98,6 +97,7 @@ static pthread_cond_t answer_cond = PTHREAD_COND_INITIALIZER;
static int local_verbose;
static char local_ecuid[DLT_CTRL_ECUID_LEN]; /* Name of ECU */
static int local_timeout;
static char local_filename[DLT_MOUNT_PATH_MAX]= {0}; /* Path to dlt.conf */

int get_verbosity(void)
{
Expand Down Expand Up @@ -181,7 +181,11 @@ int dlt_parse_config_param(char *config_id, char **config_data)
*config_data = NULL;

/* open configuration file */
filename = CONFIGURATION_FILES_DIR "/dlt.conf";
if (local_filename[0] != 0) {
filename = local_filename;
} else {
filename = CONFIGURATION_FILES_DIR "/dlt.conf";
}
pFile = fopen(filename, "r");

if (pFile != NULL) {
Expand Down
2 changes: 2 additions & 0 deletions src/console/dlt-control-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@

#define DLT_CTRL_DEFAULT_ECUID "ECU1"

#define DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH "/tmp/dlt-ctrl.sock"

#define NANOSEC_PER_MILLISEC 1000000
#define NANOSEC_PER_SEC 1000000000

Expand Down
13 changes: 8 additions & 5 deletions src/console/dlt-control.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,14 @@ int main(int argc, char *argv[])
{
g_dltclient.mode = DLT_CLIENT_MODE_UNIX;
g_dltclient.socketPath = NULL;
dlt_parse_config_param("ControlSocketPath", &g_dltclient.socketPath);
if (dlt_parse_config_param("ControlSocketPath",
&g_dltclient.socketPath) == DLT_RETURN_ERROR) {
/* Failed to read from conf, copy default */
if (dlt_client_set_socket_path(&g_dltclient, DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH) == -1) {
pr_error("set socket path didn't succeed\n");
return -1;
}
}
}
else {
g_dltclient.mode = DLT_CLIENT_MODE_TCP;
Expand All @@ -508,8 +515,6 @@ int main(int argc, char *argv[])
return -1;
}



if (g_dltclient.servIP == 0) {
/* no hostname selected, show usage and terminate */
fprintf(stderr, "ERROR: No hostname selected\n");
Expand All @@ -526,8 +531,6 @@ int main(int argc, char *argv[])
return -1;
}



if (g_dltclient.serialDevice == 0) {
/* no serial device name selected, show usage and terminate */
fprintf(stderr, "ERROR: No serial device name specified\n");
Expand Down
20 changes: 13 additions & 7 deletions src/daemon/dlt-daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1490,12 +1490,6 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in
if (daemon_local->flags.sendMessageTime)
daemon->timingpackets = 1;

/* Binary semaphore for thread */
if (sem_init(&dlt_daemon_mutex, 0, 1) == -1) {
dlt_log(LOG_ERR, "Could not initialize binary semaphore\n");
return -1;
}

/* Get ECU version info from a file. If it fails, use dlt_version as fallback. */
if (dlt_daemon_local_ecu_version_init(daemon, daemon_local, daemon_local->flags.vflag) < 0) {
daemon->ECUVersionString = malloc(DLT_DAEMON_TEXTBUFSIZE);
Expand Down Expand Up @@ -3457,6 +3451,17 @@ int dlt_daemon_process_user_message_log(DltDaemon *daemon,
* or the headers are corrupted (error case). */
dlt_log(LOG_DEBUG, "Can't read messages from receiver\n");

if (dlt_receiver_remove(rec, rec->bytesRcvd) != DLT_RETURN_OK) {
/* In certain rare scenarios where only a partial message has been received
* (Eg: kernel IPC buffer memory being full), we want to discard the message
* and not broadcast it forward to connected clients. Since the DLT library
* checks return value of the writev() call against the sent total message
* length, the partial message will be buffered and retransmitted again.
* This implicitly ensures that no message loss occurs.
*/
dlt_log(LOG_WARNING, "failed to remove required bytes from receiver.\n");
}

return DLT_DAEMON_ERROR_UNKNOWN;
}

Expand Down Expand Up @@ -3736,7 +3741,8 @@ static void *timer_thread(void *data)
}

while (1) {
if (0 > write(dlt_timer_pipes[timer_thread_data->timer_id][1], "1", 1)) {
if ((dlt_timer_pipes[timer_thread_data->timer_id][1] > 0) &&
(0 > write(dlt_timer_pipes[timer_thread_data->timer_id][1], "1", 1))) {
dlt_vlog(LOG_ERR, "Failed to send notification for timer [%s]!\n",
dlt_timer_names[timer_thread_data->timer_id]);
pexit = 1;
Expand Down
53 changes: 26 additions & 27 deletions src/daemon/dlt_daemon_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,19 +129,16 @@ static int dlt_daemon_client_send_all_multiple(DltDaemon *daemon,

if ((temp == NULL) || (temp->receiver == NULL) ||
!((1 << temp->type) & type_mask)) {
dlt_vlog(LOG_DEBUG, "The connection not found or the connection type not TCP/Serial.\n");
dlt_log(LOG_DEBUG, "The connection not found or the connection type not TCP/Serial.\n");
continue;
}

DLT_DAEMON_SEM_LOCK();

ret = dlt_connection_send_multiple(temp,
data1,
size1,
data2,
size2,
daemon->sendserialheader);
DLT_DAEMON_SEM_FREE();

if ((ret != DLT_DAEMON_ERROR_OK) &&
(DLT_CONNECTION_CLIENT_MSG_TCP == temp->type)) {
Expand Down Expand Up @@ -175,6 +172,7 @@ int dlt_daemon_client_send(int sock,
int verbose)
{
int sent, ret;
static int sent_message_overflow_cnt = 0;

if ((daemon == NULL) || (daemon_local == NULL)) {
dlt_vlog(LOG_ERR, "%s: Invalid arguments\n", __func__);
Expand All @@ -184,26 +182,19 @@ int dlt_daemon_client_send(int sock,
if ((sock != DLT_DAEMON_SEND_TO_ALL) && (sock != DLT_DAEMON_SEND_FORCE)) {
/* Send message to specific socket */
if (isatty(sock)) {
DLT_DAEMON_SEM_LOCK();

if ((ret = dlt_daemon_serial_send(sock, data1, size1, data2, size2, (char) daemon->sendserialheader))) {
DLT_DAEMON_SEM_FREE();
if ((ret =
dlt_daemon_serial_send(sock, data1, size1, data2, size2,
daemon->sendserialheader))) {
dlt_vlog(LOG_WARNING, "%s: serial send dlt message failed\n", __func__);
return ret;
}

DLT_DAEMON_SEM_FREE();
}
else {
DLT_DAEMON_SEM_LOCK();

if ((ret = dlt_daemon_socket_send(sock, data1, size1, data2, size2, (char) daemon->sendserialheader))) {
DLT_DAEMON_SEM_FREE();
} else {
if ((ret =
dlt_daemon_socket_send(sock, data1, size1, data2, size2,
daemon->sendserialheader))) {
dlt_vlog(LOG_WARNING, "%s: socket send dlt message failed\n", __func__);
return ret;
}

DLT_DAEMON_SEM_FREE();
}

return DLT_DAEMON_ERROR_OK;
Expand Down Expand Up @@ -275,11 +266,8 @@ int dlt_daemon_client_send(int sock,
((daemon->state == DLT_DAEMON_STATE_BUFFER) || (daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) ||
(daemon->state == DLT_DAEMON_STATE_BUFFER_FULL))) {
if (daemon->state != DLT_DAEMON_STATE_BUFFER_FULL) {
DLT_DAEMON_SEM_LOCK();
/* Store message in history buffer */
ret = dlt_buffer_push3(&(daemon->client_ringbuffer), data1, (unsigned int) size1, data2, (unsigned int) size2, 0, 0);
DLT_DAEMON_SEM_FREE();

ret = dlt_buffer_push3(&(daemon->client_ringbuffer), data1, size1, data2, size2, 0, 0);
if (ret < DLT_RETURN_OK) {
dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_BUFFER_FULL);
}
Expand All @@ -293,11 +281,22 @@ int dlt_daemon_client_send(int sock,
}
} else {
if ((daemon->overflow_counter > 0) &&
(daemon_local->client_connections > 0) &&
(dlt_daemon_send_message_overflow(daemon, daemon_local, verbose) == DLT_DAEMON_ERROR_OK)) {
dlt_vlog(LOG_WARNING, "%s: %u messages discarded! Now able to send messages to the client.\n",
__func__, daemon->overflow_counter);
daemon->overflow_counter = 0;
(daemon_local->client_connections > 0)) {
sent_message_overflow_cnt++;
if (sent_message_overflow_cnt >= 2) {
sent_message_overflow_cnt--;
}
else {
if (dlt_daemon_send_message_overflow(daemon, daemon_local,
verbose) == DLT_DAEMON_ERROR_OK) {
dlt_vlog(LOG_WARNING,
"%s: %u messages discarded! Now able to send messages to the client.\n",
__func__,
daemon->overflow_counter);
daemon->overflow_counter = 0;
sent_message_overflow_cnt--;
}
}
}
}

Expand Down
1 change: 0 additions & 1 deletion src/daemon/dlt_daemon_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@
#include "dlt_daemon_serial.h"

char *app_recv_buffer = NULL; /* pointer to receiver buffer for application msges */
sem_t dlt_daemon_mutex;

static int dlt_daemon_cmp_apid(const void *m1, const void *m2)
{
Expand Down
10 changes: 0 additions & 10 deletions src/daemon/dlt_daemon_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,6 @@ extern "C" {
# define DLT_DAEMON_SEND_TO_ALL -3/**< Constant value to identify the command "send to all" */
# define DLT_DAEMON_SEND_FORCE -4/**< Constant value to identify the command "send force to all" */

/* Use a semaphore or mutex from your OS to prevent concurrent access to the DLT buffer. */

#define DLT_DAEMON_SEM_LOCK() do{\
while ((sem_wait(&dlt_daemon_mutex) == -1) && (errno == EINTR)) \
continue; /* Restart if interrupted */ \
} while(false)

#define DLT_DAEMON_SEM_FREE() { sem_post(&dlt_daemon_mutex); }
extern sem_t dlt_daemon_mutex;

/* UDPMulticart Default IP and Port */
# ifdef UDP_CONNECTION_SUPPORT
# define MULTICASTIPADDRESS "225.0.0.37"
Expand Down
6 changes: 4 additions & 2 deletions src/daemon/dlt_daemon_unix_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,14 @@ int dlt_daemon_unix_socket_open(int *sock, char *sock_path, int type, int mask)
old_mask = umask(mask);

if (bind(*sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
dlt_log(LOG_WARNING, "unix socket: bind() error");
dlt_vlog(LOG_WARNING, "%s: bind() error (%s)\n", __func__,
strerror(errno));
return -1;
}

if (listen(*sock, 1) == -1) {
dlt_log(LOG_WARNING, "unix socket: listen error");
dlt_vlog(LOG_WARNING, "%s: listen error (%s)\n", __func__,
strerror(errno));
return -1;
}

Expand Down
2 changes: 1 addition & 1 deletion src/system/dlt-system-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

/*******************************************************************************
** **
** SRC-MODULE: dlt-system-options.c **
** SRC-MODULE: dlt-system-options.c **
** **
** TARGET : linux **
** **
Expand Down
4 changes: 2 additions & 2 deletions src/system/dlt-system.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ DLT_DECLARE_CONTEXT(dltsystem)

int main(int argc, char *argv[])
{
DltSystemCliOptions options;
DltSystemConfiguration config;
DltSystemCliOptions options = {0};
DltSystemConfiguration config = {0};

#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
int ret;
Expand Down
8 changes: 4 additions & 4 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ set(TARGET_LIST gtest_dlt_common
foreach(target IN LISTS TARGET_LIST)
set(target_SRCS ${target})
if(${target} STREQUAL "gtest_dlt_daemon_common")
set(target_SRCS ${target_SRCS} ../src/daemon/dlt_daemon_common.c)
set(target_SRCS ${target_SRCS} ${PROJECT_SOURCE_DIR}/src/daemon/dlt_daemon_common.c)
endif()
add_executable(${target} ${target_SRCS})
target_link_libraries(${target} ${DLT_LIBRARIES})
Expand Down Expand Up @@ -91,12 +91,12 @@ endforeach()
# DLT control tests
#####################
if(WITH_EXTENDED_FILTERING)
configure_file(${PROJECT_SOURCE_DIR}/tests/testfile_extended.dlt ${PROJECT_BINARY_DIR}/tests COPYONLY)
configure_file(${PROJECT_SOURCE_DIR}/tests/testfilter.json ${PROJECT_BINARY_DIR}/tests COPYONLY)
configure_file(${PROJECT_SOURCE_DIR}/tests/testfile_extended.dlt ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
configure_file(${PROJECT_SOURCE_DIR}/tests/testfilter.json ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)

add_executable(gtest_dlt_json_filter gtest_dlt_json_filter.cpp)
target_link_libraries(gtest_dlt_json_filter ${DLT_CONTROL_LIBRARIES})
add_test(NAME gtest_dlt_json_filter
COMMAND gtest_dlt_json_filter)
set_tests_properties(${target} PROPERTIES TIMEOUT "${seconds}")
endif()

Loading

0 comments on commit ffc46c5

Please sign in to comment.