/* * Copyright (c) 2010, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * @file timm_osal_pipes.c * This file contains methods that provides the functionality * for creating/using Nucleus pipes. * * @path \ * */ /* -------------------------------------------------------------------------- */ /* ========================================================================= *! *! Revision History *! =================================== *! 07-Nov-2008 Maiya ShreeHarsha: Linux specific changes *! 0.1: Created the first draft version, ksrini@ti.com * ========================================================================= */ /****************************************************************************** * Includes ******************************************************************************/ #include "timm_osal_types.h" #include "timm_osal_error.h" #include "timm_osal_memory.h" #include "timm_osal_trace.h" #include <unistd.h> #include <stdio.h> #include <unistd.h> #include <errno.h> /** * TIMM_OSAL_PIPE structure define the OSAL pipe */ typedef struct TIMM_OSAL_PIPE { int pfd[2]; TIMM_OSAL_U32 pipeSize; TIMM_OSAL_U32 messageSize; TIMM_OSAL_U8 isFixedMessage; int messageCount; int totalBytesInPipe; } TIMM_OSAL_PIPE; /****************************************************************************** * Function Prototypes ******************************************************************************/ /* ========================================================================== */ /** * @fn TIMM_OSAL_CreatePipe function * * */ /* ========================================================================== */ TIMM_OSAL_ERRORTYPE TIMM_OSAL_CreatePipe(TIMM_OSAL_PTR * pPipe, TIMM_OSAL_U32 pipeSize, TIMM_OSAL_U32 messageSize, TIMM_OSAL_U8 isFixedMessage) { TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_UNKNOWN; TIMM_OSAL_PIPE *pHandle = TIMM_OSAL_NULL; pHandle = (TIMM_OSAL_PIPE *) TIMM_OSAL_Malloc(sizeof(TIMM_OSAL_PIPE), 0, 0, 0); if (TIMM_OSAL_NULL == pHandle) { bReturnStatus = TIMM_OSAL_ERR_ALLOC; goto EXIT; } TIMM_OSAL_Memset(pHandle, 0x0, sizeof(TIMM_OSAL_PIPE)); pHandle->pfd[0] = -1; pHandle->pfd[1] = -1; if (SUCCESS != pipe(pHandle->pfd)) { TIMM_OSAL_Error("Pipe failed: %s!!!", strerror(errno)); goto EXIT; } pHandle->pipeSize = pipeSize; pHandle->messageSize = messageSize; pHandle->isFixedMessage = isFixedMessage; pHandle->messageCount = 0; pHandle->totalBytesInPipe = 0; *pPipe = (TIMM_OSAL_PTR) pHandle; bReturnStatus = TIMM_OSAL_ERR_NONE; return bReturnStatus; EXIT: TIMM_OSAL_Free(pHandle); return bReturnStatus; } /* ========================================================================== */ /** * @fn TIMM_OSAL_DeletePipe function * * */ /* ========================================================================== */ TIMM_OSAL_ERRORTYPE TIMM_OSAL_DeletePipe(TIMM_OSAL_PTR pPipe) { TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_NONE; TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe; if (TIMM_OSAL_NULL == pHandle) { bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } if (SUCCESS != close(pHandle->pfd[0])) { TIMM_OSAL_Error("Delete_Pipe Read fd failed!!!"); bReturnStatus = TIMM_OSAL_ERR_UNKNOWN; } if (SUCCESS != close(pHandle->pfd[1])) { TIMM_OSAL_Error("Delete_Pipe Write fd failed!!!"); bReturnStatus = TIMM_OSAL_ERR_UNKNOWN; } TIMM_OSAL_Free(pHandle); EXIT: return bReturnStatus; } /* ========================================================================== */ /** * @fn TIMM_OSAL_WriteToPipe function * * */ /* ========================================================================== */ TIMM_OSAL_ERRORTYPE TIMM_OSAL_WriteToPipe(TIMM_OSAL_PTR pPipe, void *pMessage, TIMM_OSAL_U32 size, TIMM_OSAL_S32 timeout) { TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_UNKNOWN; TIMM_OSAL_U32 lSizeWritten = -1; TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe; if (size == 0) { TIMM_OSAL_Error("0 size!!!"); bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } lSizeWritten = write(pHandle->pfd[1], pMessage, size); if (lSizeWritten != size) { TIMM_OSAL_Error("Write of pipe failed!!!"); bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } /*Update message count and size */ pHandle->messageCount++; pHandle->totalBytesInPipe += size; bReturnStatus = TIMM_OSAL_ERR_NONE; EXIT: return bReturnStatus; } /* ========================================================================== */ /** * @fn TIMM_OSAL_WriteToFrontOfPipe function * * */ /* ========================================================================== */ TIMM_OSAL_ERRORTYPE TIMM_OSAL_WriteToFrontOfPipe(TIMM_OSAL_PTR pPipe, void *pMessage, TIMM_OSAL_U32 size, TIMM_OSAL_S32 timeout) { TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_UNKNOWN; TIMM_OSAL_U32 lSizeWritten = -1; TIMM_OSAL_U32 lSizeRead = -1; TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe; TIMM_OSAL_U8 *tempPtr = NULL; /*First write to this pipe */ if (size == 0) { bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } lSizeWritten = write(pHandle->pfd[1], pMessage, size); if (lSizeWritten != size) { bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } /*Update number of messages */ pHandle->messageCount++; if (pHandle->messageCount > 1) { /*First allocate memory */ tempPtr = (TIMM_OSAL_U8 *) TIMM_OSAL_Malloc(pHandle-> totalBytesInPipe, 0, 0, 0); if (tempPtr == NULL) { bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } /*Read out of pipe */ lSizeRead = read(pHandle->pfd[0], tempPtr, pHandle->totalBytesInPipe); /*Write back to pipe */ lSizeWritten = write(pHandle->pfd[1], tempPtr, pHandle->totalBytesInPipe); if (lSizeWritten != size) { bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } /*Update Total bytes in pipe */ pHandle->totalBytesInPipe += size; } EXIT: TIMM_OSAL_Free(tempPtr); return bReturnStatus; } /* ========================================================================== */ /** * @fn TIMM_OSAL_ReadFromPipe function * * */ /* ========================================================================== */ TIMM_OSAL_ERRORTYPE TIMM_OSAL_ReadFromPipe(TIMM_OSAL_PTR pPipe, void *pMessage, TIMM_OSAL_U32 size, TIMM_OSAL_U32 * actualSize, TIMM_OSAL_S32 timeout) { TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_UNKNOWN; TIMM_OSAL_U32 lSizeRead = -1; TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe; if (size == 0) { TIMM_OSAL_Error("nRead size has error!!!"); bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } if ((pHandle->messageCount == 0) && (timeout == TIMM_OSAL_NO_SUSPEND)) { /*If timeout is 0 and pipe is empty, return error */ TIMM_OSAL_Error("Pipe is empty!!!"); bReturnStatus = TIMM_OSAL_ERR_PIPE_EMPTY; goto EXIT; } if ((timeout !=TIMM_OSAL_NO_SUSPEND) && (timeout != (TIMM_OSAL_S32)TIMM_OSAL_SUSPEND)) { TIMM_OSAL_Warning("Only infinite or no timeouts \ supported. Going to read with infinite timeout now"); } /*read blocks infinitely until message is available */ *actualSize = lSizeRead = read(pHandle->pfd[0], pMessage, size); if (0 == lSizeRead) { TIMM_OSAL_Error("EOF reached or no data in pipe!!!"); bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } bReturnStatus = TIMM_OSAL_ERR_NONE; pHandle->messageCount--; pHandle->totalBytesInPipe -= size; EXIT: return bReturnStatus; } /* ========================================================================== */ /** * @fn TIMM_OSAL_ClearPipe function * * */ /* ========================================================================== */ TIMM_OSAL_ERRORTYPE TIMM_OSAL_ClearPipe(TIMM_OSAL_PTR pPipe) { TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR; TIMM_OSAL_Warning("This function is currently not implemented"); return bReturnStatus; } /* ========================================================================== */ /** * @fn TIMM_OSAL_IsPipeReady function * * */ /* ========================================================================== */ TIMM_OSAL_ERRORTYPE TIMM_OSAL_IsPipeReady(TIMM_OSAL_PTR pPipe) { TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR; TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe; if (pHandle->messageCount <= 0) { bReturnStatus = TIMM_OSAL_ERR_NOT_READY; } else { bReturnStatus = TIMM_OSAL_ERR_NONE; } return bReturnStatus; } /* ========================================================================== */ /** * @fn TIMM_OSAL_GetPipeReadyMessageCount function * * */ /* ========================================================================== */ TIMM_OSAL_ERRORTYPE TIMM_OSAL_GetPipeReadyMessageCount(TIMM_OSAL_PTR pPipe, TIMM_OSAL_U32 * count) { TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_NONE; TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe; *count = pHandle->messageCount; return bReturnStatus; }