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_filetransfer.c
23 : */
24 :
25 : /*******************************************************************************
26 : ** **
27 : ** SRC-MODULE: dlt-test-client.c **
28 : ** **
29 : ** TARGET : linux **
30 : ** **
31 : ** PROJECT : DLT **
32 : ** **
33 : ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
34 : ** **
35 : ** PURPOSE : **
36 : ** **
37 : ** REMARKS : **
38 : ** **
39 : ** PLATFORM DEPENDANT [yes/no]: yes **
40 : ** **
41 : ** TO BE CHANGED BY USER [yes/no]: no **
42 : ** **
43 : *******************************************************************************/
44 :
45 : /*******************************************************************************
46 : ** Author Identity **
47 : ********************************************************************************
48 : ** **
49 : ** Initials Name Company **
50 : ** -------- ------------------------- ---------------------------------- **
51 : ** aw Alexander Wenzel BMW **
52 : *******************************************************************************/
53 :
54 : #include <errno.h>
55 : #include <stdio.h>
56 : #include <string.h>
57 : #include "dlt_filetransfer.h"
58 : #include "dlt_common.h"
59 : #include "dlt_user_macros.h"
60 :
61 : /*!Defines the buffer size of a single file package which will be logged to dlt */
62 : #define BUFFER_SIZE 1024
63 :
64 : /*!Defines the minimum timeout between two dlt logs. This is important because dlt should not be flooded with too many
65 : * logs in a short period of time. */
66 : #define MIN_TIMEOUT 20
67 :
68 :
69 : #define DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES INT_MAX
70 :
71 : #define NANOSEC_PER_MILLISEC 1000000
72 : #define NANOSEC_PER_SEC 1000000000
73 :
74 :
75 : /*!Buffer for dlt file transfer. The size is defined by BUFFER_SIZE */
76 : unsigned char buffer[BUFFER_SIZE];
77 :
78 :
79 : /*!Get some information about the file size of a file */
80 : /**See stat(2) for more informations.
81 : * @param file Absolute file path
82 : * @param ok Result of stat
83 : * @return Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
84 : */
85 0 : uint32_t getFilesize(const char* file, int* ok)
86 : {
87 : struct stat st;
88 :
89 0 : if (-1 == stat(file, &st)) {
90 : /*we can only return 0, as the value is unsigned */
91 0 : *ok = 0;
92 0 : return 0;
93 : }
94 :
95 0 : *ok = 1;
96 0 : return (uint32_t)st.st_size;
97 : }
98 :
99 : /** A simple Hash function for C-strings
100 : * @param str input string. E.g. a file path.
101 : * @param hash start and result value for hash computation
102 : *
103 : */
104 0 : void stringHash(const char* str, uint32_t* hash)
105 : {
106 0 : if (!str || !hash) {
107 : return;
108 : }
109 :
110 0 : unsigned int len = (unsigned int)strlen(str);
111 :
112 : unsigned int i = 0;
113 :
114 0 : if (len <= 0) {
115 : return;
116 : }
117 :
118 0 : for (i = 0; i < len; i++) {
119 0 : *hash = 53 * *hash + (uint32_t)(unsigned char)str[i];
120 : }
121 : }
122 :
123 :
124 : /*!Get some information about the file serial number of a file */
125 : /** See stat(2) for more informations.
126 : * @param file Absolute file path
127 : * @param ok *ok == 0 -> error; *ok == 1 -> ok
128 : * @return Returns a unique number associated with each filename
129 : */
130 0 : uint32_t getFileSerialNumber(const char* file, int* ok)
131 : {
132 : struct stat st;
133 : uint32_t ret;
134 :
135 0 : if (-1 == stat(file, &st)) {
136 0 : *ok = 0;
137 0 : ret = 0;
138 : } else {
139 0 : *ok = 1;
140 0 : ret = (uint32_t)st.st_ino;
141 0 : ret = ret << (sizeof(ret) * 8) / 2;
142 0 : ret |= (uint32_t)st.st_size;
143 0 : ret ^= (uint32_t)st.st_ctime;
144 0 : stringHash(file, &ret);
145 : }
146 :
147 0 : return ret;
148 : }
149 :
150 : /*!Returns the creation date of a file */
151 : /** See stat(2) for more informations.
152 : * @param file Absolute file path
153 : * @param ok Result of stat
154 : * @return Returns the creation date of a file
155 : */
156 0 : time_t getFileCreationDate(const char* file, int* ok)
157 : {
158 : struct stat st;
159 :
160 0 : if (-1 == stat(file, &st)) {
161 0 : *ok = 0;
162 0 : return 0;
163 : }
164 :
165 0 : *ok = 1;
166 0 : return st.st_ctime;
167 : }
168 :
169 : /*!Returns the creation date of a file */
170 : /** Format of the creation date is Day Mon dd hh:mm:ss yyyy
171 : * @param file Absolute file path
172 : * @param ok Result of stat
173 : * @param date Local time
174 : * @return Returns the creation date of a file
175 : */
176 0 : void getFileCreationDate2(const char* file, int* ok, char* date)
177 : {
178 : struct stat st;
179 : struct tm ts;
180 :
181 0 : if (-1 == stat(file, &st)) {
182 0 : *ok = 0;
183 : date = 0;
184 0 : return;
185 : }
186 :
187 0 : *ok = 1;
188 0 : tzset();
189 0 : localtime_r(&st.st_ctime, &ts);
190 0 : asctime_r(&ts, date);
191 : }
192 :
193 : /*!Checks if the file exists */
194 : /**@param file Absolute file path
195 : * @return Returns 1 if the file exists, 0 if the file does not exist
196 : */
197 0 : int isFile(const char* file)
198 : {
199 : struct stat st;
200 0 : return stat(file, &st) == 0;
201 : }
202 :
203 : /*!Waits a period of time */
204 : /**Waits a period of time. The minimal time to wait is MIN_TIMEOUT. This makes sure that the FIFO of dlt is not flooded.
205 : * @param timeout Timeout to in ms but can not be smaller as MIN_TIMEOUT
206 : */
207 0 : void doTimeout(unsigned int timeout)
208 : {
209 : struct timespec ts;
210 0 : ts.tv_sec = (long int)(timeout * NANOSEC_PER_MILLISEC) / NANOSEC_PER_SEC;
211 0 : ts.tv_nsec = (long int)(timeout * NANOSEC_PER_MILLISEC) % NANOSEC_PER_SEC;
212 0 : nanosleep(&ts, NULL);
213 0 : }
214 :
215 : /*!Checks free space of the user buffer */
216 : /**
217 : * @return -1 if more than 50% space in the user buffer is free. Otherwise 1 will be returned.
218 : */
219 0 : int checkUserBufferForFreeSpace(void)
220 : {
221 : int total_size, used_size;
222 :
223 0 : dlt_user_check_buffer(&total_size, &used_size);
224 :
225 0 : if ((total_size - used_size) < (total_size / 2)) {
226 0 : return -1;
227 : }
228 :
229 : return 1;
230 : }
231 :
232 : /*!Deletes the given file */
233 : /**
234 : * @param filename Absolute file path
235 : * @return If the file is successfully deleted, a zero value is returned.If the file can not be deleted a nonzero value
236 : * is returned.
237 : */
238 0 : int doRemoveFile(const char* filename)
239 : {
240 0 : return remove(filename);
241 : }
242 :
243 0 : void dlt_user_log_file_errorMessage(DltContext* fileContext, const char* filename, int errorCode)
244 : {
245 0 : if (errno != ENOENT) {
246 0 : int ok = 0;
247 0 : uint32_t fserial = getFileSerialNumber(filename, &ok);
248 :
249 0 : if (!ok) {
250 0 : DLT_LOG(
251 : *fileContext, DLT_LOG_ERROR,
252 : DLT_STRING("dlt_user_log_file_errorMessage, error in getFileSerialNumber for: "), DLT_STRING(filename));
253 : }
254 :
255 0 : uint32_t fsize = getFilesize(filename, &ok);
256 :
257 0 : if (!ok) {
258 0 : DLT_LOG(
259 : *fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_errorMessage, error in getFilesize for: "),
260 : DLT_STRING(filename));
261 : }
262 :
263 0 : char fcreationdate[50] = {0};
264 0 : getFileCreationDate2(filename, &ok, fcreationdate);
265 :
266 0 : if (!ok) {
267 0 : DLT_LOG(
268 : *fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_errorMessage, error in getFilesize for: "),
269 : DLT_STRING(filename));
270 : }
271 :
272 0 : int package_count = dlt_user_log_file_packagesCount(fileContext, filename);
273 :
274 0 : DLT_LOG(
275 : *fileContext, DLT_LOG_ERROR, DLT_STRING("FLER"), DLT_INT(errorCode), DLT_INT(-errno), DLT_UINT(fserial),
276 : DLT_STRING(filename), DLT_UINT(fsize), DLT_STRING(fcreationdate), DLT_INT(package_count),
277 : DLT_UINT(BUFFER_SIZE), DLT_STRING("FLER"));
278 : } else {
279 0 : DLT_LOG(
280 : *fileContext, DLT_LOG_ERROR, DLT_STRING("FLER"), DLT_INT(errorCode), DLT_INT(-errno), DLT_STRING(filename),
281 : DLT_STRING("FLER"));
282 : }
283 0 : }
284 :
285 :
286 :
287 : /*!Logs specific file inforamtions to dlt */
288 : /**The filename, file size, file serial number and the number of packages will be logged to dlt.
289 : * @param fileContext Specific context
290 : * @param filename Absolute file path
291 : * @return Returns 0 if everything was okey.If there was a failure a value < 0 will be returned.
292 : */
293 0 : int dlt_user_log_file_infoAbout(DltContext* fileContext, const char* filename)
294 : {
295 0 : if (isFile(filename)) {
296 : int ok;
297 :
298 0 : uint32_t fsize = getFilesize(filename, &ok);
299 :
300 0 : if (!ok) {
301 0 : DLT_LOG(
302 : *fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_infoAbout, Error getting size of file:"),
303 : DLT_STRING(filename));
304 : }
305 :
306 0 : uint32_t fserialnumber = getFileSerialNumber(filename, &ok);
307 :
308 0 : if (!ok) {
309 0 : DLT_LOG(
310 : *fileContext, DLT_LOG_ERROR,
311 : DLT_STRING("dlt_user_log_file_infoAbout, Error getting serial number of file:"), DLT_STRING(filename));
312 : }
313 :
314 0 : char creationdate[50] = {0};
315 0 : getFileCreationDate2(filename, &ok, creationdate);
316 :
317 0 : if (!ok) {
318 0 : DLT_LOG(
319 : *fileContext, DLT_LOG_ERROR,
320 : DLT_STRING("dlt_user_log_file_infoAbout, Error getting creation date of file:"), DLT_STRING(filename));
321 : }
322 :
323 0 : DLT_LOG(
324 : *fileContext, DLT_LOG_INFO, DLT_STRING("FLIF"), DLT_STRING("file serialnumber"), DLT_UINT(fserialnumber),
325 : DLT_STRING("filename"), DLT_STRING(filename), DLT_STRING("file size in bytes"), DLT_UINT(fsize),
326 : DLT_STRING("file creation date"), DLT_STRING(creationdate), DLT_STRING("number of packages"),
327 : DLT_UINT((unsigned int)dlt_user_log_file_packagesCount(fileContext, filename)), DLT_STRING("FLIF"));
328 : return 0;
329 : } else {
330 0 : dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_INFO_ABOUT);
331 0 : return DLT_FILETRANSFER_ERROR_INFO_ABOUT;
332 : }
333 : }
334 :
335 : /*!Transfer the complete file as several dlt logs. */
336 : /**This method transfer the complete file as several dlt logs. At first it will be checked that the file exist.
337 : * In the next step some generic informations about the file will be logged to dlt.
338 : * Now the header will be logged to dlt. See the method dlt_user_log_file_header for more informations.
339 : * Then the method dlt_user_log_data will be called with the parameter to log all packages in a loop with some timeout.
340 : * At last dlt_user_log_end is called to signal that the complete file transfer was okey. This is important for the
341 : * plugin of the dlt viewer.
342 : * @param fileContext Specific context to log the file to dlt
343 : * @param filename Absolute file path
344 : * @param deleteFlag Flag if the file will be deleted after transfer. 1->delete, 0->notDelete
345 : * @param timeout Timeout in ms to wait between some logs. Important that the FIFO of dlt will not be flooded with to
346 : * many messages in a short period of time.
347 : * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
348 : */
349 0 : int dlt_user_log_file_complete(DltContext* fileContext, const char* filename, int deleteFlag, unsigned int timeout)
350 : {
351 0 : if (!isFile(filename)) {
352 0 : dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_COMPLETE);
353 0 : return DLT_FILETRANSFER_ERROR_FILE_COMPLETE;
354 : }
355 :
356 0 : if (dlt_user_log_file_header(fileContext, filename) != 0) {
357 : return DLT_FILETRANSFER_ERROR_FILE_COMPLETE1;
358 : }
359 :
360 0 : if (dlt_user_log_file_data(fileContext, filename, DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES, timeout) != 0) {
361 : return DLT_FILETRANSFER_ERROR_FILE_COMPLETE2;
362 : }
363 :
364 0 : if (dlt_user_log_file_end(fileContext, filename, deleteFlag) != 0) {
365 0 : return DLT_FILETRANSFER_ERROR_FILE_COMPLETE3;
366 : }
367 :
368 : return 0;
369 : }
370 :
371 : /*!This method gives information about the number of packages the file have */
372 : /**Every file will be divided into several packages. Every package will be logged as a single dlt log.
373 : * The number of packages depends on the BUFFER_SIZE.
374 : * At first it will be checked if the file exist. Then the file will be divided into
375 : * several packages depending on the buffer size.
376 : * @param fileContext Specific context to log the file to dlt
377 : * @param filename Absolute file path
378 : * @return Returns the number of packages if everything was okey. If there was a failure a value < 0 will be returned.
379 : */
380 0 : int dlt_user_log_file_packagesCount(DltContext* fileContext, const char* filename)
381 : {
382 : int packages;
383 : uint32_t filesize;
384 :
385 0 : if (isFile(filename)) {
386 : packages = 1;
387 : int ok;
388 0 : filesize = getFilesize(filename, &ok);
389 :
390 0 : if (!ok) {
391 0 : DLT_LOG(
392 : *fileContext, DLT_LOG_ERROR, DLT_STRING("Error in: dlt_user_log_file_packagesCount, isFile"),
393 : DLT_STRING(filename), DLT_INT(DLT_FILETRANSFER_ERROR_PACKAGE_COUNT));
394 0 : return -1;
395 : }
396 :
397 0 : if (filesize < BUFFER_SIZE) {
398 : return packages;
399 : } else {
400 0 : packages = (int)(filesize / BUFFER_SIZE);
401 :
402 0 : if (filesize % BUFFER_SIZE == 0) {
403 : return packages;
404 : } else {
405 0 : return packages + 1;
406 : }
407 : }
408 : } else {
409 0 : DLT_LOG(
410 : *fileContext, DLT_LOG_ERROR, DLT_STRING("Error in: dlt_user_log_file_packagesCount, !isFile"),
411 : DLT_STRING(filename), DLT_INT(DLT_FILETRANSFER_ERROR_PACKAGE_COUNT));
412 0 : return -1;
413 : }
414 : }
415 :
416 : /*!Transfer the head of the file as a dlt logs. */
417 : /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number,
418 : * the file name, the file size, package number the file have and the buffer size.
419 : * All these informations are needed from the plugin of the dlt viewer.
420 : * See the Mainpages.c for more informations.
421 : * @param fileContext Specific context to log the file to dlt
422 : * @param filename Absolute file path
423 : * @param alias Alias for the file. An alternative name to show in the receiving end
424 : * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
425 : */
426 0 : int dlt_user_log_file_header_alias(DltContext* fileContext, const char* filename, const char* alias)
427 : {
428 0 : if (isFile(filename)) {
429 : int ok;
430 :
431 0 : uint32_t fserialnumber = getFileSerialNumber(filename, &ok);
432 :
433 0 : if (!ok) {
434 0 : DLT_LOG(
435 : *fileContext, DLT_LOG_ERROR,
436 : DLT_STRING("dlt_user_log_file_header_alias, Error getting serial number of file:"),
437 : DLT_STRING(filename));
438 0 : return DLT_FILETRANSFER_FILE_SERIAL_NUMBER;
439 : }
440 :
441 0 : uint32_t fsize = getFilesize(filename, &ok);
442 :
443 0 : if (!ok) {
444 0 : DLT_LOG(
445 : *fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_header_alias, Error getting size of file:"),
446 : DLT_STRING(filename));
447 : }
448 :
449 0 : char fcreationdate[50] = {0};
450 0 : getFileCreationDate2(filename, &ok, fcreationdate);
451 :
452 0 : if (!ok) {
453 0 : DLT_LOG(
454 : *fileContext, DLT_LOG_ERROR,
455 : DLT_STRING("dlt_user_log_file_header_alias, Error getting creation date of file:"),
456 : DLT_STRING(filename));
457 : }
458 :
459 0 : DLT_LOG(*fileContext, DLT_LOG_INFO, DLT_STRING("FLST"), DLT_UINT(fserialnumber), DLT_STRING(alias),
460 : DLT_UINT(fsize), DLT_STRING(fcreationdate);
461 : DLT_UINT((unsigned int)dlt_user_log_file_packagesCount(fileContext, filename)), DLT_UINT(BUFFER_SIZE),
462 : DLT_STRING("FLST"));
463 :
464 0 : return 0;
465 : } else {
466 0 : dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_HEAD);
467 0 : return DLT_FILETRANSFER_ERROR_FILE_HEAD;
468 : }
469 : }
470 :
471 : /*!Transfer the head of the file as a dlt logs. */
472 : /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number,
473 : * the file name, the file size, package number the file have and the buffer size.
474 : * All these informations are needed from the plugin of the dlt viewer.
475 : * See the Mainpages.c for more informations.
476 : * @param fileContext Specific context to log the file to dlt
477 : * @param filename Absolute file path
478 : * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
479 : */
480 0 : int dlt_user_log_file_header(DltContext* fileContext, const char* filename)
481 : {
482 0 : if (isFile(filename)) {
483 : int ok;
484 :
485 0 : uint32_t fserialnumber = getFileSerialNumber(filename, &ok);
486 :
487 0 : if (!ok) {
488 0 : DLT_LOG(
489 : *fileContext, DLT_LOG_ERROR,
490 : DLT_STRING("dlt_user_log_file_header, Error getting serial number of file:"), DLT_STRING(filename));
491 : }
492 :
493 0 : uint32_t fsize = getFilesize(filename, &ok);
494 :
495 0 : if (!ok) {
496 0 : DLT_LOG(
497 : *fileContext, DLT_LOG_ERROR, DLT_STRING("dlt_user_log_file_header, Error getting size of file:"),
498 : DLT_STRING(filename));
499 : }
500 :
501 0 : char fcreationdate[50] = {0};
502 0 : getFileCreationDate2(filename, &ok, fcreationdate);
503 :
504 0 : if (!ok) {
505 0 : DLT_LOG(
506 : *fileContext, DLT_LOG_ERROR,
507 : DLT_STRING("dlt_user_log_file_header, Error getting creation date of file:"), DLT_STRING(filename));
508 : }
509 :
510 0 : DLT_LOG(*fileContext, DLT_LOG_INFO, DLT_STRING("FLST"), DLT_UINT(fserialnumber), DLT_STRING(filename),
511 : DLT_UINT(fsize), DLT_STRING(fcreationdate);
512 : DLT_UINT((unsigned int)dlt_user_log_file_packagesCount(fileContext, filename)), DLT_UINT(BUFFER_SIZE),
513 : DLT_STRING("FLST"));
514 :
515 : return 0;
516 : } else {
517 0 : dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_HEAD);
518 0 : return DLT_FILETRANSFER_ERROR_FILE_HEAD;
519 : }
520 : }
521 :
522 : /*!Transfer the content data of a file. */
523 : /**See the Mainpages.c for more informations.
524 : * @param fileContext Specific context to log the file to dlt
525 : * @param filename Absolute file path
526 : * @param packageToTransfer Package number to transfer. If this param is LONG_MAX, the whole file will be transferred
527 : * with a specific timeout
528 : * @param timeout Timeout to wait between dlt logs. Important because the dlt FIFO should not be flooded. Default is
529 : * defined by MIN_TIMEOUT. The given timeout in ms can not be smaller than MIN_TIMEOUT.
530 : * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
531 : */
532 0 : int dlt_user_log_file_data(DltContext* fileContext, const char* filename, int packageToTransfer, unsigned int timeout)
533 : {
534 0 : bool fileCancelTransferFlag = false;
535 0 : return dlt_user_log_file_data_cancelable(
536 : fileContext, filename, packageToTransfer, timeout, &fileCancelTransferFlag);
537 : }
538 :
539 : /* !Transfer the content data of a cancelable file*/
540 : /**See the Mainpages.c for more informations.
541 : * @param fileContext Specific context to log the file to dlt
542 : * @param filename Absolute file path
543 : * @param packageToTransfer Package number to transfer. If this param is LONG_MAX, the whole file will be transferred
544 : * with a specific timeout
545 : * @param timeout Timeout to wait between dlt logs. Important because the dlt FIFO should not be flooded. Default is
546 : * defined by MIN_TIMEOUT. The given timeout in ms can not be smaller than MIN_TIMEOUT.
547 : * @param fileCancelTransferFlag is a bool pointer to cancel the filetransfer on demand. For example in case of
548 : * application shutdown event outstanding file transfer should abort and return
549 : * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned.
550 : */
551 0 : int dlt_user_log_file_data_cancelable(
552 : DltContext* fileContext, const char* filename, int packageToTransfer, unsigned int timeout,
553 : bool* const fileCancelTransferFlag)
554 : {
555 : FILE* file;
556 : int pkgNumber;
557 : uint32_t readBytes;
558 :
559 0 : if (isFile(filename)) {
560 0 : file = fopen(filename, "rb");
561 :
562 0 : if (file == NULL) {
563 0 : dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_DATA);
564 0 : return DLT_FILETRANSFER_ERROR_FILE_DATA;
565 : }
566 :
567 0 : if (((packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES)
568 0 : && (packageToTransfer > dlt_user_log_file_packagesCount(fileContext, filename)))
569 0 : || (packageToTransfer <= 0)) {
570 0 : DLT_LOG(
571 : *fileContext, DLT_LOG_ERROR,
572 : DLT_STRING("Error at dlt_user_log_file_data: packageToTransfer out of scope"),
573 : DLT_STRING("packageToTransfer:"), DLT_UINT((unsigned int)packageToTransfer),
574 : DLT_STRING("numberOfMaximalPackages:"),
575 : DLT_UINT((unsigned int)dlt_user_log_file_packagesCount(fileContext, filename)), DLT_STRING("for File:"),
576 : DLT_STRING(filename));
577 0 : fclose(file);
578 0 : return DLT_FILETRANSFER_ERROR_FILE_DATA;
579 : }
580 :
581 : readBytes = 0;
582 :
583 0 : if (packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES) {
584 : /* If a single package should be transferred. The user has to check that the free space in
585 : * the user buffer > 50% */
586 : /* if(checkUserBufferForFreeSpace()<0) */
587 : /* return DLT_FILETRANSFER_ERROR_FILE_DATA_USER_BUFFER_FAILED; */
588 :
589 0 : if (0 != fseek(file, (packageToTransfer - 1) * BUFFER_SIZE, SEEK_SET)) {
590 0 : DLT_LOG(
591 : *fileContext, DLT_LOG_ERROR, DLT_STRING("failed to fseek in file: "), DLT_STRING(filename),
592 : DLT_STRING("ferror:"), DLT_INT(ferror(file)));
593 :
594 0 : fclose(file);
595 0 : return -1;
596 : }
597 :
598 : readBytes = (uint32_t)fread(buffer, sizeof(char), BUFFER_SIZE, file);
599 : int ok;
600 :
601 0 : uint32_t fserial = getFileSerialNumber(filename, &ok);
602 :
603 0 : if (1 != ok) {
604 0 : DLT_LOG(
605 : *fileContext, DLT_LOG_ERROR, DLT_STRING("failed to get FileSerialNumber for: "),
606 : DLT_STRING(filename));
607 0 : fclose(file);
608 0 : return DLT_FILETRANSFER_FILE_SERIAL_NUMBER;
609 : }
610 :
611 0 : DLT_LOG(
612 : *fileContext, DLT_LOG_INFO, DLT_STRING("FLDA"), DLT_UINT(fserial),
613 : DLT_UINT((unsigned int)packageToTransfer), DLT_RAW(buffer, (uint16_t)readBytes), DLT_STRING("FLDA"));
614 :
615 0 : if (*fileCancelTransferFlag) {
616 0 : DLT_LOG(
617 : *fileContext, DLT_LOG_ERROR, DLT_STRING("FLER"),
618 : DLT_INT(DLT_FILETRANSFER_ERROR_FILE_END_USER_CANCELLED));
619 0 : return DLT_FILETRANSFER_ERROR_FILE_END_USER_CANCELLED;
620 : }
621 0 : doTimeout(timeout);
622 : } else {
623 : pkgNumber = 0;
624 :
625 0 : while (!feof(file)) {
626 : /* If the complete file should be transferred, the user buffer will be checked. */
627 : /* If free space < 50% the package won't be transferred. */
628 0 : if (checkUserBufferForFreeSpace() > 0) {
629 0 : pkgNumber++;
630 0 : readBytes = (uint32_t)fread(buffer, sizeof(char), BUFFER_SIZE, file);
631 :
632 0 : if (readBytes == 0) {
633 : // If the file size is divisible by the package size don't send
634 : // one empty FLDA. Also we send the correct number of FLDAs too.
635 : break;
636 : }
637 :
638 : int ok;
639 :
640 0 : uint32_t fserial = getFileSerialNumber(filename, &ok);
641 :
642 0 : if (1 != ok) {
643 0 : DLT_LOG(
644 : *fileContext, DLT_LOG_ERROR, DLT_STRING("failed to get FileSerialNumber for: "),
645 : DLT_STRING(filename));
646 0 : fclose(file);
647 0 : return DLT_FILETRANSFER_FILE_SERIAL_NUMBER;
648 : }
649 :
650 0 : DLT_LOG(
651 : *fileContext, DLT_LOG_INFO, DLT_STRING("FLDA"), DLT_UINT(fserial),
652 : DLT_UINT((unsigned int)pkgNumber), DLT_RAW(buffer, (uint16_t)readBytes), DLT_STRING("FLDA"));
653 0 : if (*fileCancelTransferFlag) {
654 0 : DLT_LOG(
655 : *fileContext, DLT_LOG_ERROR, DLT_STRING("FLER"),
656 : DLT_INT(DLT_FILETRANSFER_ERROR_FILE_END_USER_CANCELLED));
657 0 : return DLT_FILETRANSFER_ERROR_FILE_END_USER_CANCELLED;
658 : }
659 : } else {
660 0 : fclose(file);
661 0 : return DLT_FILETRANSFER_ERROR_FILE_DATA_USER_BUFFER_FAILED;
662 : }
663 0 : doTimeout(timeout);
664 : }
665 : }
666 :
667 0 : fclose(file);
668 :
669 0 : return 0;
670 : } else {
671 0 : dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_DATA);
672 0 : return DLT_FILETRANSFER_ERROR_FILE_DATA;
673 : }
674 : }
675 : /*!Transfer the end of the file as a dlt logs. */
676 : /**The end of the file must be logged to dlt because the end contains inforamtion about the file serial number.
677 : * This informations is needed from the plugin of the dlt viewer.
678 : * See the Mainpages.c for more informations.
679 : * @param fileContext Specific context to log the file to dlt
680 : * @param filename Absolute file path
681 : * @param deleteFlag Flag to delete the file after the whole file is transferred (logged to dlt).1->delete,0->NotDelete
682 : * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
683 : */
684 0 : int dlt_user_log_file_end(DltContext* fileContext, const char* filename, int deleteFlag)
685 : {
686 0 : if (isFile(filename)) {
687 : int ok;
688 0 : uint32_t fserial = getFileSerialNumber(filename, &ok);
689 :
690 0 : if (1 != ok) {
691 0 : DLT_LOG(
692 : *fileContext, DLT_LOG_ERROR, DLT_STRING("failed to get FileSerialNumber for: "), DLT_STRING(filename));
693 0 : return DLT_FILETRANSFER_FILE_SERIAL_NUMBER;
694 : }
695 :
696 0 : DLT_LOG(*fileContext, DLT_LOG_INFO, DLT_STRING("FLFI"), DLT_UINT(fserial), DLT_STRING("FLFI"));
697 :
698 0 : if (deleteFlag) {
699 0 : if (doRemoveFile(filename) != 0) {
700 0 : dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_END);
701 0 : return -1;
702 : }
703 : }
704 :
705 0 : return 0;
706 : } else {
707 0 : dlt_user_log_file_errorMessage(fileContext, filename, DLT_FILETRANSFER_ERROR_FILE_END);
708 0 : return DLT_FILETRANSFER_ERROR_FILE_END;
709 : }
710 : }
|