From c74050b028d91c9bb8995dafba440babc7b621ff Mon Sep 17 00:00:00 2001 From: Alexander Wenzel Date: Mon, 14 Nov 2011 19:28:47 +0100 Subject: Created abstraction of shm buffer management. --- include/dlt/dlt_common.h | 44 +++++ include/dlt/dlt_shm.h | 6 +- src/shared/dlt_common.c | 413 +++++++++++++++++++++++++++++++++++++++++ src/shared/dlt_shm.c | 474 ++++------------------------------------------- 4 files changed, 492 insertions(+), 445 deletions(-) diff --git a/include/dlt/dlt_common.h b/include/dlt/dlt_common.h index be315a0..cb317c6 100755 --- a/include/dlt/dlt_common.h +++ b/include/dlt/dlt_common.h @@ -417,6 +417,7 @@ typedef struct */ typedef struct { + uint32_t service_id; /**< service ID */ char apid[DLT_ID_SIZE]; /**< application id */ char ctid[DLT_ID_SIZE]; /**< context id */ @@ -557,6 +558,26 @@ typedef struct uint32_t count; /**< nr. of entries */ } DltRingBuffer; +typedef struct +{ + char* shm; /* pointer to beginning of shared memory */ + int size; /* size of data area in shared memory */ + char* mem; /* pointer to data area in shared memory */ + + uint32_t min_size; /**< Minimum size of buffer */ + uint32_t max_size; /**< Maximum size of buffer */ + uint32_t step_size; /**< Step size of buffer */ +} DltBuffer; + +#define DLT_BUFFER_HEAD "SHM" + +typedef struct +{ + char head[4]; + unsigned char status; + int size; +} DltBufferBlockHead; + #ifdef __cplusplus extern "C" { @@ -942,6 +963,29 @@ extern "C" */ int dlt_check_storageheader(DltStorageHeader *storageheader); + + int dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size); + int dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size); + int dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size,uint32_t step_size); + int dlt_buffer_free_static(DltBuffer *buf); + int dlt_buffer_free_dynamic(DltBuffer *buf); + int dlt_buffer_push(DltBuffer *buf,const unsigned char *data,unsigned int size); + int dlt_buffer_push3(DltBuffer *buf,const unsigned char *data1,unsigned int size1,const unsigned char *data2,unsigned int size2,const unsigned char *data3,unsigned int size3); + int dlt_buffer_pull(DltBuffer *buf,unsigned char *data, int max_size); + int dlt_buffer_copy(DltBuffer *buf,unsigned char *data, int max_size); + int dlt_buffer_remove(DltBuffer *buf); + void dlt_buffer_info(DltBuffer *buf); + void dlt_buffer_status(DltBuffer *buf); + int dlt_buffer_get_total_size(DltBuffer *buf); + int dlt_buffer_get_used_size(DltBuffer *buf); + int dlt_buffer_get_message_count(DltBuffer *buf); + + int dlt_buffer_get(DltBuffer *buf,unsigned char *data, int max_size,int delete); + int dlt_buffer_reset(DltBuffer *buf); + void dlt_buffer_write_block(DltBuffer *buf,int *write, const unsigned char *data,unsigned int size); + void dlt_buffer_read_block(DltBuffer *buf,int *read,unsigned char *data,unsigned int size); + + /** * Initialize ringbuffer of with a maximum size of size * @param dltbuf Pointer to ringbuffer structure diff --git a/include/dlt/dlt_shm.h b/include/dlt/dlt_shm.h index 3744ec7..b623981 100644 --- a/include/dlt/dlt_shm.h +++ b/include/dlt/dlt_shm.h @@ -68,6 +68,8 @@ #ifndef DLT_SHM_H #define DLT_SHM_H +#include + /* shared memory key */ /* must be the same for server and cleint */ #define DLT_SHM_KEY 11771 @@ -88,9 +90,7 @@ typedef struct { int shmid; /* Id of shared memory */ int semid; /* Id of semaphore */ - char* shm; /* pointer to beginning of shared memory */ - int size; /* size of data area in shared memory */ - char* mem; /* pointer to data area in shared memory */ + DltBuffer buffer; } DltShm; typedef struct diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c index fc6d49b..8e52265 100755 --- a/src/shared/dlt_common.c +++ b/src/shared/dlt_common.c @@ -2272,6 +2272,419 @@ int dlt_check_storageheader(DltStorageHeader *storageheader) (storageheader->pattern[3] == 1)); } + + + + + + + + + + + +int dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size) +{ + char str[256]; + + // Init parameters + buf->shm = ptr; + buf->min_size = size; + buf->max_size = size; + buf->step_size = 0; + + // 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 = size - (buf->mem - buf->shm); + + // clear memory + memset(buf->mem,0,buf->size); + + snprintf(str,sizeof(str),"Buffer: Size %d\n",buf->size); + dlt_log(LOG_INFO, str); + + return 0; /* OK */ +} + +int dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size) +{ + char str[256]; + + // Init parameters + buf->shm = ptr; + buf->min_size = size; + buf->max_size = size; + buf->step_size = 0; + + // Init pointers + buf->mem = (char*)(&(((int*)(buf->shm))[3])); + buf->size = size - (buf->mem - buf->shm); + + snprintf(str,sizeof(str),"Buffer: Size %d\n",buf->size); + dlt_log(LOG_INFO, str); + + return 0; /* OK */ +} + +int dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size,uint32_t step_size) +{ + char str[256]; + + // Init parameters + buf->min_size = min_size; + buf->max_size = max_size; + buf->step_size = step_size; + + // allocat memory + buf->shm = malloc(buf->min_size+3*sizeof(int)); + if(buf->shm == NULL) { + snprintf(str,sizeof(str),"Buffer: Cannot allocate %d bytes\n",buf->min_size); + dlt_log(LOG_EMERG, str); + return -1; + } + + // 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 = buf->min_size - 3 * sizeof(int); + + // clear memory + memset(buf->mem,0,buf->size); + + snprintf(str,sizeof(str),"Buffer: Size %d bytes\n",buf->size); + dlt_log(LOG_INFO, str); + + return 0; /* OK */ +} + +int dlt_buffer_free_static(DltBuffer *buf) +{ + if(!buf->mem) { + // buffer not initialised + dlt_log(LOG_ERR,"Buffer: Buffer not initialised\n"); + return -1; /* ERROR */ + } + + return 0; +} + +int dlt_buffer_free_dynamic(DltBuffer *buf) +{ + if(!buf->mem) { + // buffer not initialised + dlt_log(LOG_ERR,"Buffer: Buffer not initialised\n"); + return -1; /* ERROR */ + } + + free(buf->shm); + + return 0; +} + +void dlt_buffer_write_block(DltBuffer *buf,int *write, const unsigned char *data,unsigned int size) +{ + if((*write+size) <= buf->size) { + // write one block + memcpy(buf->mem+*write,data,size); + *write += size; + } + else { + // write two blocks + memcpy(buf->mem+*write, data, buf->size-*write); + memcpy(buf->mem, data+buf->size-*write, size-buf->size+*write); + *write += size-buf->size; + } +} + +void dlt_buffer_read_block(DltBuffer *buf,int *read,unsigned char *data,unsigned int size) +{ + if((*read+size) <= buf->size) { + // read one block + memcpy(data,buf->mem+*read,size); + *read += size; + } + else { + // read two blocks + memcpy(data, buf->mem+*read, buf->size-*read); + memcpy(data+buf->size-*read, buf->mem, size-buf->size+*read); + *read += size-buf->size; + } +} + +int dlt_buffer_reset(DltBuffer *buf) +{ + dlt_log(LOG_ERR,"Buffer: Buffer reset triggered.\n"); + + /* reset pointers and counters */ + ((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 + + // clear memory + memset(buf->mem,0,buf->size); + + return 0; /* OK */ +} + +int dlt_buffer_push(DltBuffer *buf,const unsigned char *data,unsigned int size) +{ + return dlt_buffer_push3(buf,data,size,0,0,0,0); +} + +int dlt_buffer_push3(DltBuffer *buf,const unsigned char *data1,unsigned int size1,const unsigned char *data2,unsigned int size2,const unsigned char *data3,unsigned int size3) +{ + int free_size; + int write, read; + DltBufferBlockHead head; + + if(!buf->mem) { + // buffer not initialised + dlt_log(LOG_ERR,"Buffer: Buffer not initialised\n"); + return -1; /* ERROR */ + } + + // get current write pointer + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + + // check pointers + if((read>buf->size) || (write>buf->size)) + { + dlt_log(LOG_ERR,"Buffer: Pointer out of range\n"); + dlt_buffer_reset(buf); + return -1; // ERROR + } + + // calculate free size + if(read>write) + free_size = read - write; + else + free_size = buf->size - write + read; + + // check size + if(free_size < (sizeof(DltBufferBlockHead)+size1+size2+size3)) { + dlt_log(LOG_ERR,"Buffer: Buffer is full\n"); + return -1; // ERROR + } + + // set header + strcpy(head.head,DLT_BUFFER_HEAD); + head.status = 2; + head.size = size1+size2+size3; + + // write data + dlt_buffer_write_block(buf,&write,(unsigned char*)&head,sizeof(DltBufferBlockHead)); + if(size1) dlt_buffer_write_block(buf,&write,data1,size1); + if(size2) dlt_buffer_write_block(buf,&write,data2,size2); + if(size3) dlt_buffer_write_block(buf,&write,data3,size3); + + // update global shm pointers + ((int*)(buf->shm))[0] = write; // set new write pointer + ((int*)(buf->shm))[2] += 1; // increase counter + + return 0; // OK + +} + +int dlt_buffer_get(DltBuffer *buf,unsigned char *data, int max_size,int delete) +{ + int used_size; + int write, read, count; + char head_compare[] = DLT_BUFFER_HEAD; + DltBufferBlockHead head; + + if(!buf->mem) { + // shm not initialised + dlt_log(LOG_ERR,"Buffer: SHM not initialised\n"); + return -1; /* ERROR */ + } + + // get current write pointer + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + + // check pointers + if((read>buf->size) || (write>buf->size) || (count<0)) + { + dlt_log(LOG_ERR,"Buffer: Pointer out of range\n"); + dlt_buffer_reset(buf); + return -1; // ERROR + } + + // check if data is in there + if(count==0) { + if(write!=read) + { + dlt_log(LOG_ERR,"Buffer: SHM should be empty, but is not\n"); + dlt_buffer_reset(buf); + } + return -1; // ERROR + } + + // calculate used size + if(write>read) + used_size = write - read; + else + used_size = buf->size - read + write; + + // first check size + if(used_size < (sizeof(DltBufferBlockHead))) { + dlt_log(LOG_ERR,"Buffer: Size check 1 failed\n"); + dlt_buffer_reset(buf); + return -1; // ERROR + } + + // read header + dlt_buffer_read_block(buf,&read,(unsigned char*)&head,sizeof(DltBufferBlockHead)); + + // check header + if(memcmp((unsigned char*)(head.head),head_compare,sizeof(head_compare))!=0) + { + dlt_log(LOG_ERR,"Buffer: Header head check failed\n"); + dlt_buffer_reset(buf); + return -1; // ERROR + } + if(head.status != 2) + { + dlt_log(LOG_ERR,"Buffer: Header status check failed\n"); + dlt_buffer_reset(buf); + return -1; // ERROR + } + + // second check size + if(used_size < (sizeof(DltBufferBlockHead)+head.size)) { + dlt_log(LOG_ERR,"Buffer: Size check 2 failed\n"); + dlt_buffer_reset(buf); + return -1; // ERROR + } + + // third check size + if(max_size && (head.size > max_size)) { + dlt_log(LOG_ERR,"Buffer: Size check 3 failed\n"); + // nothing to do but data does not fit provided buffer + } + + if(data && max_size) + { + // read data + dlt_buffer_read_block(buf,&read,data,head.size); + + if(delete) + { + // update buffer pointers + ((int*)(buf->shm))[1] = read; // set new read pointer + } + } + else + { + if(delete) { + if( (read+head.size) <= buf->size) + ((int*)(buf->shm))[1] = read+head.size; // set new read pointer + else + ((int*)(buf->shm))[1] = read+head.size-buf->size; // set new read pointer + } + } + if(delete) { + ((int*)(buf->shm))[2] -= 1; // decrease counter + } + + return head.size; // OK +} + +int dlt_buffer_pull(DltBuffer *buf,unsigned char *data, int max_size) +{ + return dlt_buffer_get(buf,data,max_size,1); +} + +int dlt_buffer_copy(DltBuffer *buf,unsigned char *data, int max_size) +{ + return dlt_buffer_get(buf,data,max_size,0); +} + +int dlt_buffer_remove(DltBuffer *buf) +{ + return dlt_buffer_get(buf,0,0,1); +} + +void dlt_buffer_info(DltBuffer *buf) +{ + char str[256]; + + snprintf(str,sizeof(str),"Buffer: Available size: %d\n",buf->size); + dlt_log(LOG_INFO, str); + snprintf(str,sizeof(str),"Buffer: Buffer full start address: %lX\n",(unsigned long)buf->shm); + dlt_log(LOG_INFO, str); + snprintf(str,sizeof(str),"Buffer: Buffer start address: %lX\n",(unsigned long)buf->mem); + dlt_log(LOG_INFO, str); + +} + +void dlt_buffer_status(DltBuffer *buf) +{ + int write, read, count; + char str[256]; + + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + + snprintf(str,sizeof(str),"Buffer: Write: %d\n",write); + dlt_log(LOG_INFO, str); + snprintf(str,sizeof(str),"Buffer: Read: %d\n",read); + dlt_log(LOG_INFO, str); + snprintf(str,sizeof(str),"Buffer: Count: %d\n",count); + dlt_log(LOG_INFO, str); +} + +int dlt_buffer_get_total_size(DltBuffer *buf) +{ + return buf->size; +} + +int dlt_buffer_get_used_size(DltBuffer *buf) +{ + int write, read, count; + + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + + if(count == 0) + return 0; + + if(write>read) + return (write - read); + + return (buf->size - read + write); +} + +int dlt_buffer_get_message_count(DltBuffer *buf) +{ + return ((int*)(buf->shm))[2]; +} + + + + + + + + + + + + + + + + + int dlt_ringbuffer_init(DltRingBuffer *dltbuf, uint32_t size) { diff --git a/src/shared/dlt_shm.c b/src/shared/dlt_shm.c index 59915ba..5f54f88 100644 --- a/src/shared/dlt_shm.c +++ b/src/shared/dlt_shm.c @@ -110,13 +110,11 @@ void dlt_shm_pv(int id,int operation) int dlt_shm_init_server(DltShm *buf,int key,int size) { struct shmid_ds shm_buf; char str[256]; + unsigned char *ptr; // 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) { @@ -132,7 +130,7 @@ int dlt_shm_init_server(DltShm *buf,int key,int size) { } // Now we attach the segment to our data space. - if ((buf->shm = shmat(buf->shmid, NULL, 0)) == (char *) -1) { + if ((ptr = shmat(buf->shmid, NULL, 0)) == (char *) -1) { dlt_log(LOG_ERR,"SHM: shmat"); return -1; /* ERROR */ } @@ -149,31 +147,19 @@ int dlt_shm_init_server(DltShm *buf,int key,int size) { 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); - - snprintf(str,sizeof(str),"SHM: Size %d\n",buf->size); - dlt_log(LOG_INFO, str); + // init buffer + dlt_buffer_init_static_server(&(buf->buffer),ptr,shm_buf.shm_segsz); return 0; /* OK */ } int dlt_shm_init_client(DltShm *buf,int key) { struct shmid_ds shm_buf; + unsigned char *ptr; // 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) { @@ -189,7 +175,7 @@ int dlt_shm_init_client(DltShm *buf,int key) { } // Now we attach the segment to our data space. - if ((buf->shm = shmat(buf->shmid, NULL, 0)) == (char *) -1) { + if ((ptr = shmat(buf->shmid, NULL, 0)) == (char *) -1) { dlt_log(LOG_ERR,"shmat"); return -1; /* ERROR */ } @@ -200,476 +186,90 @@ int dlt_shm_init_client(DltShm *buf,int key) { return -1; /* ERROR */ } - // Init pointers - buf->mem = (char*)(&(((int*)(buf->shm))[3])); - buf->size = shm_buf.shm_segsz - (buf->mem - buf->shm); + // init buffer + dlt_buffer_init_static_client(&(buf->buffer),ptr,shm_buf.shm_segsz); return 0; /* OK */ } void dlt_shm_info(DltShm *buf) { - char str[256]; - - snprintf(str,sizeof(str),"SHM: SHM id: %d\n",buf->shmid); - dlt_log(LOG_INFO, str); - snprintf(str,sizeof(str),"SHM: Available size: %d\n",buf->size); - dlt_log(LOG_INFO, str); - snprintf(str,sizeof(str),"SHM: SHM full start address: %lX\n",(unsigned long)buf->shm); - dlt_log(LOG_INFO, str); - snprintf(str,sizeof(str),"SHM: SHM start address: %lX\n",(unsigned long)buf->mem); - dlt_log(LOG_INFO, str); - + dlt_buffer_info(&(buf->buffer)); } void dlt_shm_status(DltShm *buf) { - int write, read, count; - char str[256]; - - write = ((int*)(buf->shm))[0]; - read = ((int*)(buf->shm))[1]; - count = ((int*)(buf->shm))[2]; - - snprintf(str,sizeof(str),"SHM: Write: %d\n",write); - dlt_log(LOG_INFO, str); - snprintf(str,sizeof(str),"SHM: Read: %d\n",read); - dlt_log(LOG_INFO, str); - snprintf(str,sizeof(str),"SHM: Count: %d\n",count); - dlt_log(LOG_INFO, str); + dlt_buffer_status(&(buf->buffer)); } int dlt_shm_get_total_size(DltShm *buf) { - return buf->size; + return dlt_buffer_get_total_size(&(buf->buffer)); } int dlt_shm_get_used_size(DltShm *buf) { - int write, read, count; + int ret; DLT_SHM_SEM_GET(buf->semid); - write = ((int*)(buf->shm))[0]; - read = ((int*)(buf->shm))[1]; - count = ((int*)(buf->shm))[2]; + ret = dlt_buffer_get_used_size(&(buf->buffer)); DLT_SHM_SEM_FREE(buf->semid); - if(count == 0) - return 0; - - if(write>read) - return (write - read); - - return (buf->size - read + write); + return ret; } int dlt_shm_get_message_count(DltShm *buf) { - return ((int*)(buf->shm))[2]; -} - -void dlt_shm_write_block(DltShm *buf,int *write, const unsigned char *data,unsigned int size) -{ - if((*write+size) <= buf->size) { - // write one block - memcpy(buf->mem+*write,data,size); - *write += size; - } - else { - // write two blocks - memcpy(buf->mem+*write, data, buf->size-*write); - memcpy(buf->mem, data+buf->size-*write, size-buf->size+*write); - *write += size-buf->size; - } + return dlt_buffer_get_message_count(&(buf->buffer)); } -void dlt_shm_read_block(DltShm *buf,int *read,unsigned char *data,unsigned int size) -{ - if((*read+size) <= buf->size) { - // read one block - memcpy(data,buf->mem+*read,size); - *read += size; - } - else { - // read two blocks - memcpy(data, buf->mem+*read, buf->size-*read); - memcpy(data+buf->size-*read, buf->mem, size-buf->size+*read); - *read += size-buf->size; - } -} 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 free_size; - int write, read; - DltShmBlockHead head; - - if(!buf->mem) { - // shm not initialised - dlt_log(LOG_ERR,"SHM: SHM not initialised\n"); - return -1; /* ERROR */ - } + int ret; - // get semaphore DLT_SHM_SEM_GET(buf->semid); - - // get current write pointer - write = ((int*)(buf->shm))[0]; - read = ((int*)(buf->shm))[1]; - - // check pointers - if((read>buf->size) || (write>buf->size)) - { - dlt_log(LOG_ERR,"SHM: Pointer out of range\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // calculate free size - if(read>write) - free_size = read - write; - else - free_size = buf->size - write + read; - - // check size - if(free_size < (sizeof(DltShmBlockHead)+size1+size2+size3)) { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: SHM is full\n"); - return -1; // ERROR - } - - // set header - strcpy(head.head,DLT_SHM_HEAD); - head.status = 2; - head.size = size1+size2+size3; - - // write data - dlt_shm_write_block(buf,&write,(unsigned char*)&head,sizeof(DltShmBlockHead)); - if(size1) dlt_shm_write_block(buf,&write,data1,size1); - if(size2) dlt_shm_write_block(buf,&write,data2,size2); - if(size3) dlt_shm_write_block(buf,&write,data3,size3); - - // update global shm pointers - ((int*)(buf->shm))[0] = write; // set new write pointer - ((int*)(buf->shm))[2] += 1; // increase counter - - // free semaphore + ret = dlt_buffer_push3(&(buf->buffer),data1,size1,data2,size2,data3,size3); DLT_SHM_SEM_FREE(buf->semid); - return 0; // OK + return ret; } int dlt_shm_pull(DltShm *buf,unsigned char *data, int max_size) { - int used_size; - int write, read, count; - char head_compare[] = DLT_SHM_HEAD; - DltShmBlockHead head; - - if(!buf->mem) { - // shm not initialised - dlt_log(LOG_ERR,"SHM: SHM not initialised\n"); - return -1; /* ERROR */ - } + int ret; - // 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]; - - // check pointers - if((read>buf->size) || (write>buf->size) || (count<0)) - { - dlt_log(LOG_ERR,"SHM: Pointer out of range\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // check if data is in there - if(count==0) { - DLT_SHM_SEM_FREE(buf->semid); - if(write!=read) - { - dlt_log(LOG_ERR,"SHM: SHM should be empty, but is not\n"); - dlt_shm_reset(buf); - } - return -1; // ERROR - } - - // calculate used size - if(write>read) - used_size = write - read; - else - used_size = buf->size - read + write; - - // first check size - if(used_size < (sizeof(DltShmBlockHead))) { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Size check 1 failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // read header - dlt_shm_read_block(buf,&read,(unsigned char*)&head,sizeof(DltShmBlockHead)); - - // check header - if(memcmp((unsigned char*)(head.head),head_compare,sizeof(head_compare))!=0) - { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Header head check failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - if(head.status != 2) - { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Header status check failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // second check size - if(used_size < (sizeof(DltShmBlockHead)+head.size)) { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Size check 2 failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // third check size - if(head.size > max_size) { - dlt_log(LOG_ERR,"SHM: Size check 3 failed\n"); - // nothing to do but data does not fit provided buffer - } - - // read data - dlt_shm_read_block(buf,&read,data,head.size); - - // update buffer pointers - ((int*)(buf->shm))[1] = read; // set new read pointer - ((int*)(buf->shm))[2] -= 1; // decrease counter - + ret = dlt_buffer_pull(&(buf->buffer),data,max_size); DLT_SHM_SEM_FREE(buf->semid); - return head.size; // OK + return ret; } int dlt_shm_copy(DltShm *buf,unsigned char *data, int max_size) { - int used_size; - int write, read, count; - char head_compare[] = DLT_SHM_HEAD; - DltShmBlockHead head; - - if(!buf->mem) { - // shm not initialised - dlt_log(LOG_ERR,"SHM: SHM not initialised\n"); - return -1; /* ERROR */ - } + int ret; - // 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]; - - // check pointers - if((read>buf->size) || (write>buf->size) || (count<0)) - { - dlt_log(LOG_ERR,"SHM: Pointer out of range\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // check if data is in there - if(count==0) { - DLT_SHM_SEM_FREE(buf->semid); - if(write!=read) - { - dlt_log(LOG_ERR,"SHM: SHM should be empty, but is not\n"); - dlt_shm_reset(buf); - } - return -1; // ERROR - } - - // calculate used size - if(write>read) - used_size = write - read; - else - used_size = buf->size - read + write; - - // first check size - if(used_size < (sizeof(DltShmBlockHead))) { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Size check 1 failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // read header - dlt_shm_read_block(buf,&read,(unsigned char*)&head,sizeof(DltShmBlockHead)); - - // check header - if(memcmp((unsigned char*)(head.head),head_compare,sizeof(head_compare))!=0) - { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Header head check failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - if(head.status != 2) - { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Header status check failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // second check size - if(used_size < (sizeof(DltShmBlockHead)+head.size)) { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Size check 2 failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // third check size - if(head.size > max_size) { - dlt_log(LOG_ERR,"SHM: Size check 3 failed\n"); - // nothing to do but data does not fit provided buffer - } - - // read data - dlt_shm_read_block(buf,&read,data,head.size); - - // do not update pointers - + ret = dlt_buffer_copy(&(buf->buffer),data,max_size); DLT_SHM_SEM_FREE(buf->semid); - return head.size; // OK + return ret; } int dlt_shm_remove(DltShm *buf) { - int used_size; - int write, read, count; - char head_compare[] = DLT_SHM_HEAD; - DltShmBlockHead head; - - if(!buf->mem) { - // shm not initialised - dlt_log(LOG_ERR,"SHM: SHM not initialised\n"); - return -1; /* ERROR */ - } + int ret; - // 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]; - - // check pointers - if((read>buf->size) || (write>buf->size) || (count<0)) - { - dlt_log(LOG_ERR,"SHM: Pointer out of range\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // check if data is in there - if(count==0) { - DLT_SHM_SEM_FREE(buf->semid); - if(write!=read) - { - dlt_log(LOG_ERR,"SHM: SHM should be empty, but is not\n"); - dlt_shm_reset(buf); - } - return -1; // ERROR - } - - // calculate used size - if(write>read) - used_size = write - read; - else - used_size = buf->size - read + write; - - // first check size - if(used_size < (sizeof(DltShmBlockHead))) { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Size check 1 failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // read header - dlt_shm_read_block(buf,&read,(unsigned char*)&head,sizeof(DltShmBlockHead)); - - // check header - if(memcmp((unsigned char*)(head.head),head_compare,sizeof(head_compare))!=0) - { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Header head check failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - if(head.status != 2) - { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Header status check failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // second check size - if(used_size < (sizeof(DltShmBlockHead)+head.size)) { - DLT_SHM_SEM_FREE(buf->semid); - dlt_log(LOG_ERR,"SHM: Size check 2 failed\n"); - dlt_shm_reset(buf); - return -1; // ERROR - } - - // do not copy data - - // update buffer pointers - if( (read+head.size) <= buf->size) - ((int*)(buf->shm))[1] = read+head.size; // set new read pointer - else - ((int*)(buf->shm))[1] = read+head.size-buf->size; // set new read pointer - ((int*)(buf->shm))[2] -= 1; // decrease counter - - DLT_SHM_SEM_FREE(buf->semid); - - return head.size; // OK -} - -int dlt_shm_reset(DltShm *buf) { - - dlt_log(LOG_ERR,"SHM: SHM reset triggered.\n"); - - /* reset pointers and counters */ - DLT_SHM_SEM_GET(buf->semid); - ((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 + ret = dlt_buffer_remove(&(buf->buffer)); DLT_SHM_SEM_FREE(buf->semid); - return 0; /* OK */ -} - -int dlt_shm_recover(DltShm *buf) { - - return -1; /* OK */ + return ret; } int dlt_shm_free_server(DltShm *buf) { - - if(!buf->shm) { - dlt_log(LOG_ERR,"SHM: Shared memory segment not attached\n"); - return -1; /* ERROR */ - } - if(shmdt(buf->shm)) { + if(shmdt(buf->buffer.shm)) { dlt_log(LOG_ERR,"SHM: shmdt"); return -1; /* ERROR */ } @@ -685,33 +285,23 @@ int dlt_shm_free_server(DltShm *buf) { } // Reset parameters - buf->shm = NULL; buf->shmid = 0; buf->semid = 0; - buf->size = 0; - buf->mem = 0; + + return dlt_buffer_free_static(&(buf->buffer)); - return 0; /* OK */ } int dlt_shm_free_client(DltShm *buf) { - if(!buf->shm) { - dlt_log(LOG_ERR,"SHM: Shared memory segment not attached\n"); - return -1; /* ERROR */ - } - - if(shmdt(buf->shm)) { + if(shmdt(buf->buffer.shm)) { dlt_log(LOG_ERR,"SHM: shmdt"); return -1; /* ERROR */ } // Reset parameters - buf->shm = NULL; buf->shmid = 0; buf->semid = 0; - buf->size = 0; - buf->mem = 0; - return 0; /* OK */ + return dlt_buffer_free_static(&(buf->buffer)); } -- cgit v1.2.1