Line data Source code
1 : /*
2 : * SPDX license identifier: MPL-2.0
3 : *
4 : * Copyright (C) 2011-2015, BMW AG
5 : *
6 : * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
7 : *
8 : * This Source Code Form is subject to the terms of the
9 : * Mozilla Public License (MPL), v. 2.0.
10 : * If a copy of the MPL was not distributed with this file,
11 : * You can obtain one at http://mozilla.org/MPL/2.0/.
12 : *
13 : * For further information see http://www.covesa.org/.
14 : */
15 :
16 : /*!
17 : * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de>
18 : *
19 : * \copyright Copyright © 2011-2015 BMW AG. \n
20 : * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
21 : *
22 : * \file dlt_client.c
23 : */
24 :
25 : /*******************************************************************************
26 : ** **
27 : ** SRC-MODULE: dlt_client.c **
28 : ** **
29 : ** TARGET : linux **
30 : ** **
31 : ** PROJECT : DLT **
32 : ** **
33 : ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
34 : ** Markus Klein **
35 : ** **
36 : ** PURPOSE : **
37 : ** **
38 : ** REMARKS : **
39 : ** **
40 : ** PLATFORM DEPENDANT [yes/no]: yes **
41 : ** **
42 : ** TO BE CHANGED BY USER [yes/no]: no **
43 : ** **
44 : *******************************************************************************/
45 :
46 : /*******************************************************************************
47 : ** Author Identity **
48 : ********************************************************************************
49 : ** **
50 : ** Initials Name Company **
51 : ** -------- ------------------------- ---------------------------------- **
52 : ** aw Alexander Wenzel BMW **
53 : ** mk Markus Klein Fraunhofer ESK **
54 : *******************************************************************************/
55 :
56 : /*******************************************************************************
57 : ** Revision Control History **
58 : *******************************************************************************/
59 :
60 : /*
61 : * $LastChangedRevision$
62 : * $LastChangedDate$
63 : * $LastChangedBy$
64 : * Initials Date Comment
65 : * aw 12.07.2010 initial
66 : */
67 :
68 : #include <stdio.h>
69 :
70 : #if defined (__WIN32__) || defined (_MSC_VER)
71 : # pragma warning(disable : 4996) /* Switch off C4996 warnings */
72 : # include <winsock2.h> /* for socket(), connect(), send(), and recv() */
73 : #else
74 : # include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
75 :
76 : #pragma GCC diagnostic ignored "-Wconversion"
77 : # include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
78 : #pragma GCC diagnostic push
79 : #pragma GCC diagnostic pop
80 :
81 : # include <netdb.h>
82 : # include <sys/stat.h>
83 : # include <sys/un.h>
84 : #endif
85 :
86 : #if defined(_MSC_VER)
87 : # include <io.h>
88 : #else
89 : # include <unistd.h>
90 : # include <syslog.h>
91 : #endif
92 :
93 : #include <fcntl.h>
94 :
95 : #include <stdlib.h> /* for malloc(), free() */
96 : #include <string.h> /* for strlen(), memcmp(), memmove() */
97 : #include <errno.h>
98 : #include <limits.h>
99 : #include <poll.h>
100 :
101 : #include "dlt_types.h"
102 : #include "dlt_log.h"
103 : #include "dlt_client.h"
104 : #include "dlt_client_cfg.h"
105 :
106 : static int (*message_callback_function)(DltMessage *message, void *data) = NULL;
107 : static bool (*fetch_next_message_callback_function)(void *data) = NULL;
108 :
109 3 : void dlt_client_register_message_callback(int (*registerd_callback)(DltMessage *message, void *data))
110 : {
111 3 : message_callback_function = registerd_callback;
112 3 : }
113 :
114 0 : void dlt_client_register_fetch_next_message_callback(bool (*registerd_callback)(void *data))
115 : {
116 0 : fetch_next_message_callback_function = registerd_callback;
117 0 : }
118 :
119 8 : DltReturnValue dlt_client_init_port(DltClient *client, int port, int verbose)
120 : {
121 8 : if (verbose && (port != DLT_DAEMON_TCP_PORT))
122 0 : dlt_vlog(LOG_INFO,
123 : "%s: Init dlt client struct with port %d\n",
124 : __func__,
125 : port);
126 :
127 8 : if (client == NULL)
128 : return DLT_RETURN_ERROR;
129 :
130 8 : client->sock = -1;
131 8 : client->servIP = NULL;
132 8 : client->serialDevice = NULL;
133 8 : client->baudrate = DLT_CLIENT_INITIAL_BAUDRATE;
134 8 : client->port = (uint16_t)port;
135 8 : client->socketPath = NULL;
136 8 : client->mode = DLT_CLIENT_MODE_TCP;
137 8 : client->receiver.buffer = NULL;
138 8 : client->receiver.buf = NULL;
139 8 : client->receiver.backup_buf = NULL;
140 8 : client->hostip = NULL;
141 :
142 8 : return DLT_RETURN_OK;
143 : }
144 :
145 3 : DltReturnValue dlt_client_init(DltClient *client, int verbose)
146 : {
147 : char *env_daemon_port;
148 : int tmp_port;
149 : /* the port may be specified by an environment variable, defaults to DLT_DAEMON_TCP_PORT */
150 : unsigned short servPort = DLT_DAEMON_TCP_PORT;
151 :
152 : /* the port may be specified by an environment variable */
153 3 : env_daemon_port = getenv(DLT_CLIENT_ENV_DAEMON_TCP_PORT);
154 :
155 3 : if (env_daemon_port != NULL) {
156 : tmp_port = atoi(env_daemon_port);
157 :
158 0 : if ((tmp_port < IPPORT_RESERVED) || ((unsigned)tmp_port > USHRT_MAX)) {
159 0 : dlt_vlog(LOG_ERR,
160 : "%s: Specified port is out of possible range: %d.\n",
161 : __func__,
162 : tmp_port);
163 0 : return DLT_RETURN_ERROR;
164 : }
165 : else {
166 0 : servPort = (unsigned short)tmp_port;
167 : }
168 : }
169 :
170 3 : if (verbose)
171 0 : dlt_vlog(LOG_INFO,
172 : "%s: Init dlt client struct with default port: %hu.\n",
173 : __func__,
174 : servPort);
175 3 : return dlt_client_init_port(client, servPort, verbose);
176 : }
177 :
178 9 : DltReturnValue dlt_client_connect(DltClient *client, int verbose)
179 : {
180 9 : const int yes = 1;
181 9 : char portnumbuffer[33] = {0};
182 : struct addrinfo hints, *servinfo, *p;
183 : struct sockaddr_un addr;
184 : int rv;
185 : struct ip_mreq mreq;
186 : DltReceiverType receiver_type = DLT_RECEIVE_FD;
187 :
188 : struct pollfd pfds[1];
189 : int ret;
190 : int n;
191 9 : socklen_t m = sizeof(n);
192 : int connect_errno = 0;
193 :
194 : memset(&hints, 0, sizeof(hints));
195 9 : hints.ai_socktype = SOCK_STREAM;
196 :
197 9 : if (client == 0)
198 : return DLT_RETURN_ERROR;
199 :
200 9 : switch (client->mode) {
201 7 : case DLT_CLIENT_MODE_TCP:
202 7 : snprintf(portnumbuffer, 32, "%d", client->port);
203 :
204 7 : if ((rv = getaddrinfo(client->servIP, portnumbuffer, &hints, &servinfo)) != 0) {
205 0 : dlt_vlog(LOG_ERR,
206 : "%s: getaddrinfo: %s\n",
207 : __func__,
208 : gai_strerror(rv));
209 3 : return DLT_RETURN_ERROR;
210 : }
211 :
212 11 : for (p = servinfo; p != NULL; p = p->ai_next) {
213 8 : if ((client->sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
214 0 : dlt_vlog(LOG_WARNING,
215 : "%s: socket() failed! %s\n",
216 : __func__,
217 0 : strerror(errno));
218 0 : continue;
219 : }
220 :
221 : /* Set socket to Non-blocking mode */
222 8 : if(fcntl(client->sock, F_SETFL, fcntl(client->sock,F_GETFL,0) | O_NONBLOCK) < 0)
223 : {
224 0 : dlt_vlog(LOG_WARNING,
225 : "%s: Socket cannot be changed to NON BLOCK: %s\n",
226 0 : __func__, strerror(errno));
227 0 : close(client->sock);
228 0 : continue;
229 : }
230 :
231 8 : if (connect(client->sock, p->ai_addr, p->ai_addrlen) < 0) {
232 8 : if (errno == EINPROGRESS) {
233 8 : pfds[0].fd = client->sock;
234 8 : pfds[0].events = POLLOUT;
235 : ret = poll(pfds, 1, 500);
236 8 : if (ret < 0) {
237 0 : dlt_vlog(LOG_ERR, "%s: Failed to poll with err [%s]\n",
238 : __func__, strerror(errno));
239 0 : close(client->sock);
240 0 : continue;
241 : }
242 16 : else if ((pfds[0].revents & POLLOUT) &&
243 8 : getsockopt(client->sock, SOL_SOCKET,
244 : SO_ERROR, (void*)&n, &m) == 0) {
245 8 : if (n == 0) {
246 4 : dlt_vlog(LOG_DEBUG, "%s: Already connect\n", __func__);
247 4 : if(fcntl(client->sock, F_SETFL,
248 4 : fcntl(client->sock,F_GETFL,0) & ~O_NONBLOCK) < 0) {
249 0 : dlt_vlog(LOG_WARNING,
250 : "%s: Socket cannot be changed to BLOCK with err [%s]\n",
251 : __func__, strerror(errno));
252 0 : close(client->sock);
253 0 : continue;
254 : }
255 : }
256 : else {
257 : connect_errno = n;
258 4 : close(client->sock);
259 4 : continue;
260 : }
261 : }
262 : else {
263 0 : connect_errno = errno;
264 0 : close(client->sock);
265 0 : continue;
266 : }
267 : }
268 : else {
269 : connect_errno = errno;
270 0 : close(client->sock);
271 0 : continue;
272 : }
273 : }
274 :
275 : break;
276 : }
277 :
278 7 : freeaddrinfo(servinfo);
279 :
280 7 : if (p == NULL) {
281 3 : dlt_vlog(LOG_ERR,
282 : "%s: ERROR: failed to connect! %s\n",
283 : __func__,
284 : strerror(connect_errno));
285 3 : return DLT_RETURN_ERROR;
286 : }
287 :
288 4 : if (verbose) {
289 1 : dlt_vlog(LOG_INFO,
290 : "%s: Connected to DLT daemon (%s)\n",
291 : __func__,
292 : client->servIP);
293 : }
294 :
295 : receiver_type = DLT_RECEIVE_SOCKET;
296 :
297 6 : break;
298 0 : case DLT_CLIENT_MODE_SERIAL:
299 : /* open serial connection */
300 0 : client->sock = open(client->serialDevice, O_RDWR);
301 :
302 0 : if (client->sock < 0) {
303 0 : dlt_vlog(LOG_ERR,
304 : "%s: ERROR: Failed to open device %s\n",
305 : __func__,
306 : client->serialDevice);
307 0 : return DLT_RETURN_ERROR;
308 : }
309 :
310 0 : if (isatty(client->sock)) {
311 : #if !defined (__WIN32__)
312 :
313 0 : if (dlt_setup_serial(client->sock, client->baudrate) < DLT_RETURN_OK) {
314 0 : dlt_vlog(LOG_ERR,
315 : "%s: ERROR: Failed to configure serial device %s (%s) \n",
316 : __func__,
317 : client->serialDevice,
318 0 : strerror(errno));
319 0 : return DLT_RETURN_ERROR;
320 : }
321 :
322 : #else
323 : return DLT_RETURN_ERROR;
324 : #endif
325 : }
326 : else {
327 0 : if (verbose)
328 0 : dlt_vlog(LOG_ERR,
329 : "%s: ERROR: Device is not a serial device, device = %s (%s) \n",
330 : __func__,
331 : client->serialDevice,
332 0 : strerror(errno));
333 :
334 0 : return DLT_RETURN_ERROR;
335 : }
336 :
337 0 : if (verbose)
338 0 : dlt_vlog(LOG_INFO,
339 : "%s: Connected to %s\n",
340 : __func__,
341 : client->serialDevice);
342 :
343 : receiver_type = DLT_RECEIVE_FD;
344 :
345 : break;
346 2 : case DLT_CLIENT_MODE_UNIX:
347 :
348 2 : if ((client->sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
349 0 : dlt_vlog(LOG_ERR,
350 : "%s: ERROR: (unix) socket error: %s\n",
351 : __func__,
352 0 : strerror(errno));
353 :
354 0 : return DLT_RETURN_ERROR;
355 : }
356 :
357 : memset(&addr, 0, sizeof(addr));
358 2 : addr.sun_family = AF_UNIX;
359 2 : strncpy(addr.sun_path, client->socketPath, sizeof(addr.sun_path) - 1);
360 :
361 2 : if (connect(client->sock,
362 : (struct sockaddr *) &addr,
363 : sizeof(addr)) == -1) {
364 0 : dlt_vlog(LOG_ERR,
365 : "%s: ERROR: (unix) connect error: %s\n",
366 : __func__,
367 0 : strerror(errno));
368 :
369 0 : return DLT_RETURN_ERROR;
370 : }
371 :
372 2 : if (client->sock < 0) {
373 0 : dlt_vlog(LOG_ERR,
374 : "%s: ERROR: Failed to open device %s\n",
375 : __func__,
376 : client->socketPath);
377 :
378 0 : return DLT_RETURN_ERROR;
379 : }
380 :
381 : receiver_type = DLT_RECEIVE_SOCKET;
382 :
383 : break;
384 0 : case DLT_CLIENT_MODE_UDP_MULTICAST:
385 :
386 0 : if ((client->sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
387 : {
388 0 : dlt_vlog(LOG_ERR,
389 : "%s: ERROR: socket error: %s\n",
390 : __func__,
391 0 : strerror(errno));
392 :
393 0 : return DLT_RETURN_ERROR;
394 : }
395 :
396 : /* allow multiple sockets to use the same PORT number */
397 0 : if (setsockopt(client->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
398 : {
399 0 : dlt_vlog(LOG_ERR,
400 : "%s: ERROR: Reusing address failed: %s\n",
401 : __func__,
402 0 : strerror(errno));
403 :
404 0 : return DLT_RETURN_ERROR;
405 : }
406 :
407 0 : memset(&client->receiver.addr, 0, sizeof(client->receiver.addr));
408 0 : client->receiver.addr.sin_family = AF_INET;
409 : client->receiver.addr.sin_addr.s_addr = htonl(INADDR_ANY);
410 0 : client->receiver.addr.sin_port = htons(client->port);
411 :
412 : /* bind to receive address */
413 0 : if (bind(client->sock, (struct sockaddr*) &client->receiver.addr, sizeof(client->receiver.addr)) < 0)
414 : {
415 0 : dlt_vlog(LOG_ERR,
416 : "%s: ERROR: bind failed: %s\n",
417 : __func__,
418 0 : strerror(errno));
419 :
420 0 : return DLT_RETURN_ERROR;
421 : }
422 :
423 0 : mreq.imr_interface.s_addr = htonl(INADDR_ANY);
424 0 : if (client->hostip)
425 : {
426 0 : mreq.imr_interface.s_addr = inet_addr(client->hostip);
427 : }
428 0 : if (client->servIP == NULL)
429 : {
430 0 : dlt_vlog(LOG_ERR,
431 : "%s: ERROR: server address not set\n",
432 : __func__);
433 :
434 0 : return DLT_RETURN_ERROR;
435 : }
436 :
437 0 : char delimiter[] = ",";
438 0 : char* servIP = strtok(client->servIP, delimiter);
439 :
440 0 : while(servIP != NULL) {
441 0 : mreq.imr_multiaddr.s_addr = inet_addr(servIP);
442 0 : if (mreq.imr_multiaddr.s_addr == (in_addr_t)-1)
443 : {
444 0 : dlt_vlog(LOG_ERR,
445 : "%s: ERROR: server address not not valid %s\n",
446 : __func__,
447 : servIP);
448 :
449 0 : return DLT_RETURN_ERROR;
450 : }
451 :
452 0 : if (setsockopt(client->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)
453 : {
454 0 : dlt_vlog(LOG_ERR,
455 : "%s: ERROR: setsockopt add membership failed: %s\n",
456 : __func__,
457 0 : strerror(errno));
458 :
459 0 : return DLT_RETURN_ERROR;
460 : }
461 0 : servIP = strtok(NULL, delimiter);
462 : }
463 : receiver_type = DLT_RECEIVE_UDP_SOCKET;
464 :
465 : break;
466 0 : default:
467 0 : dlt_vlog(LOG_ERR,
468 : "%s: ERROR: Mode not supported: %d\n",
469 : __func__,
470 : client->mode);
471 :
472 0 : return DLT_RETURN_ERROR;
473 : }
474 :
475 6 : if (dlt_receiver_init(&(client->receiver), client->sock, receiver_type, DLT_RECEIVE_BUFSIZE) != DLT_RETURN_OK) {
476 0 : dlt_vlog(LOG_ERR, "%s: ERROR initializing receiver\n", __func__);
477 0 : return DLT_RETURN_ERROR;
478 : }
479 :
480 : return DLT_RETURN_OK;
481 : }
482 :
483 5 : DltReturnValue dlt_client_cleanup(DltClient *client, int verbose)
484 : {
485 : int ret = DLT_RETURN_OK;
486 :
487 5 : if (verbose)
488 0 : dlt_vlog(LOG_INFO, "%s: Cleanup dlt client\n", __func__);
489 :
490 5 : if (client == NULL)
491 : return DLT_RETURN_WRONG_PARAMETER;
492 :
493 5 : if (client->sock != -1)
494 5 : close(client->sock);
495 :
496 5 : if (dlt_receiver_free(&(client->receiver)) != DLT_RETURN_OK) {
497 0 : dlt_vlog(LOG_WARNING, "%s: Failed to free receiver\n", __func__);
498 : ret = DLT_RETURN_ERROR;
499 : }
500 :
501 5 : if (client->serialDevice) {
502 0 : free(client->serialDevice);
503 0 : client->serialDevice = NULL;
504 : }
505 :
506 5 : if (client->servIP) {
507 3 : free(client->servIP);
508 3 : client->servIP = NULL;
509 : }
510 :
511 5 : if (client->socketPath) {
512 2 : free(client->socketPath);
513 2 : client->socketPath = NULL;
514 : }
515 :
516 5 : if (client->hostip) {
517 0 : free(client->hostip);
518 0 : client->hostip = NULL;
519 : }
520 : return ret;
521 : }
522 :
523 3 : DltReturnValue dlt_client_main_loop(DltClient *client, void *data, int verbose)
524 : {
525 : DltMessage msg;
526 : int ret;
527 :
528 3 : if (client == 0)
529 : return DLT_RETURN_ERROR;
530 :
531 3 : if (dlt_message_init(&msg, verbose) == DLT_RETURN_ERROR)
532 : return DLT_RETURN_ERROR;
533 :
534 : bool fetch_next_message = true;
535 415 : while (fetch_next_message) {
536 : /* wait for data from socket or serial connection */
537 415 : ret = dlt_receiver_receive(&(client->receiver));
538 :
539 415 : if (ret <= 0) {
540 : /* No more data to be received */
541 3 : if (dlt_message_free(&msg, verbose) == DLT_RETURN_ERROR)
542 : return DLT_RETURN_ERROR;
543 :
544 : return DLT_RETURN_TRUE;
545 : }
546 :
547 620 : while (dlt_message_read(&msg, (unsigned char *)(client->receiver.buf),
548 620 : (unsigned int)client->receiver.bytesRcvd,
549 : client->resync_serial_header,
550 620 : verbose) == DLT_MESSAGE_ERROR_OK)
551 : {
552 : /* Call callback function */
553 208 : if (message_callback_function)
554 208 : (*message_callback_function)(&msg, data);
555 :
556 208 : int total_size = (int)((size_t)msg.headersize
557 208 : + (size_t)msg.datasize
558 208 : - sizeof(DltStorageHeader));
559 :
560 208 : if (msg.found_serialheader) {
561 : total_size += (int)sizeof(dltSerialHeader);
562 : }
563 :
564 208 : if (dlt_receiver_remove(&(client->receiver),
565 : total_size) == DLT_RETURN_ERROR) {
566 : /* Return value ignored */
567 0 : dlt_message_free(&msg, verbose);
568 0 : return DLT_RETURN_ERROR;
569 : }
570 : }
571 :
572 412 : if (dlt_receiver_move_to_begin(&(client->receiver)) == DLT_RETURN_ERROR) {
573 : /* Return value ignored */
574 0 : dlt_message_free(&msg, verbose);
575 0 : return DLT_RETURN_ERROR;
576 : }
577 412 : if (fetch_next_message_callback_function)
578 0 : fetch_next_message = (*fetch_next_message_callback_function)(data);
579 : }
580 :
581 0 : if (dlt_message_free(&msg, verbose) == DLT_RETURN_ERROR)
582 : return DLT_RETURN_ERROR;
583 :
584 : return DLT_RETURN_OK;
585 : }
586 :
587 2 : DltReturnValue dlt_client_send_message_to_socket(DltClient *client, DltMessage *msg)
588 : {
589 : int ret = 0;
590 :
591 2 : if ((client == NULL) || (client->sock < 0)
592 2 : || (msg == NULL) || (msg->databuffer == NULL))
593 : {
594 0 : dlt_log(LOG_ERR, "Invalid parameters\n");
595 0 : return DLT_RETURN_ERROR;
596 : }
597 :
598 2 : if (client->send_serial_header)
599 : {
600 0 : ret = (int)send(client->sock, (const char *)dltSerialHeader,
601 : sizeof(dltSerialHeader), 0);
602 0 : if (ret < 0)
603 : {
604 0 : dlt_vlog(LOG_ERR, "Sending serial header failed: %s\n",
605 0 : strerror(errno));
606 0 : return DLT_RETURN_ERROR;
607 : }
608 : }
609 :
610 4 : ret = (int)send(client->sock,
611 : (const char *)(msg->headerbuffer + sizeof(DltStorageHeader)),
612 2 : (size_t)((int32_t)msg->headersize - (int32_t)sizeof(DltStorageHeader)), 0);
613 2 : if (ret < 0)
614 : {
615 0 : dlt_vlog(LOG_ERR, "Sending message header failed: %s\n", strerror(errno));
616 0 : return DLT_RETURN_ERROR;
617 : }
618 :
619 2 : ret = (int)send(client->sock, (const char *)msg->databuffer, (size_t)msg->datasize, 0);
620 2 : if ( ret < 0)
621 : {
622 0 : dlt_vlog(LOG_ERR, "Sending message failed: %s\n", strerror(errno));
623 0 : return DLT_RETURN_ERROR;
624 : }
625 :
626 : return DLT_RETURN_OK;
627 : }
628 :
629 10 : DltReturnValue dlt_client_send_ctrl_msg(DltClient *client, char *apid, char *ctid, uint8_t *payload, uint32_t size)
630 : {
631 : DltMessage msg;
632 : int ret;
633 :
634 : int32_t len;
635 : uint32_t id_tmp;
636 : uint32_t id;
637 :
638 10 : if ((client == 0) || (client->sock < 0) || (apid == 0) || (ctid == 0))
639 : return DLT_RETURN_ERROR;
640 :
641 : /* initialise new message */
642 10 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
643 : return DLT_RETURN_ERROR;
644 :
645 : /* prepare payload of data */
646 10 : msg.datasize = (int32_t)size;
647 :
648 10 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
649 0 : free(msg.databuffer);
650 0 : msg.databuffer = 0;
651 : }
652 :
653 10 : if (msg.databuffer == 0) {
654 10 : msg.databuffer = (uint8_t *)malloc((size_t)msg.datasize);
655 10 : msg.databuffersize = msg.datasize;
656 : }
657 :
658 10 : if (msg.databuffer == 0) {
659 0 : dlt_message_free(&msg, 0);
660 0 : return DLT_RETURN_ERROR;
661 : }
662 :
663 : /* copy data */
664 10 : memcpy(msg.databuffer, payload, size);
665 :
666 : /* prepare storage header */
667 10 : msg.storageheader = (DltStorageHeader *)msg.headerbuffer;
668 :
669 10 : if (dlt_set_storageheader(msg.storageheader, "") == DLT_RETURN_ERROR) {
670 0 : dlt_message_free(&msg, 0);
671 0 : return DLT_RETURN_ERROR;
672 : }
673 :
674 : /* prepare standard header */
675 10 : msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader));
676 10 : msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1;
677 :
678 : #if (BYTE_ORDER == BIG_ENDIAN)
679 : msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
680 : #endif
681 :
682 10 : msg.standardheader->mcnt = 0;
683 :
684 : /* Set header extra parameters */
685 10 : dlt_set_id(msg.headerextra.ecu, client->ecuid);
686 : /*msg.headerextra.seid = 0; */
687 10 : msg.headerextra.tmsp = dlt_uptime();
688 :
689 : /* Copy header extra parameters to headerbuffer */
690 10 : if (dlt_message_set_extraparameters(&msg, 0) == DLT_RETURN_ERROR) {
691 0 : dlt_message_free(&msg, 0);
692 0 : return DLT_RETURN_ERROR;
693 : }
694 :
695 : /* prepare extended header */
696 10 : msg.extendedheader = (DltExtendedHeader *)(msg.headerbuffer +
697 : sizeof(DltStorageHeader) +
698 10 : sizeof(DltStandardHeader) +
699 10 : DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
700 :
701 10 : msg.extendedheader->msin = DLT_MSIN_CONTROL_REQUEST;
702 :
703 10 : msg.extendedheader->noar = 1; /* number of arguments */
704 :
705 19 : dlt_set_id(msg.extendedheader->apid, (apid[0] == '\0') ? DLT_CLIENT_DUMMY_APP_ID : apid);
706 19 : dlt_set_id(msg.extendedheader->ctid, (ctid[0] == '\0') ? DLT_CLIENT_DUMMY_CON_ID : ctid);
707 :
708 : /* prepare length information */
709 10 : msg.headersize = (int32_t)(sizeof(DltStorageHeader) +
710 : sizeof(DltStandardHeader) +
711 10 : sizeof(DltExtendedHeader) +
712 10 : DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
713 :
714 10 : len = (int32_t)((size_t)msg.headersize - sizeof(DltStorageHeader) + (size_t)msg.datasize);
715 :
716 :
717 10 : if (len > UINT16_MAX) {
718 0 : dlt_vlog(LOG_ERR,
719 : "%s: Critical: Huge injection message discarded!\n",
720 : __func__);
721 :
722 0 : dlt_message_free(&msg, 0);
723 :
724 0 : return DLT_RETURN_ERROR;
725 : }
726 :
727 10 : msg.standardheader->len = (uint16_t)DLT_HTOBE_16((uint16_t)len);
728 :
729 : /* Send data (without storage header) */
730 10 : if ((client->mode == DLT_CLIENT_MODE_TCP) || (client->mode == DLT_CLIENT_MODE_SERIAL)) {
731 : /* via FileDescriptor */
732 10 : if (client->send_serial_header)
733 : {
734 0 : ret = write(client->sock, dltSerialHeader, sizeof(dltSerialHeader));
735 0 : if (ret < 0)
736 : {
737 0 : dlt_log(LOG_ERR, "Sending message failed\n");
738 0 : dlt_message_free(&msg, 0);
739 0 : return DLT_RETURN_ERROR;
740 : }
741 : }
742 :
743 10 : ret = (int) write(client->sock, msg.headerbuffer + sizeof(DltStorageHeader), (size_t)((int32_t)msg.headersize - (int32_t)sizeof(DltStorageHeader)));
744 :
745 10 : if (0 > ret) {
746 0 : dlt_vlog(LOG_ERR, "%s: Sending message failed\n", __func__);
747 0 : dlt_message_free(&msg, 0);
748 0 : return DLT_RETURN_ERROR;
749 : }
750 :
751 10 : ret = (int) write(client->sock, msg.databuffer, (size_t)msg.datasize);
752 :
753 10 : if (0 > ret) {
754 0 : dlt_vlog(LOG_ERR, "%s: Sending message failed\n", __func__);
755 0 : dlt_message_free(&msg, 0);
756 0 : return DLT_RETURN_ERROR;
757 : }
758 :
759 10 : id_tmp = *((uint32_t *)(msg.databuffer));
760 10 : id = DLT_ENDIAN_GET_32(msg.standardheader->htyp, id_tmp);
761 :
762 10 : dlt_vlog(LOG_INFO,
763 : "%s: Control message forwarded : %s\n",
764 : __func__,
765 : dlt_get_service_name(id));
766 : }
767 : else {
768 : /* via Socket */
769 0 : if (dlt_client_send_message_to_socket(client, &msg) == DLT_RETURN_ERROR)
770 : {
771 0 : dlt_log(LOG_ERR, "Sending message to socket failed\n");
772 0 : dlt_message_free(&msg, 0);
773 0 : return DLT_RETURN_ERROR;
774 : }
775 : }
776 :
777 : /* free message */
778 10 : if (dlt_message_free(&msg, 0) == DLT_RETURN_ERROR)
779 : return DLT_RETURN_ERROR;
780 :
781 : return DLT_RETURN_OK;
782 : }
783 :
784 0 : DltReturnValue dlt_client_send_inject_msg(DltClient *client,
785 : char *apid,
786 : char *ctid,
787 : uint32_t serviceID,
788 : uint8_t *buffer,
789 : uint32_t size)
790 : {
791 : uint8_t *payload;
792 : int offset;
793 :
794 0 : payload = (uint8_t *)malloc(sizeof(uint32_t) + sizeof(uint32_t) + size);
795 :
796 0 : if (payload == 0)
797 : return DLT_RETURN_ERROR;
798 :
799 : offset = 0;
800 : memcpy(payload, &serviceID, sizeof(serviceID));
801 : offset += (int) sizeof(uint32_t);
802 0 : memcpy(payload + offset, &size, sizeof(size));
803 : offset += (int) sizeof(uint32_t);
804 0 : memcpy(payload + offset, buffer, size);
805 :
806 : /* free message */
807 0 : if (dlt_client_send_ctrl_msg(client, apid, ctid, payload,
808 : (uint32_t) (sizeof(uint32_t) + sizeof(uint32_t) + size)) == DLT_RETURN_ERROR) {
809 0 : free(payload);
810 0 : return DLT_RETURN_ERROR;
811 : }
812 :
813 0 : free(payload);
814 :
815 0 : return DLT_RETURN_OK;
816 :
817 : }
818 :
819 1 : DltReturnValue dlt_client_send_log_level(DltClient *client, char *apid, char *ctid, uint8_t logLevel)
820 : {
821 : DltServiceSetLogLevel *req;
822 : int ret = DLT_RETURN_ERROR;
823 :
824 1 : if (client == NULL)
825 : return ret;
826 :
827 1 : req = calloc(1, sizeof(DltServiceSetLogLevel));
828 :
829 1 : if (req == NULL)
830 : return ret;
831 :
832 1 : req->service_id = DLT_SERVICE_ID_SET_LOG_LEVEL;
833 1 : dlt_set_id(req->apid, apid);
834 1 : dlt_set_id(req->ctid, ctid);
835 1 : req->log_level = logLevel;
836 1 : dlt_set_id(req->com, "remo");
837 :
838 : /* free message */
839 1 : ret = dlt_client_send_ctrl_msg(client,
840 : "APP",
841 : "CON",
842 : (uint8_t *)req,
843 : sizeof(DltServiceSetLogLevel));
844 :
845 :
846 1 : free(req);
847 :
848 1 : return ret;
849 : }
850 :
851 4 : DltReturnValue dlt_client_get_log_info(DltClient *client)
852 : {
853 : DltServiceGetLogInfoRequest *req;
854 : int ret = DLT_RETURN_ERROR;
855 :
856 4 : if (client == NULL)
857 : return ret;
858 :
859 4 : req = (DltServiceGetLogInfoRequest *)malloc(sizeof(DltServiceGetLogInfoRequest));
860 :
861 4 : if (req == NULL)
862 : return ret;
863 :
864 4 : req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
865 4 : req->options = 7;
866 4 : dlt_set_id(req->apid, "");
867 4 : dlt_set_id(req->ctid, "");
868 4 : dlt_set_id(req->com, "remo");
869 :
870 : /* send control message to daemon*/
871 4 : ret = dlt_client_send_ctrl_msg(client,
872 : "",
873 : "",
874 : (uint8_t *)req,
875 : sizeof(DltServiceGetLogInfoRequest));
876 :
877 4 : free(req);
878 :
879 4 : return ret;
880 : }
881 :
882 1 : DltReturnValue dlt_client_get_default_log_level(DltClient *client)
883 : {
884 : DltServiceGetDefaultLogLevelRequest *req;
885 : int ret = DLT_RETURN_ERROR;
886 :
887 1 : if (client == NULL)
888 : return ret;
889 :
890 : req = (DltServiceGetDefaultLogLevelRequest *)
891 1 : malloc(sizeof(DltServiceGetDefaultLogLevelRequest));
892 :
893 1 : if (req == NULL)
894 : return ret;
895 :
896 1 : req->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
897 :
898 : /* send control message to daemon*/
899 1 : ret = dlt_client_send_ctrl_msg(client,
900 : "",
901 : "",
902 : (uint8_t *)req,
903 : sizeof(DltServiceGetDefaultLogLevelRequest));
904 :
905 1 : free(req);
906 :
907 1 : return ret;
908 : }
909 :
910 4 : DltReturnValue dlt_client_get_software_version(DltClient *client)
911 : {
912 : DltServiceGetSoftwareVersion *req;
913 : int ret = DLT_RETURN_ERROR;
914 :
915 4 : if (client == NULL)
916 : return ret;
917 :
918 4 : req = (DltServiceGetSoftwareVersion *)malloc(sizeof(DltServiceGetSoftwareVersion));
919 :
920 4 : req->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
921 :
922 : /* send control message to daemon*/
923 4 : ret = dlt_client_send_ctrl_msg(client,
924 : "",
925 : "",
926 : (uint8_t *)req,
927 : sizeof(DltServiceGetSoftwareVersion));
928 :
929 4 : free(req);
930 :
931 4 : return ret;
932 : }
933 :
934 0 : DltReturnValue dlt_client_send_trace_status(DltClient *client, char *apid, char *ctid, uint8_t traceStatus)
935 : {
936 : DltServiceSetLogLevel *req;
937 :
938 0 : req = calloc(1,sizeof(DltServiceSetLogLevel));
939 :
940 0 : if (req == 0)
941 : return DLT_RETURN_ERROR;
942 :
943 0 : req->service_id = DLT_SERVICE_ID_SET_TRACE_STATUS;
944 0 : dlt_set_id(req->apid, apid);
945 0 : dlt_set_id(req->ctid, ctid);
946 0 : req->log_level = traceStatus;
947 0 : dlt_set_id(req->com, "remo");
948 :
949 : /* free message */
950 0 : if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
951 : sizeof(DltServiceSetLogLevel)) == DLT_RETURN_ERROR) {
952 0 : free(req);
953 0 : return DLT_RETURN_ERROR;
954 : }
955 :
956 0 : free(req);
957 :
958 0 : return DLT_RETURN_OK;
959 : }
960 :
961 0 : DltReturnValue dlt_client_send_default_log_level(DltClient *client, uint8_t defaultLogLevel)
962 : {
963 : DltServiceSetDefaultLogLevel *req;
964 :
965 0 : req = calloc(1, sizeof(DltServiceSetDefaultLogLevel));
966 :
967 0 : if (req == 0)
968 : return DLT_RETURN_ERROR;
969 :
970 0 : req->service_id = DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
971 0 : req->log_level = defaultLogLevel;
972 0 : dlt_set_id(req->com, "remo");
973 :
974 : /* free message */
975 0 : if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
976 : sizeof(DltServiceSetDefaultLogLevel)) == DLT_RETURN_ERROR) {
977 0 : free(req);
978 0 : return DLT_RETURN_ERROR;
979 : }
980 :
981 0 : free(req);
982 :
983 0 : return DLT_RETURN_OK;
984 : }
985 :
986 0 : DltReturnValue dlt_client_send_all_log_level(DltClient *client, uint8_t LogLevel)
987 : {
988 : DltServiceSetDefaultLogLevel *req;
989 :
990 0 : req = calloc(1, sizeof(DltServiceSetDefaultLogLevel));
991 :
992 0 : if (req == 0)
993 : return DLT_RETURN_ERROR;
994 :
995 0 : req->service_id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL;
996 0 : req->log_level = LogLevel;
997 0 : dlt_set_id(req->com, "remo");
998 :
999 : /* free message */
1000 0 : if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
1001 : sizeof(DltServiceSetDefaultLogLevel)) == -1) {
1002 0 : free(req);
1003 0 : return DLT_RETURN_ERROR;
1004 : }
1005 :
1006 0 : free(req);
1007 :
1008 0 : return DLT_RETURN_OK;
1009 : }
1010 :
1011 0 : DltReturnValue dlt_client_send_default_trace_status(DltClient *client, uint8_t defaultTraceStatus)
1012 : {
1013 : DltServiceSetDefaultLogLevel *req;
1014 :
1015 0 : req = calloc(1, sizeof(DltServiceSetDefaultLogLevel));
1016 :
1017 0 : if (req == 0)
1018 : return DLT_RETURN_ERROR;
1019 :
1020 0 : req->service_id = DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
1021 0 : req->log_level = defaultTraceStatus;
1022 0 : dlt_set_id(req->com, "remo");
1023 :
1024 : /* free message */
1025 0 : if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
1026 : sizeof(DltServiceSetDefaultLogLevel)) == DLT_RETURN_ERROR) {
1027 0 : free(req);
1028 0 : return DLT_RETURN_ERROR;
1029 : }
1030 :
1031 0 : free(req);
1032 :
1033 0 : return DLT_RETURN_OK;
1034 : }
1035 :
1036 0 : DltReturnValue dlt_client_send_all_trace_status(DltClient *client, uint8_t traceStatus)
1037 : {
1038 : DltServiceSetDefaultLogLevel *req;
1039 :
1040 0 : if (client == NULL) {
1041 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
1042 0 : return DLT_RETURN_ERROR;
1043 : }
1044 :
1045 0 : req = calloc(1, sizeof(DltServiceSetDefaultLogLevel));
1046 :
1047 0 : if (req == 0) {
1048 0 : dlt_vlog(LOG_ERR, "%s: Could not allocate memory %zu\n", __func__, sizeof(DltServiceSetDefaultLogLevel));
1049 0 : return DLT_RETURN_ERROR;
1050 : }
1051 :
1052 0 : req->service_id = DLT_SERVICE_ID_SET_ALL_TRACE_STATUS;
1053 0 : req->log_level = traceStatus;
1054 0 : dlt_set_id(req->com, "remo");
1055 :
1056 : /* free message */
1057 0 : if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
1058 : sizeof(DltServiceSetDefaultLogLevel)) == -1) {
1059 0 : free(req);;
1060 0 : return DLT_RETURN_ERROR;
1061 : }
1062 :
1063 0 : free(req);
1064 :
1065 0 : return DLT_RETURN_OK;
1066 : }
1067 :
1068 0 : DltReturnValue dlt_client_send_timing_pakets(DltClient *client, uint8_t timingPakets)
1069 : {
1070 : DltServiceSetVerboseMode *req;
1071 :
1072 0 : req = calloc(1, sizeof(DltServiceSetVerboseMode));
1073 :
1074 0 : if (req == 0)
1075 : return DLT_RETURN_ERROR;
1076 :
1077 0 : req->service_id = DLT_SERVICE_ID_SET_TIMING_PACKETS;
1078 0 : req->new_status = timingPakets;
1079 :
1080 : /* free message */
1081 0 : if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
1082 : sizeof(DltServiceSetVerboseMode)) == DLT_RETURN_ERROR) {
1083 0 : free(req);
1084 0 : return DLT_RETURN_ERROR;
1085 : }
1086 :
1087 0 : free(req);
1088 :
1089 0 : return DLT_RETURN_OK;
1090 : }
1091 :
1092 0 : DltReturnValue dlt_client_send_store_config(DltClient *client)
1093 : {
1094 : uint32_t service_id;
1095 :
1096 0 : service_id = DLT_SERVICE_ID_STORE_CONFIG;
1097 :
1098 : /* free message */
1099 0 : if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t *)&service_id, sizeof(uint32_t)) == DLT_RETURN_ERROR)
1100 0 : return DLT_RETURN_ERROR;
1101 :
1102 : return DLT_RETURN_OK;
1103 : }
1104 :
1105 0 : DltReturnValue dlt_client_send_reset_to_factory_default(DltClient *client)
1106 : {
1107 : uint32_t service_id;
1108 :
1109 0 : service_id = DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT;
1110 :
1111 : /* free message */
1112 0 : if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t *)&service_id, sizeof(uint32_t)) == DLT_RETURN_ERROR)
1113 0 : return DLT_RETURN_ERROR;
1114 :
1115 : return DLT_RETURN_OK;
1116 : }
1117 :
1118 0 : DltReturnValue dlt_client_setbaudrate(DltClient *client, int baudrate)
1119 : {
1120 0 : if (client == 0)
1121 : return DLT_RETURN_ERROR;
1122 :
1123 0 : client->baudrate = dlt_convert_serial_speed(baudrate);
1124 :
1125 0 : return DLT_RETURN_OK;
1126 : }
1127 :
1128 0 : DltReturnValue dlt_client_set_mode(DltClient *client, DltClientMode mode)
1129 : {
1130 0 : if (client == 0)
1131 : return DLT_RETURN_ERROR;
1132 :
1133 0 : client->mode = mode;
1134 0 : return DLT_RETURN_OK;
1135 :
1136 : }
1137 :
1138 6 : int dlt_client_set_server_ip(DltClient *client, char *ipaddr)
1139 : {
1140 6 : client->servIP = strdup(ipaddr);
1141 :
1142 6 : if (client->servIP == NULL) {
1143 0 : dlt_vlog(LOG_ERR, "%s: ERROR: failed to duplicate server IP\n", __func__);
1144 0 : return DLT_RETURN_ERROR;
1145 : }
1146 :
1147 : return DLT_RETURN_OK;
1148 : }
1149 :
1150 0 : int dlt_client_set_host_if_address(DltClient *client, char *hostip)
1151 : {
1152 0 : client->hostip = strdup(hostip);
1153 :
1154 0 : if (client->hostip == NULL) {
1155 0 : dlt_vlog(LOG_ERR, "%s: ERROR: failed to duplicate UDP interface address\n", __func__);
1156 0 : return DLT_RETURN_ERROR;
1157 : }
1158 :
1159 : return DLT_RETURN_OK;
1160 : }
1161 :
1162 0 : int dlt_client_set_serial_device(DltClient *client, char *serial_device)
1163 : {
1164 0 : client->serialDevice = strdup(serial_device);
1165 :
1166 0 : if (client->serialDevice == NULL) {
1167 0 : dlt_vlog(LOG_ERR, "%s: ERROR: failed to duplicate serial device\n", __func__);
1168 0 : return DLT_RETURN_ERROR;
1169 : }
1170 :
1171 : return DLT_RETURN_OK;
1172 : }
1173 :
1174 0 : int dlt_client_set_socket_path(DltClient *client, char *socket_path)
1175 : {
1176 0 : client->socketPath = strdup(socket_path);
1177 :
1178 0 : if (client->socketPath == NULL) {
1179 0 : dlt_vlog(LOG_ERR, "%s: ERROR: failed to duplicate socket path\n", __func__);
1180 0 : return DLT_RETURN_ERROR;
1181 : }
1182 :
1183 : return DLT_RETURN_OK;
1184 : }
1185 : /**
1186 : * free allocation when calloc failed
1187 : *
1188 : * @param resp DltServiceGetLogInfoResponse
1189 : * @param count_app_ids number of app_ids which needs to be freed
1190 : */
1191 0 : DLT_STATIC void dlt_client_free_calloc_failed_get_log_info(DltServiceGetLogInfoResponse *resp,
1192 : int count_app_ids)
1193 : {
1194 : AppIDsType *app = NULL;
1195 : ContextIDsInfoType *con = NULL;
1196 : int i = 0;
1197 : int j = 0;
1198 :
1199 0 : for (i = 0; i < count_app_ids; i++) {
1200 0 : app = &(resp->log_info_type.app_ids[i]);
1201 :
1202 0 : for (j = 0; j < app->count_context_ids; j++) {
1203 0 : con = &(app->context_id_info[j]);
1204 :
1205 0 : free(con->context_description);
1206 0 : con->context_description = NULL;
1207 : }
1208 :
1209 0 : free(app->app_description);
1210 0 : app->app_description = NULL;
1211 :
1212 0 : free(app->context_id_info);
1213 0 : app->context_id_info = NULL;
1214 : }
1215 :
1216 0 : free(resp->log_info_type.app_ids);
1217 0 : resp->log_info_type.app_ids = NULL;
1218 0 : resp->log_info_type.count_app_ids = 0;
1219 :
1220 0 : return;
1221 : }
1222 :
1223 2 : DltReturnValue dlt_client_parse_get_log_info_resp_text(DltServiceGetLogInfoResponse *resp,
1224 : char *resp_text)
1225 : {
1226 : AppIDsType *app = NULL;
1227 : ContextIDsInfoType *con = NULL;
1228 : int i = 0;
1229 : int j = 0;
1230 : char *rp = NULL;
1231 2 : int rp_count = 0;
1232 :
1233 2 : if ((resp == NULL) || (resp_text == NULL))
1234 : return DLT_RETURN_WRONG_PARAMETER;
1235 :
1236 : /* ------------------------------------------------------
1237 : * get_log_info data structure(all data is ascii)
1238 : *
1239 : * get_log_info, aa, bb bb cc cc cc cc dd dd ee ee ee ee ff gg hh hh ii ii ii .. ..
1240 : * ~~ ~~~~~ ~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~
1241 : * cc cc cc cc dd dd ee ee ee ee ff gg hh hh ii ii ii .. ..
1242 : * jj jj kk kk kk .. ..
1243 : * ~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~
1244 : * aa : get mode (fix value at 0x07)
1245 : * bb bb : list num of apid (little endian)
1246 : * cc cc cc cc: apid
1247 : * dd dd : list num of ctid (little endian)
1248 : * ee ee ee ee: ctid
1249 : * ff : log level
1250 : * gg : trace status
1251 : * hh hh : description length of ctid
1252 : * ii ii .. : description text of ctid
1253 : * jj jj : description length of apid
1254 : * kk kk .. : description text of apid
1255 : * ------------------------------------------------------ */
1256 :
1257 2 : rp = resp_text + DLT_GET_LOG_INFO_HEADER;
1258 : rp_count = 0;
1259 :
1260 : /* check if status is acceptable */
1261 2 : if ((resp->status < GET_LOG_INFO_STATUS_MIN) ||
1262 : (resp->status > GET_LOG_INFO_STATUS_MAX)) {
1263 0 : if (resp->status == GET_LOG_INFO_STATUS_NO_MATCHING_CTX)
1264 0 : dlt_vlog(LOG_WARNING,
1265 : "%s: The status(%d) is invalid: NO matching Context IDs\n",
1266 : __func__,
1267 : resp->status);
1268 0 : else if (resp->status == GET_LOG_INFO_STATUS_RESP_DATA_OVERFLOW)
1269 0 : dlt_vlog(LOG_WARNING,
1270 : "%s: The status(%d) is invalid: Response data over flow\n",
1271 : __func__,
1272 : resp->status);
1273 : else
1274 0 : dlt_vlog(LOG_WARNING,
1275 : "%s: The status(%d) is invalid\n",
1276 : __func__,
1277 : resp->status);
1278 :
1279 0 : return DLT_RETURN_ERROR;
1280 : }
1281 :
1282 : /* count_app_ids */
1283 2 : resp->log_info_type.count_app_ids = (uint16_t) dlt_getloginfo_conv_ascii_to_uint16_t(rp,
1284 : &rp_count);
1285 :
1286 2 : resp->log_info_type.app_ids = (AppIDsType *)calloc
1287 : (resp->log_info_type.count_app_ids, sizeof(AppIDsType));
1288 :
1289 2 : if (resp->log_info_type.app_ids == NULL) {
1290 0 : dlt_vlog(LOG_ERR, "%s: calloc failed for app_ids\n", __func__);
1291 0 : dlt_client_free_calloc_failed_get_log_info(resp, 0);
1292 0 : return DLT_RETURN_ERROR;
1293 : }
1294 :
1295 5 : for (i = 0; i < resp->log_info_type.count_app_ids; i++) {
1296 3 : app = &(resp->log_info_type.app_ids[i]);
1297 : /* get app id */
1298 3 : dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, app->app_id, DLT_ID_SIZE);
1299 :
1300 : /* count_con_ids */
1301 3 : app->count_context_ids = (uint16_t) dlt_getloginfo_conv_ascii_to_uint16_t(rp,
1302 : &rp_count);
1303 :
1304 3 : app->context_id_info = (ContextIDsInfoType *)calloc
1305 : (app->count_context_ids, sizeof(ContextIDsInfoType));
1306 :
1307 3 : if (app->context_id_info == NULL) {
1308 0 : dlt_vlog(LOG_ERR,
1309 : "%s: calloc failed for context_id_info\n", __func__);
1310 0 : dlt_client_free_calloc_failed_get_log_info(resp, i);
1311 0 : return DLT_RETURN_ERROR;
1312 : }
1313 :
1314 9 : for (j = 0; j < app->count_context_ids; j++) {
1315 6 : con = &(app->context_id_info[j]);
1316 : /* get con id */
1317 6 : dlt_getloginfo_conv_ascii_to_id(rp,
1318 : &rp_count,
1319 6 : con->context_id,
1320 : DLT_ID_SIZE);
1321 :
1322 : /* log_level */
1323 6 : if ((resp->status == 4) || (resp->status == 6) || (resp->status == 7))
1324 6 : con->log_level = dlt_getloginfo_conv_ascii_to_int16_t(rp,
1325 : &rp_count);
1326 :
1327 : /* trace status */
1328 6 : if ((resp->status == 5) || (resp->status == 6) || (resp->status == 7))
1329 6 : con->trace_status = dlt_getloginfo_conv_ascii_to_int16_t(rp,
1330 : &rp_count);
1331 :
1332 : /* context desc */
1333 6 : if (resp->status == 7) {
1334 6 : con->len_context_description = (uint16_t) dlt_getloginfo_conv_ascii_to_uint16_t(rp,
1335 : &rp_count);
1336 6 : con->context_description = (char *)calloc
1337 6 : ((size_t) (con->len_context_description + 1), sizeof(char));
1338 :
1339 6 : if (con->context_description == NULL) {
1340 0 : dlt_vlog(LOG_ERR, "%s: calloc failed for context description\n", __func__);
1341 0 : dlt_client_free_calloc_failed_get_log_info(resp, i);
1342 0 : return DLT_RETURN_ERROR;
1343 : }
1344 :
1345 6 : dlt_getloginfo_conv_ascii_to_string(rp,
1346 : &rp_count,
1347 : con->context_description,
1348 : con->len_context_description);
1349 : }
1350 : }
1351 :
1352 : /* application desc */
1353 3 : if (resp->status == 7) {
1354 3 : app->len_app_description = (uint16_t) dlt_getloginfo_conv_ascii_to_uint16_t(rp,
1355 : &rp_count);
1356 3 : app->app_description = (char *)calloc
1357 3 : ((size_t) (app->len_app_description + 1), sizeof(char));
1358 :
1359 3 : if (app->app_description == NULL) {
1360 0 : dlt_vlog(LOG_ERR, "%s: calloc failed for application description\n", __func__);
1361 0 : dlt_client_free_calloc_failed_get_log_info(resp, i);
1362 0 : return DLT_RETURN_ERROR;
1363 : }
1364 :
1365 3 : dlt_getloginfo_conv_ascii_to_string(rp,
1366 : &rp_count,
1367 : app->app_description,
1368 : app->len_app_description);
1369 : }
1370 : }
1371 :
1372 : return DLT_RETURN_OK;
1373 : }
1374 :
1375 2 : int dlt_client_cleanup_get_log_info(DltServiceGetLogInfoResponse *resp)
1376 : {
1377 : AppIDsType app;
1378 : int i = 0;
1379 : int j = 0;
1380 :
1381 2 : if (resp == NULL)
1382 : return DLT_RETURN_OK;
1383 :
1384 5 : for (i = 0; i < resp->log_info_type.count_app_ids; i++) {
1385 3 : app = resp->log_info_type.app_ids[i];
1386 :
1387 9 : for (j = 0; j < app.count_context_ids; j++) {
1388 6 : free(app.context_id_info[j].context_description);
1389 6 : app.context_id_info[j].context_description = NULL;
1390 : }
1391 :
1392 3 : free(app.context_id_info);
1393 : app.context_id_info = NULL;
1394 3 : free(app.app_description);
1395 : app.app_description = NULL;
1396 : }
1397 :
1398 2 : free(resp->log_info_type.app_ids);
1399 : resp->log_info_type.app_ids = NULL;
1400 :
1401 2 : free(resp);
1402 : resp = NULL;
1403 :
1404 2 : return DLT_RETURN_OK;
1405 : }
|