-rw-r--r-- | gammu/emb/common/device/bluetoth/bluez.c | 29 | ||||
-rw-r--r-- | gammu/emb/common/device/devfunc.c | 12 | ||||
-rw-r--r-- | gammu/emb/common/device/irda/irda.c | 8 | ||||
-rw-r--r-- | gammu/emb/common/device/irda/irda_unx.h | 2 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_djg.c | 10 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_unx.c | 38 | ||||
-rw-r--r-- | gammu/emb/common/device/serial/ser_w32.c | 6 |
7 files changed, 79 insertions, 26 deletions
diff --git a/gammu/emb/common/device/bluetoth/bluez.c b/gammu/emb/common/device/bluetoth/bluez.c index 8a4807e..e7e8adf 100644 --- a/gammu/emb/common/device/bluetoth/bluez.c +++ b/gammu/emb/common/device/bluetoth/bluez.c @@ -1,207 +1,216 @@ -/* Based on work by Marcel Holtmann and other authors of Bluez */ +/* Based on some work from Bluez (www.bluez.org) + * (C) 2000-2001 Qualcomm Incorporated + * (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> + * (C) 2002-2004 Marcel Holtmann <marcel@holtmann.org> + * GNU GPL version 2 + */ +/* based on some Marcel Holtmann work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_BLUETOOTHDEVICE #ifdef GSM_ENABLE_BLUEZ #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <sys/socket.h> #include <sys/time.h> #include <unistd.h> #include <bluetooth/bluetooth.h> #include <bluetooth/rfcomm.h> #include <bluetooth/sdp.h> #include <bluetooth/sdp_lib.h> #include "../../gsmcomon.h" #include "../devfunc.h" #include "bluetoth.h" GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device) { GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth; struct sockaddr_rc laddr, raddr; bdaddr_t bdaddr; int fd; smprintf(s, "Connecting to RF channel %i\n",port); fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); if (fd < 0) { dbgprintf("Can't create socket\n"); return ERR_DEVICENODRIVER; } bacpy(&laddr.rc_bdaddr, BDADDR_ANY); laddr.rc_family = AF_BLUETOOTH; laddr.rc_channel = 0; if (bind(fd, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { dbgprintf("Can't bind socket\n"); close(fd); return ERR_DEVICEOPENERROR; } str2ba(device, &bdaddr); bacpy(&raddr.rc_bdaddr, &bdaddr); raddr.rc_family = AF_BLUETOOTH; raddr.rc_channel = port; if (connect(fd, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) { dbgprintf("Can't connect\n"); close(fd); return ERR_DEVICEOPENERROR; } d->hPhone = fd; return ERR_NONE; } #ifdef BLUETOOTH_RF_SEARCHING struct search_context { char *svc; uuid_t group; int tree; uint32_t handle; }; static void print_service_desc(void *value, void *user) { sdp_data_t *p = (sdp_data_t *)value; int i = 0, proto = 0, *channel = (int *)user; for (; p; p = p->next, i++) { switch (p->dtd) { case SDP_UUID16: case SDP_UUID32: case SDP_UUID128: - proto = 1;//sdp_uuid_to_proto(&p->val.uuid); + proto = sdp_uuid_to_proto(&p->val.uuid); break; case SDP_UINT8: if (proto == RFCOMM_UUID) { (*channel) = p->val.uint8; return; } break; } } } void print_access_protos(value, user) { sdp_list_t *protDescSeq = (sdp_list_t *)value; int *channel = (int *)user; sdp_list_foreach(protDescSeq,print_service_desc,channel); } static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, bdaddr_t *bdaddr, struct search_context *context) { sdp_session_t *sess; - sdp_list_t *attrid, *search, *seq, *next, *proto = 0; - uint32_t range = 0x0000ffff; - char str[20]; sdp_record_t *rec; + sdp_list_t *attrid, *search, *seq, *next, *proto = 0; sdp_data_t *d; bdaddr_t interface; + uint32_t range = 0x0000ffff; struct search_context subcontext; + char str[20]; int channel,channel2; bacpy(&interface,BDADDR_ANY); ba2str(bdaddr, str); smprintf(s,"%s\n", str); sess = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY); if (!sess) { dbgprintf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno)); return ERR_UNKNOWN; } attrid = sdp_list_append(0, &range); search = sdp_list_append(0, &context->group); if (sdp_service_search_attr_req(sess, search, SDP_ATTR_REQ_RANGE, attrid, &seq)) { dbgprintf("Service Search failed: %s\n", strerror(errno)); sdp_close(sess); return ERR_UNKNOWN; } sdp_list_free(attrid, 0); sdp_list_free(search, 0); channel2 = -1; for (; seq; seq = next) { rec = (sdp_record_t *) seq->data; if (channel2 == -1) { if (!context->tree) { d = sdp_data_get(rec,SDP_ATTR_SVCNAME_PRIMARY); - if (false) { + if (sdp_get_access_protos(rec,&proto) == 0) { channel = -1; sdp_list_foreach(proto,print_access_protos,&channel); - //sdp_list_free(proto,(sdp_free_func_t)sdp_data_free); + sdp_list_free(proto,(sdp_free_func_t)sdp_data_free); } smprintf(s,"Channel %i",channel); if (d) smprintf(s," - \"%s\"",d->val.str); smprintf(s,"\n"); if (channel2 == -1 && bluetooth_checkservicename(s, d->val.str) == ERR_NONE) { channel2 = channel; } } if (sdp_get_group_id(rec,&subcontext.group) != -1) { memcpy(&subcontext, context, sizeof(struct search_context)); if (subcontext.group.value.uuid16 != context->group.value.uuid16) bluetooth_checkdevice(s,bdaddr,&subcontext); } } next = seq->next; free(seq); - //sdp_record_free(rec); + sdp_record_free(rec); } sdp_close(sess); if (channel2 != -1) return bluetooth_connect(s, channel2, str); - return ERR_UNKNOWN; + return ERR_NOTSUPPORTED; } GSM_Error bluetooth_findchannel(GSM_StateMachine *s) { inquiry_info ii[20]; uint8_t count = 0; int i; struct search_context context; GSM_Error error = ERR_NOTSUPPORTED; memset(&context, '\0', sizeof(struct search_context)); - //sdp_uuid16_create(&(context.group),PUBLIC_BROWSE_GROUP); + sdp_uuid16_create(&(context.group),PUBLIC_BROWSE_GROUP); if (!strcmp(s->CurrentConfig->Device,"/dev/ttyS1")) { dbgprintf("Searching for devices\n"); if (sdp_general_inquiry(ii, 20, 8, &count) < 0) { return ERR_UNKNOWN; } } else { count = 1; str2ba(s->CurrentConfig->Device,&ii[0].bdaddr); } for (i=0;i<count;i++) { error = bluetooth_checkdevice(s,&ii[i].bdaddr,&context); if (error == ERR_NONE) return error; } return error; } #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/devfunc.c b/gammu/emb/common/device/devfunc.c index d31ebbf..c58a01f 100644 --- a/gammu/emb/common/device/devfunc.c +++ b/gammu/emb/common/device/devfunc.c @@ -1,266 +1,274 @@ +/* Some source from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ +/* Some source from Minicom (http://alioth.debian.org/projects/minicom) + * (C) 1991,1992,1993,1994,1995,1996 by Miquel van Smoorenburg + * GNU GPL version 2 + */ #include <string.h> #ifdef WIN32 # include <io.h> #else # include <errno.h> # include <signal.h> #endif #include "../gsmstate.h" #ifdef GSM_ENABLE_BLUETOOTHDEVICE #ifdef BLUETOOTH_RF_SEARCHING GSM_Error bluetooth_checkservicename(GSM_StateMachine *s, char *name) { if (s->ConnectionType == GCT_BLUEPHONET && strstr(name,"Nokia PC Suite")!=NULL) return ERR_NONE; if (s->ConnectionType == GCT_BLUEOBEX && strstr(name,"OBEX") !=NULL) return ERR_NONE; if (s->ConnectionType == GCT_BLUEAT && strstr(name,"COM 1") !=NULL) return ERR_NONE; return ERR_UNKNOWN; } #endif #endif #if defined (GSM_ENABLE_BLUETOOTHDEVICE) || defined (GSM_ENABLE_IRDADEVICE) int socket_read(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone) { fd_set readfds; #ifdef WIN32 struct timeval timer; #endif FD_ZERO(&readfds); FD_SET(hPhone, &readfds); #ifndef WIN32 if (select(hPhone+1, &readfds, NULL, NULL, 0)) { return(read(hPhone, buf, nbytes)); } #else memset(&timer,0,sizeof(timer)); if (select(0, &readfds, NULL, NULL, &timer) != 0) { return(recv(hPhone, buf, nbytes, 0)); } #endif return 0; } #ifdef WIN32 int socket_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes, int hPhone) #else int socket_write(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone) #endif { int ret; size_t actual = 0; do { ret = send(hPhone, buf, nbytes - actual, 0); if (ret < 0) { if (actual != nbytes) GSM_OSErrorInfo(s,"socket_write"); return actual; } actual += ret; buf += ret; } while (actual < nbytes); return actual; } GSM_Error socket_close(GSM_StateMachine *s, int hPhone) { shutdown(hPhone, 0); #ifdef WIN32 closesocket(hPhone); /*FIXME: error checking */ #else close(hPhone); /*FIXME: error checking */ #endif return ERR_NONE; } #endif #ifdef ENABLE_LGPL GSM_Error lock_device(const char* port, char **lock_device) { *lock_device = 0; return ERR_NONE; } bool unlock_device(char **lock_file) { return true; } #else #define max_buf_len 128 #define lock_path "/var/lock/LCK.." /* Lock the device. Allocated string with a lock name is returned * in lock_device */ GSM_Error lock_device(const char* port, char **lock_device) { -#ifndef WIN32 +#if !defined(WIN32) && !defined(DJGPP) char *lock_file = NULL; char buffer[max_buf_len]; const char *aux; int fd, len; GSM_Error error = ERR_NONE; dbgprintf("Locking device\n"); aux = strrchr(port, '/'); /* Remove leading '/' */ if (aux) { aux++; } else { /* No / in port */ aux = port; } len = strlen(aux) + strlen(lock_path); memset(buffer, 0, sizeof(buffer)); lock_file = calloc(len + 1, 1); if (!lock_file) { dbgprintf("Out of memory error while locking device\n"); return ERR_MOREMEMORY; } /* I think we don't need to use strncpy, as we should have enough * buffer due to strlen results */ strcpy(lock_file, lock_path); strcat(lock_file, aux); /* Check for the stale lockfile. * The code taken from minicom by Miquel van Smoorenburg */ if ((fd = open(lock_file, O_RDONLY)) >= 0) { char buf[max_buf_len]; int pid, n = 0; n = read(fd, buf, sizeof(buf) - 1); close(fd); if (n > 0) { pid = -1; if (n == 4) /* Kermit-style lockfile. */ pid = *(int *)buf; else { /* Ascii lockfile. */ buf[n] = 0; sscanf(buf, "%d", &pid); } if (pid > 0 && kill((pid_t)pid, 0) < 0 && errno == ESRCH) { dbgprintf("Lockfile %s is stale. Overriding it..\n", lock_file); sleep(1); if (unlink(lock_file) == -1) { dbgprintf("Overriding failed, please check the permissions\n"); dbgprintf("Cannot lock device\n"); error = ERR_PERMISSION; goto failed; } } else { dbgprintf("Device already locked by PID %d.\n", pid); error = ERR_DEVICELOCKED; goto failed; } } /* this must not happen. because we could open the file */ /* no wrong permissions are set. only reason could be */ /* flock/lockf or a empty lockfile due to a broken binary */ /* which is more likely */ if (n == 0) { dbgprintf("Unable to read lockfile %s.\n", lock_file); dbgprintf("Please check for reason and remove the lockfile by hand.\n"); dbgprintf("Cannot lock device\n"); error = ERR_UNKNOWN; goto failed; } } /* Try to create a new file, with 0644 mode */ fd = open(lock_file, O_CREAT | O_EXCL | O_WRONLY, 0644); if (fd == -1) { if (errno == EEXIST) { dbgprintf("Device seems to be locked by unknown process\n"); error = ERR_DEVICEOPENERROR; } else if (errno == EACCES) { dbgprintf("Please check permission on lock directory\n"); error = ERR_PERMISSION; } else if (errno == ENOENT) { dbgprintf("Cannot create lockfile %s. Please check for existence of path\n", lock_file); error = ERR_UNKNOWN; } else { dbgprintf("Unknown error with creating lockfile %s\n", lock_file); error = ERR_UNKNOWN; } goto failed; } sprintf(buffer, "%10ld gammu\n", (long)getpid()); write(fd, buffer, strlen(buffer)); close(fd); *lock_device = lock_file; return ERR_NONE; failed: free(lock_file); *lock_device = 0; return error; #else *lock_device = 0; return ERR_NONE; #endif } /* Removes lock and frees memory */ bool unlock_device(char **lock_file) { -#ifndef WIN32 +#if !defined(WIN32) && !defined(DJGPP) int err; if (!lock_file) { dbgprintf("Cannot unlock device\n"); return false; } err = unlink(*lock_file); free(*lock_file); *lock_file = NULL; return (err + 1); #else return true; #endif } #endif int FindSerialSpeed(char *buffer) { switch (atoi(buffer)) { case 50 : return 50; case 75 : return 75; case 110 : return 110; case 134 : return 134; case 150 : return 150; case 200 : return 200; case 300 : return 300; case 600 : return 600; case 1200 : return 1200; case 1800 : return 1800; case 2400 : return 2400; case 4800 : return 4800; case 9600 : return 9600; case 19200 : return 19200; case 38400 : return 38400; case 57600 : return 57600; case 115200 : return 115200; case 230400 : return 230400; default : return 0; } } /* 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/irda/irda.c b/gammu/emb/common/device/irda/irda.c index fef50ac..e680377 100644 --- a/gammu/emb/common/device/irda/irda.c +++ b/gammu/emb/common/device/irda/irda.c @@ -1,99 +1,103 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Ralf Thelen and MyGnokii */ -/* based on some work from Gnokii and MSDN */ +/* based on some work from Ralf Thelen and MyGnokii (www.mwiacek.com) */ +/* based on some work from MSDN */ +/* based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ /* You have to include wsock32.lib library to MS VC project to compile it */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_IRDADEVICE #ifndef DJGPP #ifndef WIN32 # include <stdlib.h> # include <unistd.h> # include <stdio.h> # include <fcntl.h> # include <errno.h> # include <string.h> # include <sys/time.h> # include <sys/poll.h> # include <sys/socket.h> # include <sys/ioctl.h> #else # include <windows.h> # include <io.h> #endif #include "../../gsmcomon.h" #include "../devfunc.h" #include "irda.h" static bool irda_discover_device(GSM_StateMachine *state) { GSM_Device_IrdaData *d = &state->Device.Data.Irda; struct irda_device_list *list; unsigned char *buf; unsigned int sec; int s, z, len, fd, i; GSM_DateTime Date; bool founddevice = false; #ifdef WIN32 int index; #endif fd = socket(AF_IRDA, SOCK_STREAM, 0); /* can handle maximally 10 devices during discovering */ len = sizeof(struct irda_device_list) + sizeof(struct irda_device_info) * 10; buf = malloc(len); list = (struct irda_device_list *)buf; /* Trying to find device during 2 seconds */ for (z=0;z<2;z++) { GSM_GetCurrentDateTime (&Date); sec = Date.Second; while (sec==Date.Second) { s = len; memset(buf, 0, s); if (getsockopt(fd, SOL_IRLMP, IRLMP_ENUMDEVICES, buf, &s) == 0) { for (i = 0; i < (int)list->numDevice; i++) { dbgprintf("Irda: found device \"%s\" (address %x) - ",list->Device[i].irdaDeviceName,list->Device[i].irdaDeviceID); if (strcmp(GetModelData(NULL,NULL,list->Device[i].irdaDeviceName)->number,"") != 0) { founddevice = true; /* Model AUTO */ if (state->CurrentConfig->Model[0]==0) strcpy(state->Phone.Data.Model,GetModelData(NULL,NULL,list->Device[i].irdaDeviceName)->number); state->Phone.Data.ModelInfo = GetModelData(NULL,state->Phone.Data.Model,NULL); } if (founddevice) { dbgprintf("correct\n"); #ifdef WIN32 for(index=0; index <= 3; index++) d->peer.irdaDeviceID[index] = list->Device[i].irdaDeviceID[index]; #else d->peer.irdaDeviceID = list->Device[i].irdaDeviceID; #endif break; } dbgprintf("\n"); } } if (founddevice) break; my_sleep(10); GSM_GetCurrentDateTime(&Date); } if (founddevice) break; } free(buf); close(fd); return founddevice; } static GSM_Error irda_open (GSM_StateMachine *s) { GSM_Device_IrdaData *d = &s->Device.Data.Irda; int fd = -1; #ifdef WIN32 int Enable9WireMode = 1; diff --git a/gammu/emb/common/device/irda/irda_unx.h b/gammu/emb/common/device/irda/irda_unx.h index 8dbcb97..7a55273 100644 --- a/gammu/emb/common/device/irda/irda_unx.h +++ b/gammu/emb/common/device/irda/irda_unx.h @@ -1,61 +1,61 @@ -/* part of irda.h available in Linux kernel source */ +/* part of irda.h available in Linux kernel source (www.kernel.org) */ /********************************************************************* * * Filename: irda.h * Version: * Description: * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Mar 8 14:06:12 1999 * Modified at: Sat Dec 25 16:06:42 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. * * This program 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. * * Neither Dag Brattli nor University of Tromsų admit liability nor * provide warranty for any of this software. This material is * provided "AS-IS" and at no charge. * ********************************************************************/ #ifndef __irda_unx_h #define __irda_unx_h #include <sys/types.h> #include <sys/socket.h> #define SOL_IRLMP 266 /* Same as SOL_IRDA for now */ #define IRLMP_ENUMDEVICES 1 /* Return discovery log */ #define LSAP_ANY 0xff struct sockaddr_irda { sa_family_t irdaAddressFamily; /* AF_IRDA */ u_int8_t sir_lsap_sel; /* LSAP selector */ u_int32_t irdaDeviceID; /* Device address */ char irdaServiceName[25]; /* Usually <service>:IrDA:TinyTP */ }; struct irda_device_info { u_int32_t saddr; /* Address of local interface */ u_int32_t irdaDeviceID; /* Address of remote device */ char irdaDeviceName[22]; /* Description */ u_int8_t charset; /* Charset used for description */ u_int8_t hints[2]; /* Hint bits */ }; struct irda_device_list { u_int32_t numDevice; struct irda_device_info Device[1]; }; #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.c b/gammu/emb/common/device/serial/ser_djg.c index ac9d7c8..2524187 100644 --- a/gammu/emb/common/device/serial/ser_djg.c +++ b/gammu/emb/common/device/serial/ser_djg.c @@ -1,74 +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; + return ERR_NOTIMPLEMENTED; } static GSM_Error serial_open (GSM_StateMachine *s) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NONE; + return ERR_NOTIMPLEMENTED; } static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NONE; + return ERR_NOTIMPLEMENTED; } static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NONE; + return ERR_NOTIMPLEMENTED; } static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NONE; + return ERR_NOTIMPLEMENTED; } 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_unx.c b/gammu/emb/common/device/serial/ser_unx.c index 2a87b11..69c7515 100644 --- a/gammu/emb/common/device/serial/ser_unx.c +++ b/gammu/emb/common/device/serial/ser_unx.c @@ -1,291 +1,319 @@ /* (c) 2002-2004 by Marcin Wiacek */ /* locking device and settings all speeds by Michal Cihar */ +/* based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #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" +#ifndef O_NONBLOCK +# define O_NONBLOCK 0 +#endif + +#ifdef __NetBSD__ +# define FNONBLOCK O_NONBLOCK + +# define B57600 0010001 +# define B115200 0010002 +# define B230400 0010003 +# define B460800 0010004 +# define B500000 0010005 +# define B576000 0010006 +# define B921600 0010007 +# define B1000000 0010010 +# define B1152000 0010011 +# define B1500000 0010012 +# define B2000000 0010013 +# define B2500000 0010014 +# define B3000000 0010015 +# define B3500000 0010016 +# define B4000000 0010017 +#endif + 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; + 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; +#ifdef B57600 case 57600: speed2 = B57600; break; case 115200: speed2 = B115200; break; case 230400: speed2 = B230400; break; case 460800: speed2 = B460800; break; +#ifdef B500000 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; +#endif +#endif } /* 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_w32.c b/gammu/emb/common/device/serial/ser_w32.c index 9fa0135..7d88fc7 100644 --- a/gammu/emb/common/device/serial/ser_w32.c +++ b/gammu/emb/common/device/serial/ser_w32.c @@ -1,98 +1,102 @@ /* (c) 2002-2004 by Marcin Wiacek */ -/* based on some work from Gnokii, MSDN and others */ +/* based on some work from MSDN and others */ +/* based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #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, |