~ubuntu-branches/ubuntu/lucid/skyeye/lucid

« back to all changes in this revision

Viewing changes to device/uart/skyeye_uart_pipe.c

  • Committer: Bazaar Package Importer
  • Author(s): Yu Guanghui
  • Date: 2007-08-07 13:25:49 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20070807132549-96159k1obat1fxr0
Tags: 1.2.3-1
* New upstream release
* Added NO_BFD=1, don't require libbfd now. (Closes:Bug#423933) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#endif
30
30
 
31
31
#if (defined(__MINGW32__) || (defined(__BEOS__) && B_BEOS_VERSION < 0x510))
32
 
#define SKYEYE_UART_PIPE_SUPPORTED 0
 
32
#define SKYEYE_UART_PIPE_POSIX_SUPPORTED 0
33
33
#else
34
 
#define SKYEYE_UART_PIPE_SUPPORTED 1
 
34
#define SKYEYE_UART_PIPE_POSIX_SUPPORTED 1
35
35
#endif
36
36
 
37
 
#if SKYEYE_UART_PIPE_SUPPORTED
 
37
#if SKYEYE_UART_PIPE_POSIX_SUPPORTED
38
38
 
39
39
#include <sys/select.h>
40
40
#include <unistd.h>
57
57
        {
58
58
                ret = -1;
59
59
        }
60
 
        else if(uart_dev->desc_out[0] == '\0')
 
60
        else if(uart_dev->desc_out[0] == '\0' || strcmp(uart_dev->desc_in, uart_dev->desc_out) == 0)
61
61
        {
62
62
                dev->fd_out = -1;
63
63
                if((dev->fd_in = open(uart_dev->desc_in, O_RDWR)) == -1)
64
64
                {
65
65
                        ret = -1;
66
 
                        fprintf(stderr, "Error when open device %s", uart_dev->desc_in);
 
66
                        fprintf(stderr, "Error when open device \"%s\" !!!", uart_dev->desc_in);
67
67
                }
68
68
        }
69
69
        else
71
71
                if((dev->fd_in = open(uart_dev->desc_in, O_RDONLY)) == -1)
72
72
                {
73
73
                        ret = -1;
74
 
                        fprintf(stderr, "Error when open device %s", uart_dev->desc_in);
 
74
                        fprintf(stderr, "Error when open device \"%s\" for input !!!", uart_dev->desc_in);
75
75
                }
76
76
                else if((dev->fd_out = open(uart_dev->desc_out, O_WRONLY)) == -1)
77
77
                {
78
78
                        close(dev->fd_in);
79
79
                        ret = -1;
80
 
                        fprintf(stderr, "Error when open device %s", uart_dev->desc_out);
 
80
                        fprintf(stderr, "Error when open device \"%s\" for output !!!", uart_dev->desc_out);
81
81
                }
82
82
        }
83
83
 
129
129
        return write((dev->fd_out != -1 ? dev->fd_out : dev->fd_in), buf, count);
130
130
}
131
131
 
132
 
#else /* !SKYEYE_UART_PIPE_SUPPORTED */
 
132
#else /* !SKYEYE_UART_PIPE_POSIX_SUPPORTED */
 
133
 
 
134
#if (defined(__MINGW32__) || defined(__CYGWIN__))
 
135
 
 
136
#undef WORD
 
137
#include <windows.h>
 
138
 
 
139
#define PIPE_BUFFER_SIZE        1
 
140
 
 
141
typedef struct uart_pipe_win32 {
 
142
        HANDLE fHandle;
 
143
        HANDLE fHandleOut;
 
144
        HANDLE fEvent;
 
145
        HANDLE fEventOut;
 
146
 
 
147
        unsigned char fBuffer[PIPE_BUFFER_SIZE];
 
148
        DWORD fBufferLen;
 
149
 
 
150
        CRITICAL_SECTION fLocker;
 
151
        BOOL fReading;
 
152
        OVERLAPPED fOverlapped;
 
153
        OVERLAPPED fOverlappedOut;
 
154
 
 
155
        DWORD fWritten;
 
156
} uart_pipe_win32;
 
157
 
 
158
 
 
159
int uart_pipe_open(struct uart_device *uart_dev)
 
160
{
 
161
        uart_pipe_win32 *dev = malloc(sizeof(uart_pipe_win32));
 
162
        int ret = 0;
 
163
 
 
164
        if(dev == NULL) return -1;
 
165
        bzero(dev, sizeof(uart_pipe_win32));
 
166
 
 
167
        if(strncmp(&uart_dev->desc_in[0], "/dev/ttyS", 9) == 0 &&
 
168
           uart_dev->desc_in[9] >= '0' && uart_dev->desc_in[9] <= '8' &&
 
169
           uart_dev->desc_in[10] == 0) {
 
170
                memcpy(&uart_dev->desc_in[0], "COM\0", 5);
 
171
                uart_dev->desc_in[3] = uart_dev->desc_in[9] + 1;
 
172
        }
 
173
 
 
174
        if(strncmp(&uart_dev->desc_out[0], "/dev/ttyS", 9) == 0 &&
 
175
           uart_dev->desc_out[9] >= '0' && uart_dev->desc_out[9] <= '8' &&
 
176
           uart_dev->desc_out[10] == 0) {
 
177
                memcpy(&uart_dev->desc_out[0], "COM\0", 5);
 
178
                uart_dev->desc_out[3] = uart_dev->desc_out[9] + 1;
 
179
        }
 
180
 
 
181
        if(uart_dev->desc_in[0] == '\0')
 
182
        {
 
183
                ret = -1;
 
184
        }
 
185
        else if(uart_dev->desc_out[0] == '\0' || strcmp(uart_dev->desc_in, uart_dev->desc_out) == 0)
 
186
        {
 
187
                if((dev->fHandle = CreateFile(uart_dev->desc_in,
 
188
                                              GENERIC_READ | GENERIC_WRITE,
 
189
                                              FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
 
190
                                              OPEN_EXISTING,
 
191
                                              FILE_FLAG_OVERLAPPED,
 
192
                                              NULL)) == INVALID_HANDLE_VALUE)
 
193
                {
 
194
                        ret = -1;
 
195
                        fprintf(stderr, "Error when open device \"%s\" !!!\n", uart_dev->desc_in);
 
196
                }
 
197
        }
 
198
        else
 
199
        {
 
200
                if((dev->fHandle = CreateFile(uart_dev->desc_in,
 
201
                                              GENERIC_READ,
 
202
                                              FILE_SHARE_READ, NULL,
 
203
                                              OPEN_EXISTING,
 
204
                                              FILE_FLAG_OVERLAPPED,
 
205
                                              NULL)) == INVALID_HANDLE_VALUE)
 
206
                {
 
207
                        ret = -1;
 
208
                        fprintf(stderr, "Error when open device \"%s\" for input !!!\n", uart_dev->desc_in);
 
209
                }
 
210
                else if((dev->fHandleOut = CreateFile(uart_dev->desc_out,
 
211
                                                      GENERIC_WRITE,
 
212
                                                      FILE_SHARE_WRITE, NULL,
 
213
                                                      OPEN_EXISTING,
 
214
                                                      FILE_FLAG_OVERLAPPED,
 
215
                                                      NULL)) == INVALID_HANDLE_VALUE)
 
216
                {
 
217
                        CloseHandle(dev->fHandle);
 
218
                        ret = -1;
 
219
                        fprintf(stderr, "Error when open device \"%s\" for output !!!\n", uart_dev->desc_out);
 
220
                }
 
221
        }
 
222
 
 
223
        if(ret != 0)
 
224
        {
 
225
                free(dev);
 
226
                return ret;
 
227
        }
 
228
 
 
229
        InitializeCriticalSection(&dev->fLocker);
 
230
        dev->fEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 
231
        dev->fEventOut = CreateEvent(NULL, FALSE, FALSE, NULL);
 
232
 
 
233
        uart_dev->priv = (void*)dev;
 
234
 
 
235
        return 0;
 
236
}
 
237
 
 
238
 
 
239
int uart_pipe_close(struct uart_device *uart_dev)
 
240
{
 
241
        uart_pipe_win32 *dev = (uart_dev ? (uart_pipe_win32*)(uart_dev->priv) : NULL);
 
242
        if(dev == NULL) return -1;
 
243
 
 
244
        CloseHandle(dev->fHandle);
 
245
        if(dev->fHandleOut) CloseHandle(dev->fHandleOut);
 
246
        CloseHandle(dev->fEvent);
 
247
        CloseHandle(dev->fEventOut);
 
248
        DeleteCriticalSection(&dev->fLocker);
 
249
 
 
250
        uart_dev->priv = NULL;
 
251
 
 
252
        return 0;
 
253
}
 
254
 
 
255
 
 
256
static void CALLBACK uart_pipe_read_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
 
257
{
 
258
        uart_pipe_win32 *dev = (uart_pipe_win32*)lpOverlapped->hEvent;
 
259
        if(dev == NULL) return;
 
260
 
 
261
        EnterCriticalSection(&dev->fLocker);
 
262
 
 
263
        dev->fReading = FALSE;
 
264
        dev->fBufferLen = (dwErrorCode == 0 ? dwNumberOfBytesTransfered : 0);
 
265
        SetEvent(dev->fEvent);
 
266
 
 
267
        LeaveCriticalSection(&dev->fLocker);
 
268
}
 
269
 
 
270
 
 
271
static void CALLBACK uart_pipe_write_callback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
 
272
{
 
273
        uart_pipe_win32 *dev = (uart_pipe_win32*)lpOverlapped->hEvent;
 
274
        if(dev == NULL) return;
 
275
 
 
276
        dev->fWritten = (dwErrorCode == 0 ? dwNumberOfBytesTransfered : 0);
 
277
        SetEvent(dev->fEventOut);
 
278
}
 
279
 
 
280
 
 
281
int uart_pipe_read(struct uart_device *uart_dev, void *buf, size_t count, struct timeval *tv)
 
282
{
 
283
        uart_pipe_win32 *dev = (uart_dev ? (uart_pipe_win32*)(uart_dev->priv) : NULL);
 
284
        int retVal = 0, flags = 1;
 
285
        DWORD status;
 
286
 
 
287
        if(dev == NULL) return -1;
 
288
 
 
289
restart:
 
290
        EnterCriticalSection(&dev->fLocker);
 
291
 
 
292
        if(dev->fReading)
 
293
        {
 
294
                retVal = 0;
 
295
        }
 
296
        else if(dev->fBufferLen == 0)
 
297
        {
 
298
                retVal = 0;
 
299
 
 
300
                dev->fReading = TRUE;
 
301
                dev->fOverlapped.Internal = 0;
 
302
                dev->fOverlapped.InternalHigh = 0;
 
303
                dev->fOverlapped.Offset = 0;
 
304
                dev->fOverlapped.OffsetHigh = 0;
 
305
                dev->fOverlapped.hEvent = dev;
 
306
                ResetEvent(dev->fEvent);
 
307
 
 
308
                if(ReadFileEx(dev->fHandle, &dev->fBuffer[0], PIPE_BUFFER_SIZE,
 
309
                              &dev->fOverlapped, uart_pipe_read_callback) == 0)
 
310
                {
 
311
                        dev->fReading = FALSE;
 
312
                        retVal = -1;
 
313
                }
 
314
        }
 
315
        else
 
316
        {
 
317
                retVal = min((int)dev->fBufferLen, count);
 
318
                memcpy(buf, &dev->fBuffer[0], (size_t)retVal);
 
319
 
 
320
                if(count < dev->fBufferLen)
 
321
                        memmove(&dev->fBuffer[0], &dev->fBuffer[count], dev->fBufferLen - count);
 
322
 
 
323
                dev->fBufferLen -= retVal;
 
324
        }
 
325
 
 
326
        LeaveCriticalSection(&dev->fLocker);
 
327
 
 
328
        if(retVal == 0 && flags == 1)
 
329
        {
 
330
                DWORD timeout = (tv == NULL ? INFINITE : (DWORD)(tv->tv_sec * 1000UL + tv->tv_usec / 1000UL));
 
331
                while(TRUE)
 
332
                {
 
333
                        status = WaitForSingleObjectEx(dev->fEvent, timeout, TRUE);
 
334
                        if(status == WAIT_IO_COMPLETION && tv == NULL) continue;
 
335
                        if(status == WAIT_OBJECT_0)
 
336
                        {
 
337
                                flags = 0;
 
338
                                goto restart;
 
339
                        }
 
340
                        break;
 
341
                }
 
342
        }
 
343
 
 
344
        return retVal;
 
345
}
 
346
 
 
347
 
 
348
int uart_pipe_write(struct uart_device *uart_dev, void *buf, size_t count)
 
349
{
 
350
        uart_pipe_win32 *dev = (uart_dev ? (uart_pipe_win32*)(uart_dev->priv) : NULL);
 
351
        DWORD written = 0, status;
 
352
        HANDLE handle;
 
353
 
 
354
        if(dev == NULL) return -1;
 
355
 
 
356
        handle = (dev->fHandleOut == NULL ? dev->fHandle : dev->fHandleOut);
 
357
 
 
358
        dev->fOverlappedOut.Internal = 0;
 
359
        dev->fOverlappedOut.InternalHigh = 0;
 
360
        dev->fOverlappedOut.Offset = 0;
 
361
        dev->fOverlappedOut.OffsetHigh = 0;
 
362
        dev->fOverlappedOut.hEvent = dev;
 
363
        dev->fWritten = 0;
 
364
 
 
365
        if(WriteFileEx(handle, buf, (DWORD)count, &dev->fOverlappedOut, uart_pipe_write_callback) != 0)
 
366
        {
 
367
                while(TRUE)
 
368
                {
 
369
                        status = WaitForSingleObjectEx(dev->fEventOut, INFINITE, TRUE);
 
370
                        if(status == WAIT_IO_COMPLETION) continue;
 
371
                        if(status == WAIT_OBJECT_0) written = dev->fWritten;
 
372
                        break;
 
373
                }
 
374
        }
 
375
 
 
376
        return (int)written;
 
377
}
 
378
 
 
379
#else /* other system */
133
380
 
134
381
int uart_pipe_open(struct uart_device *uart_dev)
135
382
{
154
401
        return -1;
155
402
}
156
403
 
157
 
#endif /* SKYEYE_UART_PIPE_SUPPORTED */
 
404
#endif
 
405
 
 
406
#endif /* SKYEYE_UART_PIPE_POSIX_SUPPORTED */
158
407