Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (c) 2010, Texas Instruments Incorporated
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * *  Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  *
     12  * *  Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * *  Neither the name of Texas Instruments Incorporated nor the names of
     17  *    its contributors may be used to endorse or promote products derived
     18  *    from this software without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 /*
     34 *   @file  timm_osal_pipes.c
     35 *   This file contains methods that provides the functionality
     36 *   for creating/using Nucleus pipes.
     37 *
     38 *  @path \
     39 *
     40 */
     41 /* -------------------------------------------------------------------------- */
     42 /* =========================================================================
     43  *!
     44  *! Revision History
     45  *! ===================================
     46  *! 07-Nov-2008 Maiya ShreeHarsha: Linux specific changes
     47  *! 0.1: Created the first draft version, ksrini (at) ti.com
     48  * ========================================================================= */
     49 
     50 /******************************************************************************
     51 * Includes
     52 ******************************************************************************/
     53 
     54 #include "timm_osal_types.h"
     55 #include "timm_osal_error.h"
     56 #include "timm_osal_memory.h"
     57 #include "timm_osal_trace.h"
     58 
     59 #include <unistd.h>
     60 #include <stdio.h>
     61 #include <unistd.h>
     62 #include <errno.h>
     63 
     64 /**
     65 * TIMM_OSAL_PIPE structure define the OSAL pipe
     66 */
     67 typedef struct TIMM_OSAL_PIPE
     68 {
     69 	int pfd[2];
     70 	TIMM_OSAL_U32 pipeSize;
     71 	TIMM_OSAL_U32 messageSize;
     72 	TIMM_OSAL_U8 isFixedMessage;
     73 	int messageCount;
     74 	int totalBytesInPipe;
     75 } TIMM_OSAL_PIPE;
     76 
     77 
     78 /******************************************************************************
     79 * Function Prototypes
     80 ******************************************************************************/
     81 
     82 /* ========================================================================== */
     83 /**
     84 * @fn TIMM_OSAL_CreatePipe function
     85 *
     86 *
     87 */
     88 /* ========================================================================== */
     89 
     90 TIMM_OSAL_ERRORTYPE TIMM_OSAL_CreatePipe(TIMM_OSAL_PTR * pPipe,
     91     TIMM_OSAL_U32 pipeSize,
     92     TIMM_OSAL_U32 messageSize, TIMM_OSAL_U8 isFixedMessage)
     93 {
     94 	TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_UNKNOWN;
     95 	TIMM_OSAL_PIPE *pHandle = TIMM_OSAL_NULL;
     96 
     97 	pHandle =
     98 	    (TIMM_OSAL_PIPE *) TIMM_OSAL_Malloc(sizeof(TIMM_OSAL_PIPE), 0, 0,
     99 	    0);
    100 
    101 	if (TIMM_OSAL_NULL == pHandle)
    102 	{
    103 		bReturnStatus = TIMM_OSAL_ERR_ALLOC;
    104 		goto EXIT;
    105 	}
    106 	TIMM_OSAL_Memset(pHandle, 0x0, sizeof(TIMM_OSAL_PIPE));
    107 
    108 	pHandle->pfd[0] = -1;
    109 	pHandle->pfd[1] = -1;
    110 	if (SUCCESS != pipe(pHandle->pfd))
    111 	{
    112 		TIMM_OSAL_Error("Pipe failed: %s!!!", strerror(errno));
    113 		goto EXIT;
    114 	}
    115 
    116 	pHandle->pipeSize = pipeSize;
    117 	pHandle->messageSize = messageSize;
    118 	pHandle->isFixedMessage = isFixedMessage;
    119 	pHandle->messageCount = 0;
    120 	pHandle->totalBytesInPipe = 0;
    121 
    122 	*pPipe = (TIMM_OSAL_PTR) pHandle;
    123 
    124 	bReturnStatus = TIMM_OSAL_ERR_NONE;
    125 
    126 
    127 	return bReturnStatus;
    128 EXIT:
    129 	TIMM_OSAL_Free(pHandle);
    130 	return bReturnStatus;
    131 }
    132 
    133 
    134 
    135 /* ========================================================================== */
    136 /**
    137 * @fn TIMM_OSAL_DeletePipe function
    138 *
    139 *
    140 */
    141 /* ========================================================================== */
    142 
    143 TIMM_OSAL_ERRORTYPE TIMM_OSAL_DeletePipe(TIMM_OSAL_PTR pPipe)
    144 {
    145 	TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_NONE;
    146 
    147 	TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe;
    148 
    149 	if (TIMM_OSAL_NULL == pHandle)
    150 	{
    151 		bReturnStatus = TIMM_OSAL_ERR_PARAMETER;
    152 		goto EXIT;
    153 	}
    154 
    155 	if (SUCCESS != close(pHandle->pfd[0]))
    156 	{
    157 		TIMM_OSAL_Error("Delete_Pipe Read fd failed!!!");
    158 		bReturnStatus = TIMM_OSAL_ERR_UNKNOWN;
    159 	}
    160 	if (SUCCESS != close(pHandle->pfd[1]))
    161 	{
    162 		TIMM_OSAL_Error("Delete_Pipe Write fd failed!!!");
    163 		bReturnStatus = TIMM_OSAL_ERR_UNKNOWN;
    164 	}
    165 
    166 	TIMM_OSAL_Free(pHandle);
    167 EXIT:
    168 	return bReturnStatus;
    169 }
    170 
    171 
    172 
    173 /* ========================================================================== */
    174 /**
    175 * @fn TIMM_OSAL_WriteToPipe function
    176 *
    177 *
    178 */
    179 /* ========================================================================== */
    180 
    181 TIMM_OSAL_ERRORTYPE TIMM_OSAL_WriteToPipe(TIMM_OSAL_PTR pPipe,
    182     void *pMessage, TIMM_OSAL_U32 size, TIMM_OSAL_S32 timeout)
    183 {
    184 	TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_UNKNOWN;
    185 	TIMM_OSAL_U32 lSizeWritten = -1;
    186 
    187 	TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe;
    188 
    189 	if (size == 0)
    190 	{
    191 		TIMM_OSAL_Error("0 size!!!");
    192 		bReturnStatus = TIMM_OSAL_ERR_PARAMETER;
    193 		goto EXIT;
    194 	}
    195 	lSizeWritten = write(pHandle->pfd[1], pMessage, size);
    196 
    197 	if (lSizeWritten != size)
    198 	{
    199 		TIMM_OSAL_Error("Write of pipe failed!!!");
    200 		bReturnStatus = TIMM_OSAL_ERR_PARAMETER;
    201 		goto EXIT;
    202 	}
    203 
    204 	/*Update message count and size */
    205 	pHandle->messageCount++;
    206 	pHandle->totalBytesInPipe += size;
    207 
    208 	bReturnStatus = TIMM_OSAL_ERR_NONE;
    209 
    210       EXIT:
    211 	return bReturnStatus;
    212 }
    213 
    214 
    215 
    216 /* ========================================================================== */
    217 /**
    218 * @fn TIMM_OSAL_WriteToFrontOfPipe function
    219 *
    220 *
    221 */
    222 /* ========================================================================== */
    223 
    224 TIMM_OSAL_ERRORTYPE TIMM_OSAL_WriteToFrontOfPipe(TIMM_OSAL_PTR pPipe,
    225     void *pMessage, TIMM_OSAL_U32 size, TIMM_OSAL_S32 timeout)
    226 {
    227 
    228 	TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_UNKNOWN;
    229 	TIMM_OSAL_U32 lSizeWritten = -1;
    230 	TIMM_OSAL_U32 lSizeRead = -1;
    231 	TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe;
    232 	TIMM_OSAL_U8 *tempPtr = NULL;
    233 
    234 
    235 	/*First write to this pipe */
    236 	if (size == 0)
    237 	{
    238 		bReturnStatus = TIMM_OSAL_ERR_PARAMETER;
    239 		goto EXIT;
    240 	}
    241 
    242 	lSizeWritten = write(pHandle->pfd[1], pMessage, size);
    243 
    244 	if (lSizeWritten != size)
    245 	{
    246 		bReturnStatus = TIMM_OSAL_ERR_PARAMETER;
    247 		goto EXIT;
    248 	}
    249 
    250 	/*Update number of messages */
    251 	pHandle->messageCount++;
    252 
    253 
    254 	if (pHandle->messageCount > 1)
    255 	{
    256 		/*First allocate memory */
    257 		tempPtr =
    258 		    (TIMM_OSAL_U8 *) TIMM_OSAL_Malloc(pHandle->
    259 		    totalBytesInPipe, 0, 0, 0);
    260 
    261 		if (tempPtr == NULL)
    262 		{
    263 			bReturnStatus = TIMM_OSAL_ERR_PARAMETER;
    264 			goto EXIT;
    265 		}
    266 
    267 		/*Read out of pipe */
    268 		lSizeRead =
    269 		    read(pHandle->pfd[0], tempPtr, pHandle->totalBytesInPipe);
    270 
    271 		/*Write back to pipe */
    272 		lSizeWritten =
    273 		    write(pHandle->pfd[1], tempPtr,
    274 		    pHandle->totalBytesInPipe);
    275 
    276 		if (lSizeWritten != size)
    277 		{
    278 			bReturnStatus = TIMM_OSAL_ERR_PARAMETER;
    279 			goto EXIT;
    280 		}
    281 
    282 		/*Update Total bytes in pipe */
    283 		pHandle->totalBytesInPipe += size;
    284 	}
    285 
    286 
    287       EXIT:
    288 	TIMM_OSAL_Free(tempPtr);
    289 
    290 	return bReturnStatus;
    291 
    292 }
    293 
    294 
    295 
    296 /* ========================================================================== */
    297 /**
    298 * @fn TIMM_OSAL_ReadFromPipe function
    299 *
    300 *
    301 */
    302 /* ========================================================================== */
    303 
    304 TIMM_OSAL_ERRORTYPE TIMM_OSAL_ReadFromPipe(TIMM_OSAL_PTR pPipe,
    305     void *pMessage,
    306     TIMM_OSAL_U32 size, TIMM_OSAL_U32 * actualSize, TIMM_OSAL_S32 timeout)
    307 {
    308 	TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_UNKNOWN;
    309 	TIMM_OSAL_U32 lSizeRead = -1;
    310 	TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe;
    311 
    312 	if (size == 0)
    313 	{
    314 		TIMM_OSAL_Error("nRead size has error!!!");
    315 		bReturnStatus = TIMM_OSAL_ERR_PARAMETER;
    316 		goto EXIT;
    317 	}
    318 	if ((pHandle->messageCount == 0) && (timeout == TIMM_OSAL_NO_SUSPEND))
    319 	{
    320 		/*If timeout is 0 and pipe is empty, return error */
    321 		TIMM_OSAL_Error("Pipe is empty!!!");
    322 		bReturnStatus = TIMM_OSAL_ERR_PIPE_EMPTY;
    323 		goto EXIT;
    324 	}
    325 	if ((timeout !=TIMM_OSAL_NO_SUSPEND) &&
    326 	    (timeout != (TIMM_OSAL_S32)TIMM_OSAL_SUSPEND))
    327 	{
    328 		TIMM_OSAL_Warning("Only infinite or no timeouts \
    329 			supported. Going to read with infinite timeout now");
    330 	}
    331 	/*read blocks infinitely until message is available */
    332 	*actualSize = lSizeRead = read(pHandle->pfd[0], pMessage, size);
    333 	if (0 == lSizeRead)
    334 	{
    335 		TIMM_OSAL_Error("EOF reached or no data in pipe!!!");
    336 		bReturnStatus = TIMM_OSAL_ERR_PARAMETER;
    337 		goto EXIT;
    338 	}
    339 
    340 	bReturnStatus = TIMM_OSAL_ERR_NONE;
    341 
    342 	pHandle->messageCount--;
    343 	pHandle->totalBytesInPipe -= size;
    344 
    345       EXIT:
    346 	return bReturnStatus;
    347 
    348 }
    349 
    350 
    351 
    352 /* ========================================================================== */
    353 /**
    354 * @fn TIMM_OSAL_ClearPipe function
    355 *
    356 *
    357 */
    358 /* ========================================================================== */
    359 
    360 TIMM_OSAL_ERRORTYPE TIMM_OSAL_ClearPipe(TIMM_OSAL_PTR pPipe)
    361 {
    362 	TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR;
    363 
    364 	TIMM_OSAL_Warning("This function is currently not implemented");
    365 
    366 	return bReturnStatus;
    367 }
    368 
    369 
    370 
    371 /* ========================================================================== */
    372 /**
    373 * @fn TIMM_OSAL_IsPipeReady function
    374 *
    375 *
    376 */
    377 /* ========================================================================== */
    378 
    379 TIMM_OSAL_ERRORTYPE TIMM_OSAL_IsPipeReady(TIMM_OSAL_PTR pPipe)
    380 {
    381 	TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR;
    382 	TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe;
    383 
    384 	if (pHandle->messageCount <= 0)
    385 	{
    386 		bReturnStatus = TIMM_OSAL_ERR_NOT_READY;
    387 	} else
    388 	{
    389 		bReturnStatus = TIMM_OSAL_ERR_NONE;
    390 	}
    391 
    392 	return bReturnStatus;
    393 
    394 }
    395 
    396 
    397 
    398 /* ========================================================================== */
    399 /**
    400 * @fn TIMM_OSAL_GetPipeReadyMessageCount function
    401 *
    402 *
    403 */
    404 /* ========================================================================== */
    405 
    406 TIMM_OSAL_ERRORTYPE TIMM_OSAL_GetPipeReadyMessageCount(TIMM_OSAL_PTR pPipe,
    407     TIMM_OSAL_U32 * count)
    408 {
    409 	TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_NONE;
    410 	TIMM_OSAL_PIPE *pHandle = (TIMM_OSAL_PIPE *) pPipe;
    411 
    412 	*count = pHandle->messageCount;
    413 	return bReturnStatus;
    414 
    415 }
    416