55 |
|
|
56 |
extern RDPDR_DEVICE g_rdpdr_device[]; |
extern RDPDR_DEVICE g_rdpdr_device[]; |
57 |
|
|
58 |
int serial_fd; |
SERIAL_DEVICE * |
59 |
struct termios termios; |
get_serial_info(HANDLE handle) |
|
|
|
|
int dtr; |
|
|
uint32 baud_rate; |
|
|
uint32 queue_in_size, queue_out_size; |
|
|
uint32 wait_mask; |
|
|
uint8 stop_bits, parity, word_length; |
|
|
|
|
|
SERIAL_DEVICE * get_serial_info(HANDLE handle) |
|
60 |
{ |
{ |
61 |
int index; |
int index; |
62 |
|
|
190 |
} |
} |
191 |
|
|
192 |
static void |
static void |
193 |
set_termios(void) |
set_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd) |
194 |
{ |
{ |
195 |
speed_t speed; |
speed_t speed; |
196 |
|
|
197 |
switch (baud_rate) |
struct termios *ptermios; |
198 |
|
|
199 |
|
ptermios = pser_inf->ptermios; |
200 |
|
|
201 |
|
|
202 |
|
switch (pser_inf->baud_rate) |
203 |
{ |
{ |
204 |
#ifdef B75 |
#ifdef B75 |
205 |
case 75: |
case 75: |
283 |
|
|
284 |
/* on systems with separate ispeed and ospeed, we can remember the speed |
/* on systems with separate ispeed and ospeed, we can remember the speed |
285 |
in ispeed while changing DTR with ospeed */ |
in ispeed while changing DTR with ospeed */ |
286 |
cfsetispeed(&termios, speed); |
cfsetispeed(pser_inf->ptermios, speed); |
287 |
cfsetospeed(&termios, dtr ? speed : 0); |
cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0); |
288 |
|
|
289 |
termios.c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE); |
ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE); |
290 |
switch (stop_bits) |
switch (pser_inf->stop_bits) |
291 |
{ |
{ |
292 |
case STOP_BITS_2: |
case STOP_BITS_2: |
293 |
termios.c_cflag |= CSTOPB; |
ptermios->c_cflag |= CSTOPB; |
294 |
break; |
break; |
295 |
} |
} |
296 |
switch (parity) |
switch (pser_inf->parity) |
297 |
{ |
{ |
298 |
case EVEN_PARITY: |
case EVEN_PARITY: |
299 |
termios.c_cflag |= PARENB; |
ptermios->c_cflag |= PARENB; |
300 |
break; |
break; |
301 |
case ODD_PARITY: |
case ODD_PARITY: |
302 |
termios.c_cflag |= PARENB | PARODD; |
ptermios->c_cflag |= PARENB | PARODD; |
303 |
break; |
break; |
304 |
} |
} |
305 |
switch (word_length) |
switch (pser_inf->word_length) |
306 |
{ |
{ |
307 |
case 5: |
case 5: |
308 |
termios.c_cflag |= CS5; |
ptermios->c_cflag |= CS5; |
309 |
break; |
break; |
310 |
case 6: |
case 6: |
311 |
termios.c_cflag |= CS6; |
ptermios->c_cflag |= CS6; |
312 |
break; |
break; |
313 |
case 7: |
case 7: |
314 |
termios.c_cflag |= CS7; |
ptermios->c_cflag |= CS7; |
315 |
break; |
break; |
316 |
default: |
default: |
317 |
termios.c_cflag |= CS8; |
ptermios->c_cflag |= CS8; |
318 |
break; |
break; |
319 |
} |
} |
320 |
|
|
321 |
tcsetattr(serial_fd, TCSANOW, &termios); |
tcsetattr(serial_fd, TCSANOW, ptermios); |
322 |
} |
} |
323 |
|
|
324 |
/* Enumeration of devices from rdesktop.c */ |
/* Enumeration of devices from rdesktop.c */ |
377 |
serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY); |
serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY); |
378 |
|
|
379 |
if (serial_fd == -1) |
if (serial_fd == -1) |
380 |
|
{ |
381 |
|
perror("open"); |
382 |
return STATUS_ACCESS_DENIED; |
return STATUS_ACCESS_DENIED; |
383 |
|
} |
384 |
|
|
385 |
if (!get_termios(pser_inf, serial_fd)) |
if (!get_termios(pser_inf, serial_fd)) |
386 |
return STATUS_ACCESS_DENIED; |
return STATUS_ACCESS_DENIED; |
392 |
printf("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u\n", g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path, pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr); |
printf("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u\n", g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path, pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr); |
393 |
printf("INFO: use stty to change settings\n"); |
printf("INFO: use stty to change settings\n"); |
394 |
|
|
395 |
//tcgetattr(serial_fd, pser_inf->ptermios); |
/* ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD; |
396 |
|
ptermios->c_cflag |= CREAD; |
397 |
|
ptermios->c_lflag |= ICANON; |
398 |
|
ptermios->c_iflag = IGNPAR | ICRNL; |
399 |
|
|
400 |
|
tcsetattr(serial_fd, TCSANOW, ptermios); |
401 |
|
*/ |
402 |
*handle = serial_fd; |
*handle = serial_fd; |
403 |
return STATUS_SUCCESS; |
return STATUS_SUCCESS; |
404 |
} |
} |
406 |
static NTSTATUS |
static NTSTATUS |
407 |
serial_close(HANDLE handle) |
serial_close(HANDLE handle) |
408 |
{ |
{ |
409 |
close(serial_fd); |
g_rdpdr_device[get_device_index(handle)].handle = 0; |
410 |
|
close(handle); |
411 |
return STATUS_SUCCESS; |
return STATUS_SUCCESS; |
412 |
} |
} |
413 |
|
|
418 |
SERIAL_DEVICE *pser_inf; |
SERIAL_DEVICE *pser_inf; |
419 |
struct termios *ptermios; |
struct termios *ptermios; |
420 |
|
|
421 |
timeout = 0; |
// timeout = 90; |
422 |
pser_inf = get_serial_info(handle); |
pser_inf = get_serial_info(handle); |
423 |
ptermios = pser_inf->ptermios; |
ptermios = pser_inf->ptermios; |
424 |
|
|
425 |
|
#if 0 |
426 |
// Set timeouts kind of like the windows serial timeout parameters. Multiply timeout |
// Set timeouts kind of like the windows serial timeout parameters. Multiply timeout |
427 |
// with requested read size |
// with requested read size |
428 |
if (pser_inf->read_total_timeout_multiplier | pser_inf->read_total_timeout_constant) |
if (pser_inf->read_total_timeout_multiplier | pser_inf->read_total_timeout_constant) |
450 |
ptermios->c_cc[VMIN] = 1; |
ptermios->c_cc[VMIN] = 1; |
451 |
} |
} |
452 |
tcsetattr(handle, TCSANOW, ptermios); |
tcsetattr(handle, TCSANOW, ptermios); |
453 |
|
#endif |
454 |
*result = read(handle, data, length); |
*result = read(handle, data, length); |
455 |
return STATUS_SUCCESS; |
return STATUS_SUCCESS; |
456 |
} |
} |
467 |
{ |
{ |
468 |
uint32 result; |
uint32 result; |
469 |
uint8 immediate; |
uint8 immediate; |
470 |
|
SERIAL_DEVICE *pser_inf; |
471 |
|
struct termios *ptermios; |
472 |
|
|
473 |
if ((request >> 16) != FILE_DEVICE_SERIAL_PORT) |
if ((request >> 16) != FILE_DEVICE_SERIAL_PORT) |
474 |
return STATUS_INVALID_PARAMETER; |
return STATUS_INVALID_PARAMETER; |
475 |
|
|
476 |
|
pser_inf = get_serial_info(handle); |
477 |
|
ptermios = pser_inf->ptermios; |
478 |
|
|
479 |
/* extract operation */ |
/* extract operation */ |
480 |
request >>= 2; |
request >>= 2; |
481 |
request &= 0xfff; |
request &= 0xfff; |
485 |
switch (request) |
switch (request) |
486 |
{ |
{ |
487 |
case SERIAL_SET_BAUD_RATE: |
case SERIAL_SET_BAUD_RATE: |
488 |
in_uint32_le(in, baud_rate); |
in_uint32_le(in, pser_inf->baud_rate); |
489 |
set_termios(); |
set_termios(pser_inf, handle); |
490 |
break; |
break; |
491 |
case SERIAL_GET_BAUD_RATE: |
case SERIAL_GET_BAUD_RATE: |
492 |
out_uint32_le(out, baud_rate); |
out_uint32_le(out, pser_inf->baud_rate); |
493 |
break; |
break; |
494 |
case SERIAL_SET_QUEUE_SIZE: |
case SERIAL_SET_QUEUE_SIZE: |
495 |
in_uint32_le(in, queue_in_size); |
in_uint32_le(in, pser_inf->queue_in_size); |
496 |
in_uint32_le(in, queue_out_size); |
in_uint32_le(in, pser_inf->queue_out_size); |
497 |
break; |
break; |
498 |
case SERIAL_SET_LINE_CONTROL: |
case SERIAL_SET_LINE_CONTROL: |
499 |
in_uint8(in, stop_bits); |
in_uint8(in, pser_inf->stop_bits); |
500 |
in_uint8(in, parity); |
in_uint8(in, pser_inf->parity); |
501 |
in_uint8(in, word_length); |
in_uint8(in, pser_inf->word_length); |
502 |
set_termios(); |
set_termios(pser_inf, handle); |
503 |
break; |
break; |
504 |
case SERIAL_GET_LINE_CONTROL: |
case SERIAL_GET_LINE_CONTROL: |
505 |
out_uint8(out, stop_bits); |
out_uint8(out, pser_inf->stop_bits); |
506 |
out_uint8(out, parity); |
out_uint8(out, pser_inf->parity); |
507 |
out_uint8(out, word_length); |
out_uint8(out, pser_inf->word_length); |
508 |
break; |
break; |
509 |
case SERIAL_IMMEDIATE_CHAR: |
case SERIAL_IMMEDIATE_CHAR: |
510 |
in_uint8(in, immediate); |
in_uint8(in, immediate); |
535 |
out_uint8s(out, 20); |
out_uint8s(out, 20); |
536 |
break; |
break; |
537 |
case SERIAL_GET_WAIT_MASK: |
case SERIAL_GET_WAIT_MASK: |
538 |
out_uint32(out, wait_mask); |
out_uint32(out, pser_inf->wait_mask); |
539 |
break; |
break; |
540 |
case SERIAL_SET_WAIT_MASK: |
case SERIAL_SET_WAIT_MASK: |
541 |
in_uint32(in, wait_mask); |
in_uint32(in, pser_inf->wait_mask); |
542 |
break; |
break; |
543 |
case SERIAL_SET_DTR: |
case SERIAL_SET_DTR: |
544 |
dtr = 1; |
pser_inf->dtr = 1; |
545 |
set_termios(); |
set_termios(pser_inf, handle); |
546 |
break; |
break; |
547 |
case SERIAL_CLR_DTR: |
case SERIAL_CLR_DTR: |
548 |
dtr = 0; |
pser_inf->dtr = 0; |
549 |
set_termios(); |
set_termios(pser_inf, handle); |
550 |
break; |
break; |
551 |
#if 0 |
#if 0 |
552 |
case SERIAL_WAIT_ON_MASK: |
case SERIAL_WAIT_ON_MASK: |
591 |
|
|
592 |
/* Read timeout for a given file descripter (device) when adding fd's to select() */ |
/* Read timeout for a given file descripter (device) when adding fd's to select() */ |
593 |
BOOL |
BOOL |
594 |
serial_get_timeout(uint32 handle, uint32 length, uint32 * timeout, uint32 * itv_timeout) |
serial_get_timeout(HANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout) |
595 |
{ |
{ |
596 |
int index; |
int index; |
597 |
SERIAL_DEVICE *pser_inf; |
SERIAL_DEVICE *pser_inf; |