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@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
TIMM_OSAL_CreatePipe(TIMM_OSAL_PTR * pPipe,TIMM_OSAL_U32 pipeSize,TIMM_OSAL_U32 messageSize,TIMM_OSAL_U8 isFixedMessage)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
TIMM_OSAL_DeletePipe(TIMM_OSAL_PTR pPipe)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
TIMM_OSAL_WriteToPipe(TIMM_OSAL_PTR pPipe,void * pMessage,TIMM_OSAL_U32 size,TIMM_OSAL_S32 timeout)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
TIMM_OSAL_WriteToFrontOfPipe(TIMM_OSAL_PTR pPipe,void * pMessage,TIMM_OSAL_U32 size,TIMM_OSAL_S32 timeout)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
TIMM_OSAL_ReadFromPipe(TIMM_OSAL_PTR pPipe,void * pMessage,TIMM_OSAL_U32 size,TIMM_OSAL_U32 * actualSize,TIMM_OSAL_S32 timeout)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
TIMM_OSAL_ClearPipe(TIMM_OSAL_PTR pPipe)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
TIMM_OSAL_IsPipeReady(TIMM_OSAL_PTR pPipe)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
TIMM_OSAL_GetPipeReadyMessageCount(TIMM_OSAL_PTR pPipe,TIMM_OSAL_U32 * count)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