⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.c

📁 rdesktop is a client for Microsoft Windows NT Terminal Server, Windows 2000 Terminal Services, Wind
💻 C
📖 第 1 页 / 共 2 页
字号:
		g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);		strcpy(g_rdpdr_device[*id].local_path, pos2);		printf("SERIAL %s to %s\n", g_rdpdr_device[*id].name,		       g_rdpdr_device[*id].local_path);		/* set device type */		g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL;		g_rdpdr_device[*id].pdevice_data = (void *) pser_inf;		count++;		(*id)++;		optarg = pos;	}	return count;}static NTSTATUSserial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,	      uint32 flags_and_attributes, char *filename, NTHANDLE * handle){	NTHANDLE serial_fd;	SERIAL_DEVICE *pser_inf;	struct termios *ptermios;	pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;	ptermios = pser_inf->ptermios;	serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY | O_NONBLOCK);	if (serial_fd == -1)	{		perror("open");		return STATUS_ACCESS_DENIED;	}	if (!get_termios(pser_inf, serial_fd))	{		printf("INFO: SERIAL %s access denied\n", g_rdpdr_device[device_id].name);		fflush(stdout);		return STATUS_ACCESS_DENIED;	}	/* Store handle for later use */	g_rdpdr_device[device_id].handle = serial_fd;	/* some sane information */	DEBUG_SERIAL(("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u, rts %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, pser_inf->rts));	pser_inf->ptermios->c_iflag &=		~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);	pser_inf->ptermios->c_oflag &= ~OPOST;	pser_inf->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);	pser_inf->ptermios->c_cflag &= ~(CSIZE | PARENB);	pser_inf->ptermios->c_cflag |= CS8;	tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios);	pser_inf->event_txempty = 0;	pser_inf->event_cts = 0;	pser_inf->event_dsr = 0;	pser_inf->event_rlsd = 0;	pser_inf->event_pending = 0;	*handle = serial_fd;	/* all read and writes should be non blocking */	if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)		perror("fcntl");	pser_inf->read_total_timeout_constant = 5;	return STATUS_SUCCESS;}static NTSTATUSserial_close(NTHANDLE handle){	int i = get_device_index(handle);	if (i >= 0)		g_rdpdr_device[i].handle = 0;	rdpdr_abort_io(handle, 0, STATUS_TIMEOUT);	close(handle);	return STATUS_SUCCESS;}static NTSTATUSserial_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result){	long timeout;	SERIAL_DEVICE *pser_inf;	struct termios *ptermios;#ifdef WITH_DEBUG_SERIAL	int bytes_inqueue;#endif	timeout = 90;	pser_inf = get_serial_info(handle);	ptermios = pser_inf->ptermios;	/* Set timeouts kind of like the windows serial timeout parameters. Multiply timeout	   with requested read size */	if (pser_inf->read_total_timeout_multiplier | pser_inf->read_total_timeout_constant)	{		timeout =			(pser_inf->read_total_timeout_multiplier * length +			 pser_inf->read_total_timeout_constant + 99) / 100;	}	else if (pser_inf->read_interval_timeout)	{		timeout = (pser_inf->read_interval_timeout * length + 99) / 100;	}	/* If a timeout is set, do a blocking read, which times out after some time.	   It will make rdesktop less responsive, but it will improve serial performance, by not	   reading one character at a time. */	if (timeout == 0)	{		ptermios->c_cc[VTIME] = 0;		ptermios->c_cc[VMIN] = 0;	}	else	{		ptermios->c_cc[VTIME] = timeout;		ptermios->c_cc[VMIN] = 1;	}	tcsetattr(handle, TCSANOW, ptermios);#if defined(WITH_DEBUG_SERIAL) && defined(TIOCINQ)	ioctl(handle, TIOCINQ, &bytes_inqueue);	DEBUG_SERIAL(("serial_read inqueue: %d expected %d\n", bytes_inqueue, length));#endif	*result = read(handle, data, length);#ifdef WITH_DEBUG_SERIAL	DEBUG_SERIAL(("serial_read Bytes %d\n", *result));	if (*result > 0)		hexdump(data, *result);#endif	return STATUS_SUCCESS;}static NTSTATUSserial_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result){	SERIAL_DEVICE *pser_inf;	pser_inf = get_serial_info(handle);	*result = write(handle, data, length);	if (*result > 0)		pser_inf->event_txempty = *result;	DEBUG_SERIAL(("serial_write length %d, offset %d result %d\n", length, offset, *result));	return STATUS_SUCCESS;}static NTSTATUSserial_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out){	int flush_mask, purge_mask;	uint32 result, modemstate;	uint8 immediate;	SERIAL_DEVICE *pser_inf;	struct termios *ptermios;	if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)		return STATUS_INVALID_PARAMETER;	pser_inf = get_serial_info(handle);	ptermios = pser_inf->ptermios;	/* extract operation */	request >>= 2;	request &= 0xfff;	switch (request)	{		case SERIAL_SET_BAUD_RATE:			in_uint32_le(in, pser_inf->baud_rate);			set_termios(pser_inf, handle);			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BAUD_RATE %d\n",				      pser_inf->baud_rate));			break;		case SERIAL_GET_BAUD_RATE:			out_uint32_le(out, pser_inf->baud_rate);			DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_BAUD_RATE %d\n",				      pser_inf->baud_rate));			break;		case SERIAL_SET_QUEUE_SIZE:			in_uint32_le(in, pser_inf->queue_in_size);			in_uint32_le(in, pser_inf->queue_out_size);			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_QUEUE_SIZE in %d out %d\n",				      pser_inf->queue_in_size, pser_inf->queue_out_size));			break;		case SERIAL_SET_LINE_CONTROL:			in_uint8(in, pser_inf->stop_bits);			in_uint8(in, pser_inf->parity);			in_uint8(in, pser_inf->word_length);			set_termios(pser_inf, handle);			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_LINE_CONTROL stop %d parity %d word %d\n", pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length));			break;		case SERIAL_GET_LINE_CONTROL:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_LINE_CONTROL\n"));			out_uint8(out, pser_inf->stop_bits);			out_uint8(out, pser_inf->parity);			out_uint8(out, pser_inf->word_length);			break;		case SERIAL_IMMEDIATE_CHAR:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_IMMEDIATE_CHAR\n"));			in_uint8(in, immediate);			serial_write(handle, &immediate, 1, 0, &result);			break;		case SERIAL_CONFIG_SIZE:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_CONFIG_SIZE\n"));			out_uint32_le(out, 0);			break;		case SERIAL_GET_CHARS:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_CHARS\n"));			out_uint8a(out, pser_inf->chars, 6);			break;		case SERIAL_SET_CHARS:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_CHARS\n"));			in_uint8a(in, pser_inf->chars, 6);#ifdef WITH_DEBUG_SERIAL			hexdump(pser_inf->chars, 6);#endif			set_termios(pser_inf, handle);			break;		case SERIAL_GET_HANDFLOW:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_HANDFLOW\n"));			get_termios(pser_inf, handle);			out_uint32_le(out, pser_inf->control);			out_uint32_le(out, pser_inf->xonoff);	/* Xon/Xoff */			out_uint32_le(out, pser_inf->onlimit);			out_uint32_le(out, pser_inf->offlimit);			break;		case SERIAL_SET_HANDFLOW:			in_uint32_le(in, pser_inf->control);			in_uint32_le(in, pser_inf->xonoff);			in_uint32_le(in, pser_inf->onlimit);			in_uint32_le(in, pser_inf->offlimit);			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_HANDFLOW %x %x %x %x\n",				      pser_inf->control, pser_inf->xonoff, pser_inf->onlimit,				      pser_inf->onlimit));			set_termios(pser_inf, handle);			break;		case SERIAL_SET_TIMEOUTS:			in_uint32(in, pser_inf->read_interval_timeout);			in_uint32(in, pser_inf->read_total_timeout_multiplier);			in_uint32(in, pser_inf->read_total_timeout_constant);			in_uint32(in, pser_inf->write_total_timeout_multiplier);			in_uint32(in, pser_inf->write_total_timeout_constant);			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_TIMEOUTS read timeout %d %d %d\n",				      pser_inf->read_interval_timeout,				      pser_inf->read_total_timeout_multiplier,				      pser_inf->read_total_timeout_constant));			break;		case SERIAL_GET_TIMEOUTS:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_TIMEOUTS read timeout %d %d %d\n",				      pser_inf->read_interval_timeout,				      pser_inf->read_total_timeout_multiplier,				      pser_inf->read_total_timeout_constant));			out_uint32(out, pser_inf->read_interval_timeout);			out_uint32(out, pser_inf->read_total_timeout_multiplier);			out_uint32(out, pser_inf->read_total_timeout_constant);			out_uint32(out, pser_inf->write_total_timeout_multiplier);			out_uint32(out, pser_inf->write_total_timeout_constant);			break;		case SERIAL_GET_WAIT_MASK:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_WAIT_MASK %X\n",				      pser_inf->wait_mask));			out_uint32(out, pser_inf->wait_mask);			break;		case SERIAL_SET_WAIT_MASK:			in_uint32(in, pser_inf->wait_mask);			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_WAIT_MASK %X\n",				      pser_inf->wait_mask));			break;		case SERIAL_SET_DTR:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_DTR\n"));			ioctl(handle, TIOCMGET, &result);			result |= TIOCM_DTR;			ioctl(handle, TIOCMSET, &result);			pser_inf->dtr = 1;			break;		case SERIAL_CLR_DTR:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_DTR\n"));			ioctl(handle, TIOCMGET, &result);			result &= ~TIOCM_DTR;			ioctl(handle, TIOCMSET, &result);			pser_inf->dtr = 0;			break;		case SERIAL_SET_RTS:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_RTS\n"));			ioctl(handle, TIOCMGET, &result);			result |= TIOCM_RTS;			ioctl(handle, TIOCMSET, &result);			pser_inf->rts = 1;			break;		case SERIAL_CLR_RTS:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_RTS\n"));			ioctl(handle, TIOCMGET, &result);			result &= ~TIOCM_RTS;			ioctl(handle, TIOCMSET, &result);			pser_inf->rts = 0;			break;		case SERIAL_GET_MODEMSTATUS:			modemstate = 0;#ifdef TIOCMGET			ioctl(handle, TIOCMGET, &result);			if (result & TIOCM_CTS)				modemstate |= SERIAL_MS_CTS;			if (result & TIOCM_DSR)				modemstate |= SERIAL_MS_DSR;			if (result & TIOCM_RNG)				modemstate |= SERIAL_MS_RNG;			if (result & TIOCM_CAR)				modemstate |= SERIAL_MS_CAR;			if (result & TIOCM_DTR)				modemstate |= SERIAL_MS_DTR;			if (result & TIOCM_RTS)				modemstate |= SERIAL_MS_RTS;#endif			DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X\n", modemstate));			out_uint32_le(out, modemstate);			break;		case SERIAL_GET_COMMSTATUS:			out_uint32_le(out, 0);	/* Errors */			out_uint32_le(out, 0);	/* Hold reasons */			result = 0;#ifdef TIOCINQ			ioctl(handle, TIOCINQ, &result);#endif			out_uint32_le(out, result);	/* Amount in in queue */			if (result)				DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d\n",					      result));			result = 0;#ifdef TIOCOUTQ			ioctl(handle, TIOCOUTQ, &result);#endif			out_uint32_le(out, result);	/* Amount in out queue */			if (result)				DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d\n", result));			out_uint8(out, 0);	/* EofReceived */			out_uint8(out, 0);	/* WaitForImmediate */			break;		case SERIAL_PURGE:			in_uint32(in, purge_mask);			DEBUG_SERIAL(("serial_ioctl -> SERIAL_PURGE purge_mask %X\n", purge_mask));			flush_mask = 0;			if (purge_mask & SERIAL_PURGE_TXCLEAR)				flush_mask |= TCOFLUSH;			if (purge_mask & SERIAL_PURGE_RXCLEAR)				flush_mask |= TCIFLUSH;			if (flush_mask != 0)				tcflush(handle, flush_mask);			if (purge_mask & SERIAL_PURGE_TXABORT)				rdpdr_abort_io(handle, 4, STATUS_CANCELLED);			if (purge_mask & SERIAL_PURGE_RXABORT)				rdpdr_abort_io(handle, 3, STATUS_CANCELLED);			break;		case SERIAL_WAIT_ON_MASK:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_WAIT_ON_MASK %X\n",				      pser_inf->wait_mask));			pser_inf->event_pending = 1;			if (serial_get_event(handle, &result))			{				DEBUG_SERIAL(("WAIT end  event = %x\n", result));				out_uint32_le(out, result);				break;			}			return STATUS_PENDING;			break;		case SERIAL_SET_BREAK_ON:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_ON\n"));			tcsendbreak(handle, 0);			break;		case SERIAL_RESET_DEVICE:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_RESET_DEVICE\n"));			break;		case SERIAL_SET_BREAK_OFF:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_OFF\n"));			break;		case SERIAL_SET_XOFF:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XOFF\n"));			break;		case SERIAL_SET_XON:			DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XON\n"));			tcflow(handle, TCION);			break;		default:			unimpl("SERIAL IOCTL %d\n", request);			return STATUS_INVALID_PARAMETER;	}	return STATUS_SUCCESS;}BOOLserial_get_event(NTHANDLE handle, uint32 * result){	int index;	SERIAL_DEVICE *pser_inf;	int bytes;	BOOL ret = False;	*result = 0;	index = get_device_index(handle);	if (index < 0)		return False;#ifdef TIOCINQ	pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;	ioctl(handle, TIOCINQ, &bytes);	if (bytes > 0)	{		DEBUG_SERIAL(("serial_get_event Bytes %d\n", bytes));		if (bytes > pser_inf->event_rlsd)		{			pser_inf->event_rlsd = bytes;			if (pser_inf->wait_mask & SERIAL_EV_RLSD)			{				DEBUG_SERIAL(("Event -> SERIAL_EV_RLSD \n"));				*result |= SERIAL_EV_RLSD;				ret = True;			}		}		if ((bytes > 1) && (pser_inf->wait_mask & SERIAL_EV_RXFLAG))		{			DEBUG_SERIAL(("Event -> SERIAL_EV_RXFLAG Bytes %d\n", bytes));			*result |= SERIAL_EV_RXFLAG;			ret = True;		}		if ((pser_inf->wait_mask & SERIAL_EV_RXCHAR))		{			DEBUG_SERIAL(("Event -> SERIAL_EV_RXCHAR Bytes %d\n", bytes));			*result |= SERIAL_EV_RXCHAR;			ret = True;		}	}	else	{		pser_inf->event_rlsd = 0;	}#endif#ifdef TIOCOUTQ	ioctl(handle, TIOCOUTQ, &bytes);	if ((bytes == 0)	    && (pser_inf->event_txempty > 0) && (pser_inf->wait_mask & SERIAL_EV_TXEMPTY))	{		DEBUG_SERIAL(("Event -> SERIAL_EV_TXEMPTY\n"));		*result |= SERIAL_EV_TXEMPTY;		ret = True;	}	pser_inf->event_txempty = bytes;#endif	ioctl(handle, TIOCMGET, &bytes);	if ((bytes & TIOCM_DSR) != pser_inf->event_dsr)	{		pser_inf->event_dsr = bytes & TIOCM_DSR;		if (pser_inf->wait_mask & SERIAL_EV_DSR)		{			DEBUG_SERIAL(("event -> SERIAL_EV_DSR %s\n",				      (bytes & TIOCM_DSR) ? "ON" : "OFF"));			*result |= SERIAL_EV_DSR;			ret = True;		}	}	if ((bytes & TIOCM_CTS) != pser_inf->event_cts)	{		pser_inf->event_cts = bytes & TIOCM_CTS;		if (pser_inf->wait_mask & SERIAL_EV_CTS)		{			DEBUG_SERIAL((" EVENT-> SERIAL_EV_CTS %s\n",				      (bytes & TIOCM_CTS) ? "ON" : "OFF"));			*result |= SERIAL_EV_CTS;			ret = True;		}	}	if (ret)		pser_inf->event_pending = 0;	return ret;}/* Read timeout for a given file descripter (device) when adding fd's to select() */BOOLserial_get_timeout(NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout){	int index;	SERIAL_DEVICE *pser_inf;	index = get_device_index(handle);	if (index < 0)		return True;	if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)	{		return False;	}	pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;	*timeout =		pser_inf->read_total_timeout_multiplier * length +		pser_inf->read_total_timeout_constant;	*itv_timeout = pser_inf->read_interval_timeout;	return True;}DEVICE_FNS serial_fns = {	serial_create,	serial_close,	serial_read,	serial_write,	serial_device_control};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -