diff options
Diffstat (limited to 'src/shared')
-rwxr-xr-x | src/shared/dlt_common.c | 463 | ||||
-rw-r--r-- | src/shared/dlt_shm.c | 563 |
2 files changed, 563 insertions, 463 deletions
diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c index 4ac7dbe..d24527b 100755 --- a/src/shared/dlt_common.c +++ b/src/shared/dlt_common.c @@ -2231,469 +2231,6 @@ int dlt_check_storageheader(DltStorageHeader *storageheader) (storageheader->pattern[3] == 1)); } -int dlt_ringbuffer_init(DltRingBuffer *dltbuf, uint32_t size) -{ - - if (dltbuf==0) - { - return -1; - } - - if (size<=sizeof(uint32_t)) - { - return -1; - } - - dltbuf->buffer=(char*)malloc(size); - if (dltbuf->buffer==0) - { - return -1; - } - - dltbuf->size=size; - - dltbuf->pos_write=0; - dltbuf->pos_read=0; - - dltbuf->count=0; - - return 0; -} - -int dlt_ringbuffer_free(DltRingBuffer *dltbuf) -{ - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer) - { - free(dltbuf->buffer); - } - - dltbuf->buffer=0; - - dltbuf->size=0; - - dltbuf->pos_write=0; - dltbuf->pos_read=0; - - dltbuf->count=0; - - return 0; -} - -int dlt_ringbuffer_put(DltRingBuffer *dltbuf, void *data, uint32_t size) -{ - uint32_t sui, part1, part2; - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer==0) - { - return -1; - } - - if (data==0) - { - return -1; - } - - sui = sizeof(uint32_t); - - if ((size+sui)>dltbuf->size) - { - return -1; - } - - dlt_ringbuffer_checkandfreespace(dltbuf, (size+sui)); - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* Not enough space for one uint available before end of linear buffer */ - /* Start at begin of linear buffer */ - if ((dltbuf->size - dltbuf->pos_write) < sui) - { - dltbuf->pos_write = 0; - } - - /* Write length of following data to buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), &size, sui); - dltbuf->pos_write+=sui; - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - if ((dltbuf->size - dltbuf->pos_write) < size) - { - /* Not enough space til end of linear buffer, */ - /* split up write call */ - part1 = dltbuf->size - dltbuf->pos_write; - part2 = size - part1; - - memcpy(dltbuf->buffer + dltbuf->pos_write, data, part1); - memcpy(dltbuf->buffer, ((char*)data) + part1, part2); - dltbuf->pos_write = part2; - - } - else - { - /* Enough space til end of linear buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), data, size); - dltbuf->pos_write+=size; - } - - dltbuf->count++; - - return 0; -} - - -int dlt_ringbuffer_put3(DltRingBuffer *dltbuf, void *data1, uint32_t size1, void *data2, uint32_t size2, void *data3, uint32_t size3) -{ - uint32_t sui, part1, part2; - uint32_t total_size; - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer==0) - { - return -1; - } - - sui = sizeof(uint32_t); - - total_size = size1+size2+size3; - - if ((total_size+sui)>dltbuf->size) - { - return -1; - } - - dlt_ringbuffer_checkandfreespace(dltbuf, (total_size+sui)); - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* Not enough space for one uint available before end of linear buffer */ - /* Start at begin of linear buffer */ - if ((dltbuf->size - dltbuf->pos_write) < sui) - { - dltbuf->pos_write = 0; - } - - /* Write length of following data to buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), &total_size, sui); - dltbuf->pos_write+=sui; - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* First chunk of data (data1, size1) */ - if ((dltbuf->size - dltbuf->pos_write) < size1) - { - /* Not enough space til end of linear buffer, */ - /* split up write call */ - part1 = dltbuf->size - dltbuf->pos_write; - part2 = size1 - part1; - - memcpy(dltbuf->buffer + dltbuf->pos_write, data1, part1); - memcpy(dltbuf->buffer, ((char*)data1) + part1, part2); - dltbuf->pos_write = part2; - - } - else - { - /* Enough space til end of linear buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), data1, size1); - dltbuf->pos_write+=size1; - } - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* Second chunk of data (data2, size2) */ - if ((dltbuf->size - dltbuf->pos_write) < size2) - { - /* Not enough space til end of linear buffer, */ - /* split up write call */ - part1 = dltbuf->size - dltbuf->pos_write; - part2 = size2 - part1; - - memcpy(dltbuf->buffer + dltbuf->pos_write, data2, part1); - memcpy(dltbuf->buffer, ((char*)data2) + part1, part2); - dltbuf->pos_write = part2; - - } - else - { - /* Enough space til end of linear buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), data2, size2); - dltbuf->pos_write+=size2; - } - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* Third chunk of data (data3, size3) */ - if ((dltbuf->size - dltbuf->pos_write) < size3) - { - /* Not enough space til end of linear buffer, */ - /* split up write call */ - part1 = dltbuf->size - dltbuf->pos_write; - part2 = size3 - part1; - - memcpy(dltbuf->buffer + dltbuf->pos_write, data3, part1); - memcpy(dltbuf->buffer, ((char*)data3) + part1, part2); - dltbuf->pos_write = part2; - - } - else - { - /* Enough space til end of linear buffer */ - memcpy(dltbuf->buffer + dltbuf->pos_write, data3, size3); - dltbuf->pos_write+=size3; - } - - dltbuf->count++; - - return 0; -} - -int dlt_ringbuffer_get(DltRingBuffer *dltbuf, void *data, size_t *size) -{ - uint32_t tmpsize=0; - uint32_t sui; - - uint32_t part1, part2; - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer==0) - { - return -1; - } - - if (dltbuf->count==0) - { - return -1; - } - - sui = sizeof(uint32_t); - - if (dltbuf->pos_read >= dltbuf->size) - { - dltbuf->pos_read = 0; - } - - if ((dltbuf->size - dltbuf->pos_read) < sui) - { - dltbuf->pos_read = 0; - } - - /* printf("Reading at offset: %d\n", dltbuf->pos_read); */ - - memcpy(&tmpsize,&(dltbuf->buffer[dltbuf->pos_read]), sui); - dltbuf->pos_read += sui; - - if (dltbuf->pos_read >= dltbuf->size) - { - dltbuf->pos_read = 0; - } - - if ((tmpsize>0) && ((tmpsize+sizeof(uint32_t))<=dltbuf->size)) - { - if ((dltbuf->size - dltbuf->pos_read) < tmpsize) - { - /* Not enough space til end of linear buffer, */ - /* split up read call */ - part1 = dltbuf->size - dltbuf->pos_read; - part2 = tmpsize - part1; - - memcpy(data, dltbuf->buffer + dltbuf->pos_read, part1); - memcpy(((char*)data)+part1, dltbuf->buffer, part2); - dltbuf->pos_read = part2; - } - else - { - /* Enough space til end of linear buffer */ - /* no split up read call */ - memcpy(data, &(dltbuf->buffer[dltbuf->pos_read]), tmpsize); - dltbuf->pos_read+=tmpsize; - } - *size = tmpsize; - } - else - { - data=0; - *size=0; - } - - dltbuf->count--; - - return 0; -} - -int dlt_ringbuffer_get_skip(DltRingBuffer *dltbuf) -{ - uint32_t tmpsize=0; - uint32_t sui; - - uint32_t part1, part2; - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer==0) - { - return -1; - } - - if (dltbuf->count==0) - { - return -1; - } - - sui = sizeof(uint32_t); - - if (dltbuf->pos_read >= dltbuf->size) - { - dltbuf->pos_read = 0; - } - - if ((dltbuf->size - dltbuf->pos_read) < sui) - { - dltbuf->pos_read = 0; - } - - memcpy(&tmpsize,&(dltbuf->buffer[dltbuf->pos_read]), sui); - dltbuf->pos_read += sui; - - if (dltbuf->pos_read >= dltbuf->size) - { - dltbuf->pos_read = 0; - } - - if ((tmpsize>0) && ((tmpsize+sui)<=dltbuf->size)) - { - if ((dltbuf->size - dltbuf->pos_read) < tmpsize) - { - /* Not enough space til end of linear buffer */ - part1 = dltbuf->size - dltbuf->pos_read; - part2 = tmpsize - part1; - - dltbuf->pos_read = part2; - } - else - { - /* Enough space til end of linear buffer */ - dltbuf->pos_read+=tmpsize; - } - } - - dltbuf->count--; - - return 0; -} - -int dlt_ringbuffer_freespacewrite(DltRingBuffer *dltbuf, uint32_t *freespace) -{ - if ((dltbuf==0) || (freespace==0)) - { - return -1; - } - - *freespace=0; - - /* Space til pos_read */ - if (dltbuf->pos_read > dltbuf->pos_write) - { - *freespace=(dltbuf->pos_read - dltbuf->pos_write); - return 0; - } - else if (dltbuf->pos_read < dltbuf->pos_write) - { - *freespace=(dltbuf->size - dltbuf->pos_write + dltbuf->pos_read ); - return 0; - } - else - { - if (dltbuf->count) - { - return 0; - } - else - { - *freespace=dltbuf->size; - return 0; - } - } - return 0; -} - -int dlt_ringbuffer_checkandfreespace(DltRingBuffer *dltbuf, uint32_t reqspace) -{ - uint32_t space_left; - - if (dltbuf==0) - { - return -1; - } - - if (dlt_ringbuffer_freespacewrite(dltbuf,&space_left) == -1) - { - return -1; - } - - /* printf("Now reading at: %d, space_left = %d, req = %d, r=%d, w=%d, count=%d \n", - dltbuf->pos_read,space_left, reqspace, dltbuf->pos_read, dltbuf->pos_write, dltbuf->count); */ - - while (space_left<reqspace) - { - /* Overwrite, correct read position */ - - /* Read and skip one element */ - dlt_ringbuffer_get_skip(dltbuf); - - /* Space until pos_read */ - if (dlt_ringbuffer_freespacewrite(dltbuf,&space_left) == -1) - { - return -1; - } - - /* printf("Overwrite: Now reading at: %d, space_left = %d, req = %d, r=%d, w=%d, count=%d \n", - dltbuf->pos_read,space_left, reqspace, dltbuf->pos_read, dltbuf->pos_write, dltbuf->count); */ - } - - return 0; -} - #if !defined (__WIN32__) int dlt_setup_serial(int fd, speed_t speed) diff --git a/src/shared/dlt_shm.c b/src/shared/dlt_shm.c new file mode 100644 index 0000000..e3ec7c6 --- /dev/null +++ b/src/shared/dlt_shm.c @@ -0,0 +1,563 @@ +/* +* Dlt- Diagnostic Log and Trace user library +* @licence app begin@ + * + * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de> + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + * Public License, version 2.1, for more details. + * + * You should have received a copy of the GNU Lesser General Public License, version 2.1, along + * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>. + * + * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may + * also be applicable to programs even in cases in which the program is not a library in the technical sense. + * + * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may + * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to + * license your linked modules under the GNU Lesser General Public License, version 2.1, you + * may use the program under the following exception. + * + * As a special exception, the copyright holders of DLT give you permission to combine DLT + * with software programs or libraries that are released under any license unless such a combination is not + * permitted by the license of such a software program or library. You may copy and distribute such a + * system following the terms of the GNU Lesser General Public License, version 2.1, including this + * special exception, for DLT and the licenses of the other code concerned. + * + * Note that people who make modified versions of DLT are not obligated to grant this special exception + * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, + * version 2.1, gives permission to release a modified version without this exception; this exception + * also makes it possible to release a modified version which carries forward this exception. + * + * @licence end@ +*/ + + +/******************************************************************************* +** ** +** SRC-MODULE: dlt_shm.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +*******************************************************************************/ + +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/sem.h> +#include <sys/stat.h> +#include <stdio.h> +#include <string.h> + +#include <dlt_shm.h> + +void dlt_shm_print_hex(char *ptr,int size) +{ + int num; + + for (num=0;num<size;num++) + { + if((num%16)==15) + printf("%.2x\n",((unsigned char*)ptr)[num]); + else + printf("%.2x ",((unsigned char*)ptr)[num]); + } + printf("\n"); +} + +void dlt_shm_pv(int id,int operation) +{ + static struct sembuf semaphor; + + semaphor.sem_op = operation; + semaphor.sem_flg = SEM_UNDO; + + if(semop(id, &semaphor,1) == -1) { + perror("semop"); + } +} + +int dlt_shm_init_server(DltShm *buf,int key,int size) { + struct shmid_ds shm_buf; + + // Init parameters + buf->shm = NULL; + buf->shmid = 0; + buf->semid = 0; + buf->size = 0; + buf->mem = 0; + + // Create the segment. + if ((buf->shmid = shmget(key, size, IPC_CREAT | 0666)) < 0) { + perror("shmget"); + return -1; /* ERROR */ + } + + // get the size of shm + if (shmctl(buf->shmid, IPC_STAT, &shm_buf)) + { + perror("shmctl"); + return -1; /* ERROR */ + } + + // Now we attach the segment to our data space. + if ((buf->shm = shmat(buf->shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + return -1; /* ERROR */ + } + + // Init semaphore + if( (buf->semid = semget(DLT_SHM_SEM,1,S_IRWXU|S_IRWXG|IPC_CREAT|IPC_EXCL)) == -1 ) { + if( (buf->semid = semget(DLT_SHM_SEM,1,S_IRWXU|S_IRWXG|IPC_EXCL)) == -1 ) { + perror("semget"); + return -1; /* ERROR */ + } + } + if( semctl(buf->semid,0,SETVAL,(int)1) == -1 ) { + perror("semctl"); + return -1; /* ERROR */ + } + + // Init pointers + ((int*)(buf->shm))[0] = 0; // pointer to write memory + ((int*)(buf->shm))[1] = 0; // pointer to read memory + ((int*)(buf->shm))[2] = 0; // number of packets + buf->mem = (char*)(&(((int*)(buf->shm))[3])); + buf->size = shm_buf.shm_segsz - (buf->mem - buf->shm); + + // clear memory + memset(buf->mem,0,buf->size); + + //dlt_shm_status(buf); + //dlt_shm_info(buf); + printf("SHM: Size %d\n",buf->size); + + return 0; /* OK */ +} + +int dlt_shm_init_client(DltShm *buf,int key) { + struct shmid_ds shm_buf; + + // init parameters + buf->shm = NULL; + buf->shmid = 0; + buf->semid = 0; + buf->size = 0; + buf->mem = 0; + + // Create the segment. + if ((buf->shmid = shmget(key, 0, 0666)) < 0) { + perror("shmget"); + return -1; /* ERROR */ + } + + // get the size of shm + if (shmctl(buf->shmid, IPC_STAT, &shm_buf)) + { + perror("shmctl"); + return -1; /* ERROR */ + } + + // Now we attach the segment to our data space. + if ((buf->shm = shmat(buf->shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + return -1; /* ERROR */ + } + + // Init semaphore + if( (buf->semid = semget(DLT_SHM_SEM,0,0)) == -1 ) { + perror("semget"); + return -1; /* ERROR */ + } + DLT_SHM_SEM_FREE(buf->semid); + + // Init pointers + buf->mem = (char*)(&(((int*)(buf->shm))[3])); + buf->size = shm_buf.shm_segsz - (buf->mem - buf->shm); + + //dlt_shm_status(buf); + //dlt_shm_info(buf); + + return 0; /* OK */ +} + +void dlt_shm_info(DltShm *buf) +{ + + printf("SHM id: %d\n",buf->shmid); + printf("Available size: %d\n",buf->size); + printf("SHM full start address: %lX\n",(unsigned long)buf->shm); + printf("SHM start address: %lX\n",(unsigned long)buf->mem); + +} + +void dlt_shm_status(DltShm *buf) +{ + int write, read, count; + + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + + printf("Write: %d\n",write); + printf("Read: %d\n",read); + printf("Count: %d\n",count); + +} + +int dlt_shm_push(DltShm *buf,const unsigned char *data1,unsigned int size1,const unsigned char *data2,unsigned int size2,const unsigned char *data3,unsigned int size3) +{ + int write, read, count; + + if(!buf->mem) { + // shm not initialised + printf("SHM not initialised\n"); + return -1; /* ERROR */ + } + + // get semaphore + DLT_SHM_SEM_GET(buf->semid); + + // get current write pointer + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + + // check space and write pointer + if(read==write && count) { + // shm buffer is full + DLT_SHM_SEM_FREE(buf->semid); + //printf("SHM is totally full\n"); + return -1; // ERROR + } + else if(write >= buf->size) { + if((size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > read) { + DLT_SHM_SEM_FREE(buf->semid); + //printf("SHM is full at start\n"); + return -1; // ERROR + } + write = 0; + } + else if(read > write) { + if((write + size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > read) { + DLT_SHM_SEM_FREE(buf->semid); + //printf("SHM is full at end\n"); + return -1; // ERROR + } + } + else // read <= write + { + if((write+size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > buf->size) { + // data does not fit at end of buffer + // try write at beginning + if((size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > read) { + DLT_SHM_SEM_FREE(buf->semid); + //printf("SHM is full at start\n"); + return -1; // ERROR + } + // write zero status and size at end if possible + if((write+sizeof(unsigned char)+sizeof(int)) <= buf->size) { + *((unsigned char*)(buf->mem+write)) = 0; // init write status to unused + *((int*)(buf->mem+write+sizeof(unsigned char))) = 0; // init write size to unused + } + + write = 0; + } + } + + // update global shm pointers + ((int*)(buf->shm))[0] = write+sizeof(unsigned char)+sizeof(int)+size1+size2+size3; // set new write pointer + ((int*)(buf->shm))[2] += 1; // increase counter + + // update buffer pointers + *((unsigned char*)(buf->mem+write)) = 1; // set write status + *((int*)(buf->mem+write+sizeof(unsigned char))) = size1+size2+size3; // set write size + + // free semaphore + DLT_SHM_SEM_FREE(buf->semid); + + // write data + if(data1) + memcpy(buf->mem+write+sizeof(unsigned char)+sizeof(int),data1,size1); + if(data2) + memcpy(buf->mem+write+sizeof(unsigned char)+sizeof(int)+size1,data2,size2); + if(data3) + memcpy(buf->mem+write+sizeof(unsigned char)+sizeof(int)+size1+size2,data3,size3); + + // update write status + *((unsigned char*)(buf->mem+write)) = 2; + + return 0; // OK +} + +int dlt_shm_pull(DltShm *buf,unsigned char *data, int max_size) +{ + int write, read, count, size; + unsigned char status; + + if(!buf->mem) { + // shm not initialised + printf("SHM not initialised\n"); + return -1; /* ERROR */ + } + + // get current write pointer + DLT_SHM_SEM_GET(buf->semid); + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + DLT_SHM_SEM_FREE(buf->semid); + + // check if data is in there + if(count<=0) { + //printf("SHM is empty\n"); + return -1; // ERROR + } + + // check if end of buffer is reached and read status and size + if((read+sizeof(unsigned char)+sizeof(int)) <= buf->size) { + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + if(status == 0) { + // data fits not end of shm + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + } + else { + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + + // check status + if(status != 2 ) { + //printf("Buffer is not fully written\n"); + return -1; // ERROR + } + + // plausibility check of buffer size + if( (read+size) > buf->size) { + printf("Buffers size bigger than shm buffer\n"); + return -1; // ERROR + } + + // check max read size + if(size > max_size) { + printf("Buffer is bigger than max size\n"); + return -1; // ERROR + } + + // copy data + memcpy(data,buf->mem+read+sizeof(unsigned char)+sizeof(int),size); + + // update buffer pointers + ((int*)(buf->shm))[1] = read+sizeof(unsigned char)+sizeof(int)+size; // set new read pointer + ((int*)(buf->shm))[2] -= 1; // decrease counter + + return size; // OK +} + +int dlt_shm_copy(DltShm *buf,unsigned char *data, int max_size) +{ + int write, read, count, size; + unsigned char status; + + if(!buf->mem) { + // shm not initialised + printf("SHM not initialised\n"); + return -1; /* ERROR */ + } + + // get current write pointer + DLT_SHM_SEM_GET(buf->semid); + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + DLT_SHM_SEM_FREE(buf->semid); + + // check if data is in there + if(count<=0) { + //printf("SHM is empty\n"); + return -1; // ERROR + } + + // check if end of buffer is reached and read status and size + if((read+sizeof(unsigned char)+sizeof(int)) <= buf->size) { + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + if(status == 0) { + // data fits not end of shm + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + } + else { + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + + // check status + if(status != 2 ) { + //printf("Buffer is not fully written\n"); + return -1; // ERROR + } + + // plausibility check of buffer size + if( (read+size) > buf->size) { + printf("Buffers size bigger than shm buffer\n"); + return -1; // ERROR + } + + // check max read size + if(size > max_size) { + printf("Buffer is bigger than max size\n"); + return -1; // ERROR + } + + // copy data + memcpy(data,buf->mem+read+sizeof(unsigned char)+sizeof(int),size); + + return size; // OK +} + +int dlt_shm_remove(DltShm *buf) +{ + int write, read, count, size; + unsigned char status; + + if(!buf->mem) { + // shm not initialised + printf("SHM not initialised\n"); + return -1; /* ERROR */ + } + + // get current write pointer + DLT_SHM_SEM_GET(buf->semid); + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + DLT_SHM_SEM_FREE(buf->semid); + + // check if data is in there + if(count<=0) { + //printf("SHM is empty\n"); + return -1; // ERROR + } + + // check if end of buffer is reached and read status and size + if((read+sizeof(unsigned char)+sizeof(int)) <= buf->size) { + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + if(status == 0) { + // data fits not end of shm + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + } + else { + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + + // check status + if(status != 2 ) { + //printf("Buffer is not fully written\n"); + return -1; // ERROR + } + + // plausibility check of buffer size + if( (read+size) > buf->size) { + printf("Buffers size bigger than shm buffer\n"); + return -1; // ERROR + } + + // update buffer pointers + ((int*)(buf->shm))[1] = read+sizeof(unsigned char)+sizeof(int)+size; // set new read pointer + ((int*)(buf->shm))[2] -= 1; // decrease counter + + return size; // OK +} + +int dlt_shm_free_server(DltShm *buf) { + + if(!buf->shm) { + printf("Shared memory segment not attached\n"); + return -1; /* ERROR */ + } + + if(shmdt(buf->shm)) { + perror("shmdt"); + return -1; /* ERROR */ + } + + if(shmctl(buf->shmid,IPC_RMID,NULL) == -1) { + perror("shmdt"); + return -1; /* ERROR */ + } + + if(semctl(buf->semid,0,IPC_RMID,(int)0) == -1) { + perror("shmdt"); + return -1; /* ERROR */ + } + + // Reset parameters + buf->shm = NULL; + buf->shmid = 0; + buf->semid = 0; + buf->size = 0; + buf->mem = 0; + + return 0; /* OK */ +} + +int dlt_shm_free_client(DltShm *buf) { + + if(!buf->shm) { + printf("Shared memory segment not attached\n"); + return -1; /* ERROR */ + } + + if(shmdt(buf->shm)) { + perror("shmdt"); + return -1; /* ERROR */ + } + + // Reset parameters + buf->shm = NULL; + buf->shmid = 0; + buf->semid = 0; + buf->size = 0; + buf->mem = 0; + + return 0; /* OK */ +} |