diff options
Diffstat (limited to 'source/LCM/Buffers.cpp')
-rw-r--r-- | source/LCM/Buffers.cpp | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/source/LCM/Buffers.cpp b/source/LCM/Buffers.cpp new file mode 100644 index 0000000..6e513bf --- /dev/null +++ b/source/LCM/Buffers.cpp @@ -0,0 +1,264 @@ +/******************************************************************************* + * Copyright (C) ST-Ericsson SA 2011 + * License terms: 3-clause BSD license + ******************************************************************************/ + +/* + * \addtogroup ldr_communication_buffer + * @{ + */ + +/*********************************************************************** + * Includes + **********************************************************************/ +#include "Buffers.h" +#include "lcdriver_error_codes.h" +#include "t_r15_network_layer.h" +#include "Error.h" +#include <cstdlib> +using namespace std; + +vector<TBulkFile *> Buffers::m_BulkFiles; +CCriticalSectionObject Buffers::csBulkFiles; +const uint32 Buffers::MAX_BUFFERS_COUNT = 32; + +#define MAX_BUFFER_SIZE BULK_BUFFER_SIZE + +TBulkVector::TBulkVector(): + HeaderBuffer_p(NULL), + Data_p(NULL), + Offset(0), + Length(0), + ChunkSize(0) +{ +} + +TBulkVector::~TBulkVector() +{ + delete[] HeaderBuffer_p; +} + +TBulkFile::TBulkFile(): refCount(1) +{ + iAllSessionsCompleted = 0; + pMemMappedFile = 0; +} + +TBulkFile::~TBulkFile() +{ + delete pMemMappedFile; + + for (vector<TBulkVector *>::iterator i = bulkVectors.begin(); i != bulkVectors.end(); ++i) { + delete *i; + } +} + +Buffers::Buffers(): + buffersCount_(0), + logger_(0) +{ + m_BulkFile = 0; +} + +Buffers::~Buffers() +{ + Deinit(); +} + +/*********************************************************************** + * Definition of internal functions + **********************************************************************/ +ErrorCode_e Buffers::Init() +{ + return E_SUCCESS; +} + +void *Buffers::Allocate(int Size) +{ + void *Buffer_p = 0; + + if (buffersCount_ < MAX_BUFFERS_COUNT) { + Buffer_p = static_cast<uint8 *>(new uint8[Size]); + ++buffersCount_; +#ifdef _BUFFERDEBUG + PrintF("Buffers: Allocate - Buffer 0x%p", Buffer_p); +#endif + } else { +#ifdef _BUFFERDEBUG + PrintF("Buffers: Allocate - Failed, Count %u", (void *)buffersCount_); +#endif + } + + return Buffer_p; +} + +ErrorCode_e Buffers::Release(void *Buffer_p, int Size) +{ +#ifdef _BUFFERDEBUG + PrintF("Buffers: Release - Buffer 0x%p", Buffer_p); +#endif + delete[] static_cast<uint8 *>(Buffer_p); + --buffersCount_; + return E_SUCCESS; +} + +uint32 Buffers::Available(int BufferSize) +{ +#ifdef _BUFFERDEBUG + PrintF("Buffers: Available - Available %d", (void *)(MAX_BUFFERS_COUNT - buffersCount_)); +#endif + return MAX_BUFFERS_COUNT - buffersCount_; +} + +void Buffers::Deinit() +{ +#ifdef _BUFFERDEBUG + + if (buffersCount_) { + PrintF("Buffers: Deinit - Buffers still allocated %d", (void *)buffersCount_); + } + +#endif +} + +int Buffers::AllocateBulkFile(string strFile) +{ + CLockCS CsLock(csBulkFiles); + + for (vector<TBulkFile *>::iterator i = m_BulkFiles.begin(); i != m_BulkFiles.end(); ++i) { + if (strFile.compare((*i)->strFileName) == 0) { + m_BulkFile = *i; + ++m_BulkFile->refCount; + return E_SUCCESS; + } + } + + TBulkFile *newFile = new TBulkFile; + newFile->strFileName = strFile; + + MemMappedFile *file = new MemMappedFile; +#ifdef _BUFFERDEBUG + PrintF("Buffers: LoadFileData %s", (void *)strFile.c_str()); +#endif + int iReturn = file->LoadFileData(strFile.c_str()); + + if (iReturn) { + delete newFile; + delete file; + return iReturn; + } + + newFile->pMemMappedFile = file; + + m_BulkFiles.push_back(newFile); + m_BulkFile = newFile; + + return E_SUCCESS; +} + +uint64 Buffers::GetBulkFileLength() +{ + return m_BulkFile->pMemMappedFile->GetFileSize(); +} + +int Buffers::AllocateBulkVector(TL_BulkVectorList_t *BulkVector_p, uint32 iChunkSize, uint64 lOffset, uint32 iLength) +{ + CLockCS CsLock(m_BulkFile->csBulkVectors); + int ReturnValue = E_SUCCESS; + + int HeaderBufferSize = HEADER_OFFSET_IN_BUFFER + ALIGNED_HEADER_LENGTH + ALIGNED_BULK_EXTENDED_HEADER_LENGTH; + int CurrentHeaderBufferSize = (BulkVector_p->Buffers) * HeaderBufferSize; + + TBulkVector *currentVector = NULL; + + //Check that flash buffers have been initialized. + VERIFY(0 != m_BulkFile, BUFFER_BULK_FILE_NOT_ALOCATED); + + currentVector = new TBulkVector(); + currentVector->HeaderBuffer_p = new uint8[CurrentHeaderBufferSize]; + currentVector->Data_p = m_BulkFile->pMemMappedFile->AllocateFileData(lOffset, iLength); + currentVector->Offset = lOffset; + currentVector->Length = iLength; + currentVector->ChunkSize = iChunkSize; + m_BulkFile->bulkVectors.push_back(currentVector); + VERIFY(0 != currentVector->Data_p, m_BulkFile->pMemMappedFile->GetError()); + +#ifdef _BUFFERDEBUG + PrintF("Buffers: AllocateFlashBuffers - Created new bulk vector 0x%p", (void *)currentVector); +#endif + + for (uint32 i = 0; i < BulkVector_p->Buffers; i++) { + uint8 *ChunkHeader_p = currentVector->HeaderBuffer_p + i * HeaderBufferSize; + uint8 *ChunkPayload_p = currentVector->Data_p + i * iChunkSize; + + PacketMeta_t *Packet_p = BulkVector_p->Entries[i].Buffer_p; + Packet_p->Buffer_p = ChunkHeader_p; + Packet_p->ExtendedHeader_p = ChunkHeader_p + (uint64)Packet_p->ExtendedHeader_p; + Packet_p->Payload_p = ChunkPayload_p; + + BulkVector_p->Entries[i].Payload_p = ChunkPayload_p; + } + +ErrorExit: + + if ((0 != currentVector) && (0 == currentVector->Data_p)) { + m_BulkFile->bulkVectors.pop_back(); + delete currentVector; + } + + return ReturnValue; +} + +void Buffers::ReleaseBulkVector(TL_BulkVectorList_t *BulkVector_p) +{ + CLockCS CsLock(m_BulkFile->csBulkVectors); + + for (vector<TBulkVector *>::iterator i = m_BulkFile->bulkVectors.begin(); i != m_BulkFile->bulkVectors.end(); ++i) { + if (BulkVector_p->Offset == (*i)->Offset && + BulkVector_p->Length == (*i)->Length && + BulkVector_p->ChunkSize == (*i)->ChunkSize) { + m_BulkFile->pMemMappedFile->ReleaseFileData((*i)->Data_p, (*i)->Offset, (*i)->Length); + delete *i; + m_BulkFile->bulkVectors.erase(i); + break; + } + } +} + +void Buffers::ReleaseAllBulkFiles() +{ + CLockCS CsLock(csBulkFiles); + + for (vector<TBulkFile *>::iterator i = m_BulkFiles.begin(); i != m_BulkFiles.end(); ++i) { + delete *i; + } + + m_BulkFiles.clear(); +} + +void Buffers::ReleaseBulkFile() +{ + CLockCS CsLock(csBulkFiles); + + if (0 == m_BulkFile || --m_BulkFile->refCount > 0) { + return; + } + + // remove bulk file from static list + for (vector<TBulkFile *>::iterator i = m_BulkFiles.begin(); i != m_BulkFiles.end(); ++i) { + if (m_BulkFile == *i) { + m_BulkFiles.erase(i); + break; + } + } + + delete m_BulkFile; + m_BulkFile = 0; +} + +void Buffers::PrintF(const char *text, void *pVoid) +{ + if (NULL != logger_) { + logger_->log(text, pVoid); + } +} |