author | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
---|---|---|
committer | zautrix <zautrix> | 2004-08-07 17:24:40 (UTC) |
commit | 88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 (patch) (side-by-side diff) | |
tree | 6331418973714243beb674abc87692277b83869d /gammu/emb/common/device/serial | |
parent | ef8a09ce74ad3f0a51484d03fdf009bd5b3677bf (diff) | |
download | kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.zip kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.gz kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.bz2 |
Initial revision
Diffstat (limited to 'gammu/emb/common/device/serial') (more/less context) (ignore whitespace changes)
-rw-r--r-- | gammu/emb/common/device/serial/ser_djg.c | 74 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_djg.h | 15 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_unx.c | 291 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_unx.h | 22 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_w32.c | 340 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_w32.h | 19 |
6 files changed, 761 insertions, 0 deletions
diff --git a/gammu/emb/common/device/serial/ser_djg.c b/gammu/emb/common/device/serial/ser_djg.c new file mode 100644 index 0000000..ac9d7c8 --- a/dev/null +++ b/gammu/emb/common/device/serial/ser_djg.c @@ -0,0 +1,74 @@ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_SERIALDEVICE +#ifdef DJGPP + +#include "../../gsmcomon.h" +#include "ser_djg.h" + +static GSM_Error serial_close(GSM_StateMachine *s) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + return ERR_NONE; +} + +static GSM_Error serial_open (GSM_StateMachine *s) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + return ERR_NONE; +} + +static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + return ERR_NONE; +} + +static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + return ERR_NONE; +} + +static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + return ERR_NONE; +} + +static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + return 0; +} + +static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + return 0; +} + +GSM_Device_Functions SerialDevice = { + serial_open, + serial_close, + serial_setparity, + serial_setdtrrts, + serial_setspeed, + serial_read, + serial_write +}; + +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/gammu/emb/common/device/serial/ser_djg.h b/gammu/emb/common/device/serial/ser_djg.h new file mode 100644 index 0000000..b35b282 --- a/dev/null +++ b/gammu/emb/common/device/serial/ser_djg.h @@ -0,0 +1,15 @@ + +#ifdef DJGPP +#ifndef djgppserial_h +#define djgppserial_h + +typedef struct { + int hPhone; +} GSM_Device_SerialData; + +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/gammu/emb/common/device/serial/ser_unx.c b/gammu/emb/common/device/serial/ser_unx.c new file mode 100644 index 0000000..2a87b11 --- a/dev/null +++ b/gammu/emb/common/device/serial/ser_unx.c @@ -0,0 +1,291 @@ +/* (c) 2002-2004 by Marcin Wiacek */ +/* locking device and settings all speeds by Michal Cihar */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_SERIALDEVICE +#ifndef WIN32 +#ifndef DJGPP + +#include <sys/file.h> +#include <sys/time.h> +#include <string.h> +#include <termios.h> +#include <errno.h> + +#include "../../gsmcomon.h" +#include "ser_unx.h" + +static GSM_Error serial_close(GSM_StateMachine *s) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + /* Restores old settings */ + tcsetattr(d->hPhone, TCSANOW, &d->old_settings); + + /* Closes device */ + close(d->hPhone); + + return ERR_NONE; +} + +#ifndef O_NONBLOCK +# define O_NONBLOCK 0 +#endif + +static GSM_Error serial_open (GSM_StateMachine *s) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + struct termios t; + int i; + + /* O_NONBLOCK MUST is required to avoid waiting for DCD */ + d->hPhone = open(s->CurrentConfig->Device, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (d->hPhone < 0) { + i = errno; + GSM_OSErrorInfo(s,"open in serial_open"); + if (i == 2) return ERR_DEVICENOTEXIST; //no such file or directory + if (i == 13) return ERR_DEVICENOPERMISSION; //permission denied + return ERR_DEVICEOPENERROR; + } + +#ifdef TIOCEXCL + /* open() calls from other applications shall fail now */ + ioctl(d->hPhone, TIOCEXCL, (char *) 0); +#endif + + if (tcgetattr(d->hPhone, &d->old_settings) == -1) { + close(d->hPhone); + GSM_OSErrorInfo(s,"tcgetattr in serial_open"); + return ERR_DEVICEREADERROR; + } + + if (tcflush(d->hPhone, TCIOFLUSH) == -1) { + serial_close(s); + GSM_OSErrorInfo(s,"tcflush in serial_open"); + return ERR_DEVICEOPENERROR; + } + + memcpy(&t, &d->old_settings, sizeof(struct termios)); + + /* Opening without parity */ + t.c_iflag = IGNPAR; + t.c_oflag = 0; + /* disconnect line, 8 bits, enable receiver, + * ignore modem lines,lower modem line after disconnect + */ + t.c_cflag = B0 | CS8 | CREAD | CLOCAL | HUPCL; + /* enable hardware (RTS/CTS) flow control (NON POSIX) */ + /* t.c_cflag |= CRTSCTS; */ + t.c_lflag = 0; + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + + if (tcsetattr(d->hPhone, TCSANOW, &t) == -1) { + serial_close(s); + GSM_OSErrorInfo(s,"tcsetattr in serial_open"); + return ERR_DEVICEOPENERROR; + } + + /* Making file descriptor asynchronous. */ + if (fcntl(d->hPhone, F_SETFL, FASYNC | FNONBLOCK) == -1) { + serial_close(s); + GSM_OSErrorInfo(s,"fcntl in serial_open"); + return ERR_DEVICEOPENERROR; + } + + return ERR_NONE; +} + +static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + struct termios t; + + if (tcgetattr(d->hPhone, &t)) { + GSM_OSErrorInfo(s,"tcgetattr in serial_setparity"); + return ERR_DEVICEREADERROR; + } + + if (parity) { + t.c_cflag |= (PARENB | PARODD); + t.c_iflag = 0; + } else { + t.c_iflag = IGNPAR; + } + + if (tcsetattr(d->hPhone, TCSANOW, &t) == -1){ + serial_close(s); + GSM_OSErrorInfo(s,"tcsetattr in serial_setparity"); + return ERR_DEVICEPARITYERROR; + } + + return ERR_NONE; +} + +static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + struct termios t; + unsigned int flags; + + if (tcgetattr(d->hPhone, &t)) { + GSM_OSErrorInfo(s,"tcgetattr in serial_setdtrrts"); + return ERR_DEVICEREADERROR; + } + +#ifdef CRTSCTS + /* Disabling hardware flow control */ + t.c_cflag &= ~CRTSCTS; +#endif + + if (tcsetattr(d->hPhone, TCSANOW, &t) == -1) { + serial_close(s); + GSM_OSErrorInfo(s,"tcsetattr in serial_setdtrrts"); + return ERR_DEVICEDTRRTSERROR; + } + + flags = TIOCM_DTR; + if (dtr) { + ioctl(d->hPhone, TIOCMBIS, &flags); + } else { + ioctl(d->hPhone, TIOCMBIC, &flags); + } + + flags = TIOCM_RTS; + if (rts) { + ioctl(d->hPhone, TIOCMBIS, &flags); + } else { + ioctl(d->hPhone, TIOCMBIC, &flags); + } + + flags = 0; + ioctl(d->hPhone, TIOCMGET, &flags); + + dbgprintf("Serial device:"); + dbgprintf(" DTR is %s", flags&TIOCM_DTR?"up":"down"); + dbgprintf(", RTS is %s", flags&TIOCM_RTS?"up":"down"); + dbgprintf(", CAR is %s", flags&TIOCM_CAR?"up":"down"); + dbgprintf(", CTS is %s\n", flags&TIOCM_CTS?"up":"down"); + if (((flags&TIOCM_DTR)==TIOCM_DTR) != dtr) return ERR_DEVICEDTRRTSERROR; + if (((flags&TIOCM_RTS)==TIOCM_RTS) != rts) return ERR_DEVICEDTRRTSERROR; + + return ERR_NONE; +} + +static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + struct termios t; + int speed2 = B19200; + + if (tcgetattr(d->hPhone, &t)) { + GSM_OSErrorInfo(s,"tcgetattr in serial_setspeed"); + return ERR_DEVICEREADERROR; + } + + smprintf(s, "Setting speed to %d\n", speed); + + switch (speed) { + case 50: speed2 = B50; break; + case 75: speed2 = B75; break; + case 110: speed2 = B110; break; + case 134: speed2 = B134; break; + case 150: speed2 = B150; break; + case 200: speed2 = B200; break; + case 300: speed2 = B300; break; + case 600: speed2 = B600; break; + case 1200: speed2 = B1200; break; + case 1800: speed2 = B1800; break; + case 2400: speed2 = B2400; break; + case 4800: speed2 = B4800; break; + case 9600: speed2 = B9600; break; + case 19200: speed2 = B19200; break; + case 38400: speed2 = B38400; break; + case 57600: speed2 = B57600; break; + case 115200: speed2 = B115200; break; + case 230400: speed2 = B230400; break; + case 460800: speed2 = B460800; break; + case 500000: speed2 = B500000; break; + case 576000: speed2 = B576000; break; + case 921600: speed2 = B921600; break; + case 1000000: speed2 = B1000000; break; + case 1152000: speed2 = B1152000; break; + case 1500000: speed2 = B1500000; break; + case 2000000: speed2 = B2000000; break; + case 2500000: speed2 = B2500000; break; + case 3000000: speed2 = B3000000; break; + case 3500000: speed2 = B3500000; break; + case 4000000: speed2 = B4000000; break; + } + + /* This should work on all systems because it is done according to POSIX */ + cfsetispeed(&t, speed2); + cfsetospeed(&t, speed2); + + if (tcsetattr(d->hPhone, TCSADRAIN, &t) == -1) { + serial_close(s); + GSM_OSErrorInfo(s,"tcsetattr in serial_setspeed"); + return ERR_DEVICECHANGESPEEDERROR; + } + + return ERR_NONE; +} + +static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + struct timeval timeout2; + fd_set readfds; + int actual = 0; + + FD_ZERO(&readfds); + FD_SET(d->hPhone, &readfds); + + timeout2.tv_sec = 0; + timeout2.tv_usec = 1; + + if (select(d->hPhone+1, &readfds, NULL, NULL, &timeout2)) { + actual = read(d->hPhone, buf, nbytes); + if (actual == -1) GSM_OSErrorInfo(s,"serial_read"); + } + return actual; +} + +static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + int ret; + size_t actual = 0; + + do { + ret = write(d->hPhone, (unsigned char *)buf, nbytes - actual); + if (ret < 0 && errno == EAGAIN) continue; + if (ret < 0) { + if (actual != nbytes) GSM_OSErrorInfo(s,"serial_write"); + return actual; + } + actual += ret; + buf += ret; + if (s->ConnectionType == GCT_FBUS2PL2303) my_sleep(1); + } while (actual < nbytes); + return actual; +} + +GSM_Device_Functions SerialDevice = { + serial_open, + serial_close, + serial_setparity, + serial_setdtrrts, + serial_setspeed, + serial_read, + serial_write +}; + +#endif +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/gammu/emb/common/device/serial/ser_unx.h b/gammu/emb/common/device/serial/ser_unx.h new file mode 100644 index 0000000..ca8fe5a --- a/dev/null +++ b/gammu/emb/common/device/serial/ser_unx.h @@ -0,0 +1,22 @@ + +#ifndef WIN32 +#ifndef DJGPP +#ifndef unixserial_h +#define unixserial_h + +#include <fcntl.h> +#include <sys/ioctl.h> +#include <termios.h> + +typedef struct { + int hPhone; + struct termios old_settings; +} GSM_Device_SerialData; + +#endif +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/gammu/emb/common/device/serial/ser_w32.c b/gammu/emb/common/device/serial/ser_w32.c new file mode 100644 index 0000000..9fa0135 --- a/dev/null +++ b/gammu/emb/common/device/serial/ser_w32.c @@ -0,0 +1,340 @@ +/* (c) 2002-2004 by Marcin Wiacek */ +/* based on some work from Gnokii, MSDN and others */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_SERIALDEVICE +#ifdef WIN32 + +#include <windows.h> +#include <string.h> +#include <stdio.h> +#include <io.h> +#include <memory.h> + +#include "../../gsmcomon.h" +#include "ser_w32.h" + +static GSM_Error serial_close(GSM_StateMachine *s) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + /* Disables all monitored events for device */ + SetCommMask(d->hPhone, 0); + + /* Discards all characters from input/output buffer and terminates + * pending read/write operations + */ + PurgeComm(d->hPhone, PURGE_TXABORT | PURGE_RXABORT | + PURGE_TXCLEAR | PURGE_RXCLEAR); + + /* Clears the DTR (data-terminal-ready) signal */ + EscapeCommFunction(d->hPhone, CLRDTR); + + /* Restores old settings */ + if (SetCommState(d->hPhone, &d->old_settings)==0) { + GSM_OSErrorInfo(s, "SetCommState in serial_close"); + } + + /* Closes device */ + if (CloseHandle(d->hPhone)==0) { + GSM_OSErrorInfo(s, "CloseHandle in serial_close"); + } + + return ERR_NONE; +} + +static GSM_Error serial_open (GSM_StateMachine *s) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + DCB dcb; + unsigned char DeviceName[80],DeviceName2[80]; + int i; +#ifdef GSM_ENABLE_FBUS2DKU5 + HKEY hKey; + DWORD DeviceNameLen, KeyNameLen; + unsigned char KeyName[100]; +#endif + + strcpy(DeviceName2,s->CurrentConfig->Device); + +#ifdef GSM_ENABLE_FBUS2DKU5 + if (s->ConnectionType == GCT_FBUS2DKU5) { + smprintf(s,"Reading DKU5 device\n"); + DeviceName2[0] = 0; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) { + smprintf(s,"Error opening key\n"); + return ERR_DEVICENOTWORK; + } + i = 0; + while(1) { + DeviceNameLen = 80; + KeyNameLen = 100; + if (RegEnumValue(hKey,i,KeyName,&KeyNameLen,NULL,NULL,DeviceName2,&DeviceNameLen) != ERROR_SUCCESS) { + smprintf(s,"Error reading key value\n"); + return ERR_DEVICENOTWORK; + } +// smprintf(s,"Key name is %s, value is %s\n",KeyName,DeviceName2); + if (!strncmp(KeyName,"\\Device\\AtmelVirtualPort",24)) break; + i++; + } + RegCloseKey(hKey); + if (strlen(DeviceName2) == 0) return ERR_DEVICENOTWORK; + smprintf(s,"DKU5 device is \"%s\"\n",DeviceName2); + //nodriver + } +#endif + + if ((s->ConnectionType == GCT_FBUS2DKU5) || + (!strncmp(DeviceName2,"com",3) && strlen(DeviceName2)>3)) { + sprintf(DeviceName,"\\\\.\\COM%i",atoi(DeviceName2+3)); + } else { + strcpy(DeviceName,DeviceName2); + } + + smprintf(s,"Device is %s\n",DeviceName); + + /* Allows for reading/writing, no device sharing */ + d->hPhone = CreateFile(DeviceName, + GENERIC_READ | GENERIC_WRITE, + 0, + 0, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL); + + if (d->hPhone == INVALID_HANDLE_VALUE) { + i = GetLastError(); + GSM_OSErrorInfo(s, "CreateFile in serial_open"); + if (i == 2) return ERR_DEVICENOTWORK; //can't find specified file + if (i == 5) return ERR_DEVICEBUSY; //access denied + if (i == 31) return ERR_DEVICENOTWORK; //attached device not working + if (i == 123) return ERR_DEVICENOTEXIST; + return ERR_DEVICEOPENERROR; + } + + d->old_settings.DCBlength = sizeof(DCB); + if (GetCommState(d->hPhone, &d->old_settings)==0) { + GSM_OSErrorInfo(s, "ReadDevice in serial_open"); + return ERR_DEVICEREADERROR; + } + + /* When char will be received, we will receive notifications */ + SetCommMask(d->hPhone, EV_RXCHAR); + + /* Sets size for input/output buffer */ + SetupComm(d->hPhone, 4096, 4096); + + /* Discards all characters from input/output buffer and terminates + * pending read/write operations + */ + PurgeComm(d->hPhone, PURGE_TXABORT | PURGE_RXABORT | + PURGE_TXCLEAR | PURGE_RXCLEAR); + + memcpy(&dcb, &d->old_settings, sizeof(DCB)); + + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + + /* No Xon/Xof flow control */ +// dcb.fOutX = false; +// dcb.fInX = false; + + /* Hardware flow control */ +// dcb.fOutxDsrFlow = true; +// dcb.fOutxCtsFlow = true; +// dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; +// dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + + /* Initialise the port settings */ + if (SetCommState(d->hPhone, &dcb)==0) { + GSM_OSErrorInfo(s, "WriteDevice in serial_open"); + return ERR_DEVICEOPENERROR; + } + + return ERR_NONE; +} + +static GSM_Error serial_setparity (GSM_StateMachine *s, bool parity) +{ + DCB dcb; + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + dcb.DCBlength = sizeof(DCB); + if (GetCommState(d->hPhone, &dcb)==0) { + GSM_OSErrorInfo(s, "ReadDevice in serial_setparity"); + return ERR_DEVICEREADERROR; + } + + if (parity) { + dcb.Parity = ODDPARITY; + } else { + dcb.Parity = NOPARITY; + } + + if (SetCommState(d->hPhone, &dcb)==0) { + GSM_OSErrorInfo(s, "WriteDevice in serial_setparity"); + return ERR_DEVICEPARITYERROR; + } + + return ERR_NONE; +} + +static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) +{ + DCB dcb; + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + dcb.DCBlength = sizeof(DCB); + if (GetCommState(d->hPhone, &dcb)==0) { + GSM_OSErrorInfo(s, "ReadDevice in serial_setdtrrts"); + return ERR_DEVICEREADERROR; + } + + dcb.fOutxDsrFlow = 0; + dcb.fDtrControl = DTR_CONTROL_DISABLE; + if (dtr) dcb.fDtrControl = DTR_CONTROL_ENABLE; + + dcb.fOutxCtsFlow = 0; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + if (rts) dcb.fRtsControl = RTS_CONTROL_ENABLE; + + /* no software (Xon/Xof) flow control */ + dcb.fInX = dcb.fOutX = 0; + + if (SetCommState(d->hPhone, &dcb)==0) { + GSM_OSErrorInfo(s, "WriteDevice in serial_setdtrrts"); + return ERR_DEVICEDTRRTSERROR; + } + + /* the rest of function checks, if setting was really done */ + + dcb.DCBlength = sizeof(DCB); + GetCommState(d->hPhone, &dcb); + + dbgprintf("Serial device:"); + dbgprintf(" DTR is "); + switch (dcb.fDtrControl) { + case DTR_CONTROL_ENABLE : dbgprintf("up"); break; + case DTR_CONTROL_DISABLE : dbgprintf("down"); break; + case DTR_CONTROL_HANDSHAKE : dbgprintf("handshake"); break; + } + dbgprintf(", RTS is "); + switch (dcb.fRtsControl) { + case RTS_CONTROL_ENABLE : dbgprintf("up"); break; + case RTS_CONTROL_DISABLE : dbgprintf("down"); break; + case RTS_CONTROL_HANDSHAKE : dbgprintf("handshake"); break; + case RTS_CONTROL_TOGGLE : dbgprintf("toggle"); break; + } + dbgprintf("\n"); + if ( dtr && dcb.fDtrControl != DTR_CONTROL_ENABLE ) return ERR_DEVICEDTRRTSERROR; + if (!dtr && dcb.fDtrControl != DTR_CONTROL_DISABLE) return ERR_DEVICEDTRRTSERROR; + if ( rts && dcb.fRtsControl != RTS_CONTROL_ENABLE ) return ERR_DEVICEDTRRTSERROR; + if (!rts && dcb.fRtsControl != RTS_CONTROL_DISABLE) return ERR_DEVICEDTRRTSERROR; + + return ERR_NONE; +} + +static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) +{ + DCB dcb; + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + dcb.DCBlength = sizeof(DCB); + if (GetCommState(d->hPhone, &dcb)==0) { + GSM_OSErrorInfo(s, "ReadDevice in serial_setspeed"); + return ERR_DEVICEREADERROR; + } + + dcb.BaudRate = speed; + + if (SetCommState(d->hPhone, &dcb)==0) { + GSM_OSErrorInfo(s, "WriteDevice in serial_setspeed"); + return ERR_DEVICECHANGESPEEDERROR; + } + + return ERR_NONE; +} + +static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) +{ + COMSTAT ComStat; + DWORD ErrorFlags, Length; + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + /* Gets information about a communications error and + * current status of device + */ + ClearCommError(d->hPhone, &ErrorFlags, &ComStat); + Length = ComStat.cbInQue; + + /* Nothing to read */ + if (Length <= 0) return Length; + + /* Read without problems */ + if (ReadFile(d->hPhone, buf, Length, &Length, &d->osRead)) return Length; + + if (GetLastError() != ERROR_IO_PENDING) { + GSM_OSErrorInfo(s, "serial_read1"); + Length = 0; + ClearCommError(d->hPhone, &ErrorFlags, &ComStat); + return Length; + } + + while(1) { + if (GetOverlappedResult(d->hPhone,&d->osRead, &Length, TRUE)) break; + if (GetLastError() != ERROR_IO_INCOMPLETE) { + GSM_OSErrorInfo(s, "serial_read2"); + /* an error occurred, try to recover */ + ClearCommError(d->hPhone, &ErrorFlags, &ComStat); + break; + } + } + return Length; +} + +static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) +{ + DWORD BytesWritten,ErrorFlags,BytesSent=0; + COMSTAT ComStat; + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + if (WriteFile(d->hPhone, buf, nbytes, &BytesSent, &d->osWrite)) return BytesSent; + + if (GetLastError() != ERROR_IO_PENDING) { + GSM_OSErrorInfo(s, "serial_write1"); + ClearCommError(d->hPhone, &ErrorFlags, &ComStat); + return BytesSent; + } + + while (1) { + if (GetOverlappedResult(d->hPhone, &d->osWrite, &BytesWritten, TRUE)) break; + if (GetLastError() != ERROR_IO_INCOMPLETE) { + GSM_OSErrorInfo(s, "serial_write2"); + ClearCommError(d->hPhone, &ErrorFlags, &ComStat); + break; + } + BytesSent += BytesWritten; + } + BytesSent += BytesWritten; + + return BytesSent; +} + +GSM_Device_Functions SerialDevice = { + serial_open, + serial_close, + serial_setparity, + serial_setdtrrts, + serial_setspeed, + serial_read, + serial_write +}; + +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/gammu/emb/common/device/serial/ser_w32.h b/gammu/emb/common/device/serial/ser_w32.h new file mode 100644 index 0000000..d226f32 --- a/dev/null +++ b/gammu/emb/common/device/serial/ser_w32.h @@ -0,0 +1,19 @@ + +#ifdef WIN32 +#ifndef winserial_h +#define winserial_h + +#include <windows.h> + +typedef struct { + HANDLE hPhone; + DCB old_settings; + OVERLAPPED osWrite,osRead; +} GSM_Device_SerialData; + +#endif +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ |