diff options
Diffstat (limited to 'src/console/dlt-passive-node-ctrl.c')
-rw-r--r-- | src/console/dlt-passive-node-ctrl.c | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/src/console/dlt-passive-node-ctrl.c b/src/console/dlt-passive-node-ctrl.c new file mode 100644 index 0000000..db12085 --- /dev/null +++ b/src/console/dlt-passive-node-ctrl.c @@ -0,0 +1,457 @@ +/** + * @licence app begin@ + * Copyright (C) 2015 Advanced Driver Information Technology. + * This code is developed by Advanced Driver Information Technology. + * Copyright of Advanced Driver Information Technology, Bosch and DENSO. + * + * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. + * + * + * \copyright + * 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/. + * + * + * \author Christoph Lipka <clipka@jp.adit-jv.com> ADIT 2015 + * + * \file dlt-passive-node-ctrl.c + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +/******************************************************************************* +** ** +** SRC-MODULE: dlt-passive-node-ctrl.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Christoph Lipka <clipka@jp.adit-jv.com> ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** CL Christoph Lipka ADIT ** +*******************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <pthread.h> +#include "dlt_protocol.h" +#include "dlt_client.h" +#include "dlt-control-common.h" +#include "dlt_daemon_connection_types.h" + +#define MAX_RESPONSE_LENGTH 32 + +#define DLT_NODE_CONNECT 1 +#define DLT_NODE_DISCONNECT 0 +#define DLT_NODE_CONNECT_UNDEF 999 + +#define DLT_GATEWAY_CONNECTED 2 +#define DLT_NODE_CONNECTED_STR "Connected" +#define DLT_NODE_DISCONNECTED_STR "Disconnected" + +#define UNDEFINED 999 + +static struct PassiveNodeOptions { + unsigned int command; /**< passive node control command */ + unsigned int connection_state; /**< connection state */ + char node_id[DLT_ID_SIZE]; /**< node identifier */ + long timeout; /**< Default timeout */ +} g_options = { + .command = UNDEFINED, + .connection_state = UNDEFINED, + .node_id = {'\0'}, +}; + +unsigned int get_command(void) +{ + return g_options.command; +} + +void set_command(unsigned int c) +{ + g_options.command = c; +} + +unsigned int get_connection_state(void) +{ + return g_options.connection_state; +} + +void set_connection_state(unsigned int s) +{ + if ((s == DLT_NODE_CONNECT) || (s == DLT_NODE_DISCONNECT)) + { + g_options.connection_state = s; + set_command(DLT_SERVICE_ID_PASSIVE_NODE_CONNECT); + } + else + { + pr_error("Connection status %u invalid\n", s); + exit(-1); + } +} + +void set_node_id(char *id) +{ + if (id == 0) + { + pr_error("node identifier is NULL\n"); + exit(-1); + } + else + { + strncpy(g_options.node_id, id, DLT_ID_SIZE); + } +} + +char *get_node_id() +{ + return g_options.node_id; +} + +/** + * @brief Print passive node status information + * + * @param info DltServicePassiveNodeConnectionInfo + */ +static void dlt_print_passive_node_status( + DltServicePassiveNodeConnectionInfo *info) +{ + unsigned int i = 0; + char *status; + + if (info == NULL) + { + return; + } + + printf("\nPassive Node connection status:\n" + "---------------------------------\n"); + for(i = 0; i < info->num_connections; i++) + { + if (info->connection_status[i] == DLT_GATEWAY_CONNECTED) + { + status = DLT_NODE_CONNECTED_STR; + } + else + { + status = DLT_NODE_DISCONNECTED_STR; + } + + printf("%.4s: %s\n", &info->node_id[i * DLT_ID_SIZE], status); + } + + printf("\n"); +} + +/** + * @brief Analyze received DLT Daemon response + * + * This function checks the received message. In particular, it checks the + * answer string 'service(<ID>, {ok, error, perm_denied})'. In any case the + * g_callback_return variable will be set as well which is evaluated in the + * main function after the communication thread returned. + * + * @param message Received DLT Message + * @return 0 if daemon returns 'ok' message, -1 otherwise + */ +static int dlt_passive_node_analyze_response(char *answer, + void *payload, + int len) +{ + int ret = -1; + char resp_ok[MAX_RESPONSE_LENGTH] = { 0 }; + + if (answer == NULL || payload == NULL) + { + return -1; + } + + snprintf(resp_ok, + MAX_RESPONSE_LENGTH, + "service(%u), ok", + get_command()); + + pr_verbose("Response received: '%s'\n", answer); + pr_verbose("Response expected: '%s'\n", resp_ok); + + if (strncmp(answer, resp_ok, strlen(resp_ok)) == 0) + { + ret = 0; + + if (get_command() == DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS) + { + if ((int)sizeof(DltServicePassiveNodeConnectionInfo) > len) + { + pr_error("Received payload is smaller than expected\n"); + pr_verbose("Expected: %lu,\nreceived: %d", + sizeof(DltServicePassiveNodeConnectionInfo), + len); + ret = -1; + } + else + { + DltServicePassiveNodeConnectionInfo *info = + (DltServicePassiveNodeConnectionInfo *) (payload); + if (info == NULL) + { + fprintf(stderr, "Received response is NULL\n"); + return -1; + } + + dlt_print_passive_node_status(info); + } + } + } + + return ret; +} + +/** + * @brief Prepare message body to be send to DLT Daemon + * + * @return Pointer ot DltControlMsgBody, NULL otherwise + */ +DltControlMsgBody *dlt_passive_node_prepare_message_body() +{ + DltControlMsgBody *mb = calloc(1, sizeof(DltControlMsgBody)); + char *ecuid = get_node_id(); + if (mb == NULL) + { + return NULL; + } + + if (get_command() == DLT_SERVICE_ID_PASSIVE_NODE_CONNECT) + { + mb->data = calloc(1, sizeof(DltServicePassiveNodeConnect)); + if (mb->data == NULL) + { + free(mb); + return NULL; + } + mb->size = sizeof(DltServicePassiveNodeConnect); + DltServicePassiveNodeConnect *serv = (DltServicePassiveNodeConnect *) + mb->data; + serv->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT; + serv->connection_status = get_connection_state(); + + memcpy(serv->node_id, ecuid, DLT_ID_SIZE); + } + else /* DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS */ + { + mb->data = calloc(1, sizeof(DltServicePassiveNodeConnectionInfo)); + if (mb->data == NULL) + { + free(mb); + return NULL; + } + + mb->size = sizeof(DltServicePassiveNodeConnectionInfo); + DltServicePassiveNodeConnectionInfo *serv = + (DltServicePassiveNodeConnectionInfo *) mb->data; + serv->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS; + } + + return mb; +} + +/** + * @brief Destroy message body + */ +void dlt_passive_node_destroy_message_body(DltControlMsgBody *msg_body) +{ + if (msg_body == NULL) + { + return; + } + + if (msg_body->data != NULL) + { + free(msg_body->data); + } + free(msg_body); +} + +/** + * @brief Send a single command to DLT daemon and wait for response + * + * @return 0 on success, -1 on error + */ +static int dlt_passive_node_ctrl_single_request() +{ + int ret = -1; + + /* Initializing the communication with the daemon */ + if (dlt_control_init(dlt_passive_node_analyze_response, + get_ecuid(), + get_verbosity()) != 0) + { + pr_error("Failed to initialize connection with the daemon.\n"); + return ret; + } + + /* prepare message body */ + DltControlMsgBody *msg_body = NULL; + msg_body = dlt_passive_node_prepare_message_body(); + + if (msg_body == NULL) + { + pr_error("Data for Dlt Message body is NULL\n"); + return ret; + } + + ret = dlt_control_send_message(msg_body, get_timeout()); + + dlt_passive_node_destroy_message_body(msg_body); + + dlt_control_deinit(); + + return ret; +} + +static void usage() +{ + printf("Usage: dlt-passive-node-ctrl [options]\n"); + printf("Send a trigger to DLT daemon to (dis)connect a passive node " + "or get current passive node status \n"); + printf("\n"); + printf("Options:\n"); + printf(" -c Connection status (1 - connect, 0 - disconnect)\n"); + printf(" -h Usage\n"); + printf(" -n passive Node identifier (e.g. ECU2)\n"); + printf(" -s Show passive node(s) connection status\n"); + printf(" -t Specify connection timeout (Default: %ds)\n", + DLT_CTRL_TIMEOUT); + printf(" -v Set verbose flag (Default:%d)\n", get_verbosity()); +} + +/** + * @brief Parse application arguments + * + * The arguments are parsed and saved in static structure for future use. + * + * @param argc amount of arguments + * @param argv argument table + * @return 0 on success, -1 otherwise + */ +static int parse_args(int argc, char *argv[]) +{ + int c = 0; + int state = -1; + + /* Get command line arguments */ + opterr = 0; + + while ((c = getopt(argc, argv, "c:hn:stv")) != -1) + { + switch(c) + { + case 'c': + state = (int)strtol(optarg,NULL, 10); + if (state == DLT_NODE_CONNECT || state == DLT_NODE_DISCONNECT) + { + set_connection_state(state); + set_command(DLT_SERVICE_ID_PASSIVE_NODE_CONNECT); + } + else + { + pr_error("unknown connection state: %d\n", state); + return -1; + } + break; + case 'h': + usage(); + return -1; + case 'n': + set_node_id(optarg); + break; + case 's': + set_command(DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS); + break; + case 't': + set_timeout(strtol(optarg, NULL, 10)); + break; + case 'v': + set_verbosity(1); + pr_verbose("Now in verbose mode.\n"); + break; + case '?': + if (isprint(optopt)) + { + pr_error("Unknown option -%c.\n", optopt); + } + else + { + pr_error("Unknown option character \\x%x.\n", optopt); + } + usage(); + return -1; + default: + pr_error("Try %s -h for more information.\n", argv[0]); + return -1; + } + } + + return 0; +} + +/** + * @brief Entry point + * + * Execute the argument parser and call the main feature accordingly + * + * @param argc amount of arguments + * @param argv argument table + * @return 0 on success, -1 otherwise + */ +int main(int argc, char *argv[]) +{ + int ret = 0; + + set_ecuid(DLT_CTRL_DEFAULT_ECUID); + set_timeout(DLT_CTRL_TIMEOUT); + + /* Get command line arguments */ + if (parse_args(argc, argv) != 0) + { + return -1; + } + + if (get_command() == UNDEFINED || + (get_command() == DLT_SERVICE_ID_PASSIVE_NODE_CONNECT && + g_options.node_id[0] == '\0' && + g_options.connection_state == DLT_NODE_CONNECT_UNDEF)) + { + pr_error("No valid parameter configuration given!\n"); + usage(); + return -1; + } + + pr_verbose("Sending command to DLT daemon.\n"); + + /* one shot request */ + ret = dlt_passive_node_ctrl_single_request(); + + pr_verbose("Exiting.\n"); + + return ret; +} |