summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/device
Side-by-side diff
Diffstat (limited to 'gammu/emb/common/device') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/device/bluetoth/bluez.c29
-rw-r--r--gammu/emb/common/device/devfunc.c12
-rw-r--r--gammu/emb/common/device/irda/irda.c8
-rw-r--r--gammu/emb/common/device/irda/irda_unx.h2
-rw-r--r--gammu/emb/common/device/serial/ser_djg.c10
-rw-r--r--gammu/emb/common/device/serial/ser_unx.c38
-rw-r--r--gammu/emb/common/device/serial/ser_w32.c6
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,