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