Line data Source code
1 : /**
2 : * Copyright (C) 2013 - 2015 Advanced Driver Information Technology.
3 : * This code is developed by Advanced Driver Information Technology.
4 : * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
5 : *
6 : * This file is part of COVESA Project Dlt - Diagnostic Log and Trace console apps.
7 : *
8 : *
9 : * \copyright
10 : * This Source Code Form is subject to the terms of the
11 : * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
12 : * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
13 : *
14 : *
15 : * \author Syed Hameed <shameed@jp.adit-jv.com> ADIT 2013 - 2015
16 : * \author Christoph Lipka <clipka@jp.adit-jv.com> ADIT 2015
17 : * \author Frederic Berat <fberat@de.adit-jv.com> ADIT 2015
18 : *
19 : * \file dlt-logstorage-common.c
20 : * For further information see http://www.covesa.org/.
21 : */
22 :
23 : /*******************************************************************************
24 : ** **
25 : ** SRC-MODULE: dlt-logstorage-common.c **
26 : ** **
27 : ** TARGET : linux **
28 : ** **
29 : ** PROJECT : DLT **
30 : ** **
31 : ** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com **
32 : ** Frederic Berat fberat@de.adit-jv.com **
33 : ** PURPOSE : **
34 : ** **
35 : ** REMARKS : Code extracted from dlt-control-common.c and reworked. **
36 : ** **
37 : ** PLATFORM DEPENDANT [yes/no]: yes **
38 : ** **
39 : ** TO BE CHANGED BY USER [yes/no]: no **
40 : ** **
41 : *******************************************************************************/
42 :
43 : /*******************************************************************************
44 : ** Author Identity **
45 : ********************************************************************************
46 : ** **
47 : ** Initials Name Company **
48 : ** -------- ------------------------- ---------------------------------- **
49 : ** cl Christoph Lipka ADIT **
50 : ** fb Frederic Berat ADIT **
51 : *******************************************************************************/
52 : #define pr_fmt(fmt) "Logstorage common: "fmt
53 :
54 : #include <errno.h>
55 : #include <dirent.h>
56 : #include <stdio.h>
57 : #include <stdlib.h>
58 : #include <string.h>
59 : #include <unistd.h>
60 : #include <pthread.h>
61 : #include <sys/types.h>
62 : #include <sys/socket.h>
63 :
64 : #include "dlt_common.h"
65 : #include "dlt_protocol.h"
66 : #include "dlt_client.h"
67 :
68 : #include "dlt-control-common.h"
69 : #include "dlt-logstorage-common.h"
70 :
71 : #ifdef DLT_LOGSTORAGE_CTRL_UDEV_ENABLE
72 : # include "dlt-logstorage-udev.h"
73 : #endif
74 :
75 : #include "dlt-logstorage-prop.h"
76 :
77 : static struct LogstorageOptions {
78 : int event_type; /**< EVENT_UNMOUNTING/EVENT_MOUNTED */
79 : char device_path[DLT_MOUNT_PATH_MAX]; /**< Default Mount path */
80 : DltLogstorageHandler handler_type; /**< be controlled by udev or prop */
81 : long timeout; /**< Default timeout */
82 : } g_options = {
83 : .event_type = EVENT_MOUNTED,
84 : .handler_type = CTRL_NOHANDLER,
85 : };
86 :
87 4 : DltLogstorageHandler get_handler_type(void)
88 : {
89 4 : return g_options.handler_type;
90 : }
91 :
92 0 : void set_handler_type(char *type)
93 : {
94 0 : g_options.handler_type = CTRL_UDEV;
95 :
96 : if (type && check_proprietary_handling(type))
97 : g_options.handler_type = CTRL_PROPRIETARY;
98 0 : }
99 :
100 6 : int get_default_event_type(void)
101 : {
102 6 : return g_options.event_type;
103 : }
104 :
105 2 : void set_default_event_type(long type)
106 : {
107 2 : g_options.event_type = (int) type;
108 2 : }
109 :
110 2 : char *get_default_path(void)
111 : {
112 2 : return g_options.device_path;
113 : }
114 :
115 2 : void set_default_path(char *path)
116 : {
117 : memset(g_options.device_path, 0, DLT_MOUNT_PATH_MAX);
118 :
119 2 : if (path != NULL)
120 : strncpy(g_options.device_path, path, DLT_MOUNT_PATH_MAX - 1);
121 2 : }
122 :
123 : /* Used by the handlers */
124 : static DltLogstorageCtrl lctrl;
125 :
126 0 : DltLogstorageCtrl *get_logstorage_control(void)
127 : {
128 0 : return &lctrl;
129 : }
130 :
131 0 : void *dlt_logstorage_get_handler_cb(void)
132 : {
133 : union {
134 : void *ptr;
135 : int (*callback)(void);
136 : } callback_converter;
137 :
138 0 : callback_converter.callback = lctrl.callback;
139 0 : return callback_converter.ptr;
140 : }
141 :
142 0 : int dlt_logstorage_get_handler_fd(void)
143 : {
144 0 : return lctrl.fd;
145 : }
146 :
147 : /** @brief Initialized the handler based on configuration
148 : *
149 : * @return 0 on success, -1 otherwise.
150 : */
151 0 : int dlt_logstorage_init_handler(void)
152 : {
153 0 : switch (get_handler_type()) {
154 : case CTRL_PROPRIETARY:
155 : return dlt_logstorage_prop_init();
156 0 : case CTRL_UDEV:
157 : default:
158 : #ifdef DLT_LOGSTORAGE_CTRL_UDEV_ENABLE
159 : return dlt_logstorage_udev_init();
160 : #else
161 0 : return -1;
162 : #endif
163 : }
164 : }
165 :
166 : /** @brief Clean-up the handler based on configuration
167 : *
168 : * @return 0 on success, -1 otherwise.
169 : */
170 0 : int dlt_logstorage_deinit_handler(void)
171 : {
172 0 : switch (get_handler_type()) {
173 : case CTRL_PROPRIETARY:
174 : return dlt_logstorage_prop_deinit();
175 0 : case CTRL_UDEV:
176 : default:
177 : #ifdef DLT_LOGSTORAGE_CTRL_UDEV_ENABLE
178 : return dlt_logstorage_udev_deinit();
179 : #else
180 0 : return -1;
181 : #endif
182 : }
183 : }
184 :
185 : /** @brief Search for config file in given mount point
186 : *
187 : * The file is searched at the top directory. The function exits once it
188 : * founds it.
189 : *
190 : * @param mnt_point The mount point to check
191 : *
192 : * @return 1 if the file is found, 0 otherwise.
193 : */
194 0 : int dlt_logstorage_check_config_file(char *mnt_point)
195 : {
196 0 : struct dirent **files = NULL;
197 : int n;
198 : int i = 0;
199 : int ret = 0;
200 :
201 0 : if ((mnt_point == NULL) || (mnt_point[0] == '\0')) {
202 0 : pr_error("Mount point missing.\n");
203 0 : return ret;
204 : }
205 :
206 0 : pr_verbose("Now scanning %s\n", mnt_point);
207 :
208 0 : n = scandir(mnt_point, &files, NULL, alphasort);
209 :
210 0 : if (n <= 0 || files == NULL) {
211 0 : pr_error("Cannot read mounted directory\n");
212 0 : return ret;
213 : }
214 :
215 : do {
216 0 : pr_verbose("Checking %s.\n", files[i]->d_name);
217 :
218 0 : if (strncmp(files[i]->d_name, CONF_NAME, strlen(CONF_NAME)) == 0) {
219 : /* We found it ! */
220 0 : pr_verbose("File found.\n");
221 : ret = 1;
222 : break;
223 : }
224 0 : } while (++i < n);
225 :
226 0 : if (files != NULL) {
227 0 : for (i = 0; i < n; i++)
228 0 : free(files[i]);
229 0 : free(files);
230 : }
231 : return ret;
232 : }
233 :
234 : /** @brief Check if given mount point is writable
235 : *
236 : * @param mnt_point The mount point to check
237 : *
238 : * @return 1 if the file is writable, 0 otherwise.
239 : */
240 0 : int dlt_logstorage_check_directory_permission(char *mnt_point)
241 : {
242 0 : if (mnt_point == NULL) {
243 0 : pr_error("Given mount point is NULL\n");
244 0 : return 0;
245 : }
246 :
247 0 : if (access(mnt_point, W_OK) == 0)
248 : return 1;
249 :
250 : return 0;
251 : }
252 :
253 : /** @brief Prepares the body of the message to be send to DLT
254 : *
255 : * @param body A pointer to the MsgBody structure pointer
256 : * @param conn_type The type of the event (Mounted/Unmounting)
257 : * @param path The mount point path.
258 : *
259 : * @return The body once built or NULL.
260 : */
261 2 : static DltControlMsgBody *prepare_message_body(DltControlMsgBody **body,
262 : int conn_type,
263 : char *path)
264 : {
265 : DltServiceOfflineLogstorage *serv = NULL;
266 :
267 2 : if (path == NULL) {
268 0 : pr_error("Mount path is uninitialized.\n");
269 0 : return NULL;
270 : }
271 :
272 2 : pr_verbose("Sending event %d for %s.\n", conn_type, path);
273 :
274 2 : *body = calloc(1, sizeof(DltControlMsgBody));
275 :
276 2 : if (!*body) {
277 0 : pr_error("Not able to allocate memory for body.\n");
278 0 : return *body;
279 : }
280 :
281 2 : (*body)->data = calloc(1, sizeof(DltServiceOfflineLogstorage));
282 :
283 2 : if (!(*body)->data) {
284 0 : free(*body);
285 0 : *body = NULL;
286 0 : pr_error("Not able to allocate memory for body data.\n");
287 0 : return NULL;
288 : }
289 :
290 2 : (*body)->size = sizeof(DltServiceOfflineLogstorage);
291 :
292 : serv = (DltServiceOfflineLogstorage *)(*body)->data;
293 :
294 2 : serv->service_id = DLT_SERVICE_ID_OFFLINE_LOGSTORAGE;
295 2 : serv->connection_type = (uint8_t) conn_type;
296 : /* mount_point is DLT_MOUNT_PATH_MAX + 1 long,
297 : * and the memory is already zeroed.
298 : */
299 2 : strncpy(serv->mount_point, path, DLT_MOUNT_PATH_MAX - 1);
300 :
301 2 : pr_verbose("Body is now ready.\n");
302 :
303 2 : return *body;
304 : }
305 :
306 : /** @brief Send a logstorage event to DLT
307 : *
308 : * @param type The type of the event (Mounted/Unmounting)
309 : * @param mount_point The mount point for this event
310 : *
311 : * @return 0 On success, -1 otherwise.
312 : */
313 2 : int dlt_logstorage_send_event(int type, char *mount_point)
314 : {
315 : int ret = 0;
316 2 : DltControlMsgBody *msg_body = NULL;
317 :
318 : /* mount_point is checked against NULL in the preparation */
319 2 : if (!prepare_message_body(&msg_body, type, mount_point)) {
320 0 : pr_error("Data for Dlt Message body is NULL\n");
321 0 : return -1;
322 : }
323 :
324 2 : ret = dlt_control_send_message(msg_body, get_timeout());
325 :
326 2 : free(msg_body->data);
327 2 : free(msg_body);
328 :
329 2 : return ret;
330 : }
|