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

📄 winserial.c

📁 NOKIA手机开发包
💻 C
字号:
/*  $Id: winserial.c,v 1.10 2003/03/06 21:08:17 pkot Exp $  G N O K I I  A Linux/Unix toolset and driver for Nokia mobile phones.  This file is part of gnokii.  Gnokii is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.  Gnokii is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with gnokii; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  Copyright (C) 1999, 2000 Hugh Blemings & Pavel Jan韐 ml.*/#include <windows.h>#include <string.h>#include <stdio.h>#include <io.h>#include <memory.h>#include "misc.h"#include "gnokii.h"#define USECOMM      /* yes, we need the COMM API */HANDLE hPhone;OVERLAPPED osWrite, osRead;/* Open the serial port and store the settings. */int serial_open(const char *file, int oflags){	COMMTIMEOUTS  CommTimeOuts;	if ((hPhone =	    CreateFile(file, GENERIC_READ | GENERIC_WRITE,	    0,                    /* exclusive access */	    NULL,                 /* no security attrs */	    OPEN_EXISTING,	    FILE_ATTRIBUTE_NORMAL |	    FILE_FLAG_OVERLAPPED, /* overlapped I/O */	    NULL)) == (HANDLE) -1)		return FALSE;	else {		/* get any early notifications */		SetCommMask(hPhone, EV_RXCHAR);		/* setup device buffers */		SetupComm(hPhone, 4096, 4096);		/* purge any information in the buffer */		PurgeComm(hPhone, PURGE_TXABORT | PURGE_RXABORT |			  PURGE_TXCLEAR | PURGE_RXCLEAR);		/* set up for overlapped I/O */		CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;		CommTimeOuts.ReadTotalTimeoutMultiplier = 0;		CommTimeOuts.ReadTotalTimeoutConstant = 1000;#if 0		/* CBR_9600 is approximately 1byte/ms. For our purposes, allow		 * double the expected time per character for a fudge factor.		 */		CommTimeOuts.WriteTotalTimeoutMultiplier = 2 * CBR_9600 / CBR_115200;#else		CommTimeOuts.WriteTotalTimeoutMultiplier = 10;#endif		CommTimeOuts.WriteTotalTimeoutConstant = 0;		SetCommTimeouts(hPhone, &CommTimeOuts);	}	return true;}/* Close the serial port and restore old settings. */int serial_close(int fd, struct gn_statemachine *state){	/* disable event notification and wait for thread	 * to halt	 */	SetCommMask(hPhone, 0);	/* drop DTR */	EscapeCommFunction(hPhone, CLRDTR);	/* purge any outstanding reads/writes and close device handle */	PurgeComm(hPhone, PURGE_TXABORT | PURGE_RXABORT |		  PURGE_TXCLEAR | PURGE_RXCLEAR);	CloseHandle(hPhone);	return true;}/* Open a device with standard options. * Use value (-1) for "with_hw_handshake" if its specification is required from the user. */int serial_opendevice(const char *file, int with_odd_parity,		      int with_async, int with_hw_handshake,		      struct gn_statemachine *state){	serial_open(file, 0);	return true;}/* Set the DTR and RTS bit of the serial device. */void serial_setdtrrts(int fd, int dtr, int rts, struct gn_statemachine *state){	BOOL       fRetVal;	DCB        dcb;	dcb.DCBlength = sizeof(DCB);	GetCommState(hPhone, &dcb);	dcb.fOutxDsrFlow = 0;	if (dtr)		dcb.fDtrControl = DTR_CONTROL_ENABLE;	else		dcb.fDtrControl = DTR_CONTROL_DISABLE;	dcb.fOutxCtsFlow = 0;	if (rts)		dcb.fRtsControl = RTS_CONTROL_ENABLE;	else		dcb.fRtsControl = RTS_CONTROL_DISABLE;	/* no software flow control */	dcb.fInX = dcb.fOutX = 0;	fRetVal = SetCommState(hPhone, &dcb);}int serial_select(int fd, struct timeval *timeout, struct gn_statemachine *state){	usleep(timeout->tv_sec * 60 + timeout->tv_usec);	return 1;}/* Change the speed of the serial device. * RETURNS: Success */gn_error serial_changespeed(int fd, int speed, struct gn_statemachine *state){	BOOL  fRetVal;	DCB   dcb;	dcb.DCBlength = sizeof(DCB);	GetCommState(hPhone, &dcb);	dcb.BaudRate = speed;	dcb.ByteSize = 8;	dcb.Parity = NOPARITY;	dcb.StopBits = ONESTOPBIT;	fRetVal = SetCommState(hPhone, &dcb);	if (fRetVal == 0) fRetVal = GetLastError();	return GN_ERR_NONE;}/* Read from serial device. */size_t serial_read(int fd, __ptr_t buf, size_t nbytes, struct gn_statemachine *state){	BOOL    fReadStat;	COMSTAT ComStat;	DWORD   dwErrorFlags;	DWORD   dwLength=0;	DWORD   dwError;	/* only try to read number of bytes in queue */	ClearCommError(hPhone, &dwErrorFlags, &ComStat);	dwLength = min((DWORD) nbytes, ComStat.cbInQue);	if (dwLength > 0) {		fReadStat = ReadFile(hPhone, buf,				     dwLength, &dwLength, &osRead);		if (!fReadStat) {			if (GetLastError() == ERROR_IO_PENDING) {				fprintf(stderr, "\n\rIO Pending");				/* We have to wait for read to complete.				 * This function will timeout according to the				 * CommTimeOuts.ReadTotalTimeoutConstant variable				 * Every time it times out, check for port errors				 */				while (!GetOverlappedResult(hPhone, &osRead, &dwLength, TRUE)) {					dwError = GetLastError();					if (dwError == ERROR_IO_INCOMPLETE) {						/* normal result if not finished */						continue;					} else {						/* an error occurred, try to recover */						ClearCommError(hPhone, &dwErrorFlags, &ComStat);						break;					}				}			} else {				/* some other error occurred */				dwLength = 0;				ClearCommError(hPhone, &dwErrorFlags, &ComStat);			}		}	}	return dwLength;}/* Write to serial device. */size_t serial_write(int fd, __ptr_t buf, size_t n, struct gn_statemachine *state){	BOOL    fWriteStat;	DWORD   dwBytesWritten;	DWORD   dwErrorFlags;	DWORD   dwError;	DWORD   dwBytesSent = 0;	COMSTAT ComStat;	fWriteStat = WriteFile(hPhone, buf, n, &n, &osWrite);	/* Note that normally the code will not execute the following	 * because the driver caches write operations. Small I/O requests	 * (up to several thousand bytes) will normally be accepted	 * immediately and WriteFile will return true even though an	 * overlapped operation was specified	 */	if (!fWriteStat) {		if (GetLastError() == ERROR_IO_PENDING) {			/* We should wait for the completion of the write operation			 * so we know if it worked or not			 *			 * This is only one way to do this. It might be beneficial to			 * place the write operation in a separate thread			 * so that blocking on completion will not negatively			 * affect the responsiveness of the UI			 *			 * If the write takes too long to complete, this			 * function will timeout according to the			 * CommTimeOuts.WriteTotalTimeoutMultiplier variable.			 * This code logs the timeout but does not retry			 * the write.			 */			while (!GetOverlappedResult(hPhone, &osWrite, &dwBytesWritten, TRUE)) {				dwError = GetLastError();				if (dwError == ERROR_IO_INCOMPLETE) {					/* normal result if not finished */					dwBytesSent += dwBytesWritten;					continue;				} else {					/* an error occurred, try to recover */					ClearCommError(hPhone, &dwErrorFlags, &ComStat);					break;				}			}			dwBytesSent += dwBytesWritten;#if 0			if (dwBytesSent != dwBytesToWrite)				fprintf(stderr, "\nProbable Write Timeout: Total of %ld bytes sent (%ld)", dwBytesSent, dwBytesToWrite);			else				fprintf(stderr, "\n%ld bytes written", dwBytesSent);#endif		} else {			/* some other error occurred */			ClearCommError(hPhone, &dwErrorFlags, &ComStat);			return 0;		}	}	return n;}gn_error serial_nreceived(int fd, int *n, struct gn_statemachine *state){	return GN_ERR_NONE;}gn_error serial_flush(int fd, struct gn_statemachine *state){	return GN_ERR_NONE;}

⌨️ 快捷键说明

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