254 |
/* returns numer of units found and initialized. */ |
/* returns numer of units found and initialized. */ |
255 |
/* optarg looks like ':com1=/dev/ttyS0' */ |
/* optarg looks like ':com1=/dev/ttyS0' */ |
256 |
/* when it arrives to this function. */ |
/* when it arrives to this function. */ |
257 |
/* windev u*dev baud, parity, stop bits, wordlength */ |
/* :com1=/dev/ttyS0,com2=/dev/ttyS1 */ |
|
/* :com1=/dev/ttyS0:9600,0|1|2,0|2,5|6|7|8:dtr */ |
|
258 |
int |
int |
259 |
serial_enum_devices(int *id, char* optarg) |
serial_enum_devices(int *id, char* optarg) |
260 |
{ |
{ |
261 |
SERIAL_DEVICE* pser_inf; |
SERIAL_DEVICE* pser_inf; |
262 |
|
|
263 |
int argcount=0; |
char *pos = optarg; |
264 |
char* pos = optarg; |
char *pos2; |
265 |
char* pos2; |
int count = 0; |
266 |
char* pos3; |
|
267 |
|
// skip the first colon |
268 |
if(*id<RDPDR_MAX_DEVICES){ |
optarg++; |
269 |
|
while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES) |
270 |
|
{ |
271 |
// Init data structures for device |
// Init data structures for device |
272 |
pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE)); |
pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE)); |
273 |
pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios)); |
pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios)); |
274 |
pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios)); |
pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios)); |
275 |
|
|
276 |
// skip the first colon |
pos2 = next_arg(optarg, '='); |
277 |
optarg++; |
strcpy(g_rdpdr_device[*id].name, optarg); |
278 |
while( (pos = next_arg( optarg, ':')) ){ |
|
279 |
|
toupper_str(g_rdpdr_device[*id].name); |
|
switch(argcount){ |
|
|
/* com1=/dev/ttyS0 */ |
|
|
case 0: |
|
|
pos2 = next_arg(optarg,'='); |
|
|
if( !pos2 || *pos2 == (char)0x00 ){ |
|
|
error("-r comport arguments should look like: -r comport:com1=/dev/ttyS0\n"); |
|
|
return 0; |
|
|
} |
|
|
/* optarg = com1, pos2 = /dev/ttyS0 */ |
|
|
strcpy(g_rdpdr_device[*id].name,optarg); |
|
|
|
|
|
toupper_str(g_rdpdr_device[*id].name); |
|
|
|
|
|
g_rdpdr_device[*id].local_path = xmalloc( strlen(pos2) + 1 ); |
|
|
strcpy(g_rdpdr_device[*id].local_path,pos2); |
|
|
break; |
|
|
/* 9600,0|1|2,O|2,5|6|7|8 */ |
|
|
/* TODO: values should be set in serial_create()... ??? */ |
|
|
case 1: |
|
|
pos2 = next_arg(optarg,','); |
|
|
/*optarg=9600*/ |
|
|
pser_inf->baud_rate = atoi(optarg); |
|
|
if( !pos2 || *pos2 == (char)0x00 ) |
|
|
break; |
|
|
pos3 = next_arg(pos2,','); |
|
|
/* pos2 = 0|1|2 */ |
|
|
pser_inf->parity = atoi(pos2); |
|
|
/* pos3 = 0|2,5|6|7|8*/ |
|
|
pos2 = next_arg(pos3,','); |
|
|
if( !pos3 || *pos3 == (char)0x00 ) |
|
|
break; |
|
|
pser_inf->stop_bits = atoi(pos3); |
|
|
/* pos2 = 5|6|7|8 */ |
|
|
if( !pos2 || *pos2 == (char)0x00 ) |
|
|
break; |
|
|
pser_inf->word_length = atoi(pos2); |
|
|
break; |
|
|
default: |
|
|
if( (*optarg != (char)0x00) && (strcmp( optarg, "dtr" ) == 0) ){ |
|
|
pser_inf->dtr = 1; |
|
|
} |
|
|
/* TODO: add more switches here, like xon, xoff. they will be separated by colon |
|
|
if( (*optarg != (char)0x00) && (strcmp( optarg, "xon" ) == 0) ){ |
|
|
} |
|
|
*/ |
|
|
break; |
|
|
} |
|
|
argcount++; |
|
|
optarg=pos; |
|
|
} |
|
|
|
|
|
printf("SERIAL %s to %s", g_rdpdr_device[*id].name, g_rdpdr_device[*id].local_path ); |
|
|
if( pser_inf->baud_rate != 0 ){ |
|
|
printf(" with baud: %u, parity: %u, stop bits: %u word length: %u", pser_inf->baud_rate, pser_inf->parity, pser_inf->stop_bits, pser_inf->word_length ); |
|
|
if( pser_inf->dtr ) |
|
|
printf( " dtr set\n"); |
|
|
else |
|
|
printf( "\n" ); |
|
|
}else |
|
|
printf("\n"); |
|
280 |
|
|
281 |
|
g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1); |
282 |
|
strcpy(g_rdpdr_device[*id].local_path, pos2); |
283 |
|
printf("SERIAL %s to %s\n", g_rdpdr_device[*id].name, g_rdpdr_device[*id].local_path); |
284 |
// set device type |
// set device type |
285 |
g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL; |
g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL; |
286 |
g_rdpdr_device[*id].pdevice_data = (void *) pser_inf; |
g_rdpdr_device[*id].pdevice_data = (void *) pser_inf; |
287 |
|
count++; |
288 |
(*id)++; |
(*id)++; |
289 |
|
|
290 |
return 1; |
optarg = pos; |
291 |
} |
} |
292 |
return 0; |
return count; |
293 |
} |
} |
294 |
|
|
295 |
NTSTATUS |
NTSTATUS |
298 |
HANDLE serial_fd; |
HANDLE serial_fd; |
299 |
SERIAL_DEVICE *pser_inf; |
SERIAL_DEVICE *pser_inf; |
300 |
struct termios *ptermios; |
struct termios *ptermios; |
|
SERIAL_DEVICE tmp_inf; |
|
301 |
|
|
302 |
pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data; |
pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data; |
303 |
ptermios = pser_inf->ptermios; |
ptermios = pser_inf->ptermios; |
306 |
if (serial_fd == -1) |
if (serial_fd == -1) |
307 |
return STATUS_ACCESS_DENIED; |
return STATUS_ACCESS_DENIED; |
308 |
|
|
309 |
// before we clog the user inserted args store them locally |
if (!get_termios(pser_inf, serial_fd )) |
|
// |
|
|
memcpy(&tmp_inf,pser_inf, sizeof(pser_inf) ); |
|
|
|
|
|
if (!get_termios(pser_inf, serial_fd)) |
|
310 |
return STATUS_ACCESS_DENIED; |
return STATUS_ACCESS_DENIED; |
311 |
|
|
312 |
// Store handle for later use |
// Store handle for later use |
313 |
g_rdpdr_device[device_id].handle = serial_fd; |
g_rdpdr_device[device_id].handle = serial_fd; |
|
tcgetattr(serial_fd, pser_inf->pold_termios); // Backup original settings |
|
314 |
|
|
315 |
// Initial configuration. |
/* some sane information */ |
316 |
bzero(ptermios, sizeof(ptermios)); |
printf("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u\n", |
317 |
ptermios->c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD; |
g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path, |
318 |
ptermios->c_iflag = IGNPAR; |
pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr ); |
319 |
ptermios->c_oflag = 0; |
printf("INFO: use stty to change settings\n" ); |
320 |
ptermios->c_lflag = 0; //non-canonical, no echo |
|
321 |
ptermios->c_cc[VTIME] = 0; |
//tcgetattr(serial_fd, pser_inf->ptermios); |
|
tcsetattr(serial_fd, TCSANOW, ptermios); |
|
|
|
|
|
// overload with user settings |
|
|
// -- if there are any |
|
|
if( tmp_inf.baud_rate != 0 ){ |
|
|
dtr = tmp_inf.dtr; |
|
|
baud_rate = tmp_inf.baud_rate; |
|
|
parity = tmp_inf.parity; |
|
|
stop_bits = tmp_inf.stop_bits; |
|
|
word_length = tmp_inf.word_length; |
|
|
set_termios(); |
|
|
} |
|
322 |
|
|
323 |
*handle = serial_fd; |
*handle = serial_fd; |
324 |
return STATUS_SUCCESS; |
return STATUS_SUCCESS; |
325 |
} |
} |
326 |
|
|