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