summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/device
authorzautrix <zautrix>2004-08-07 17:24:40 (UTC)
committer zautrix <zautrix>2004-08-07 17:24:40 (UTC)
commit88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 (patch) (side-by-side diff)
tree6331418973714243beb674abc87692277b83869d /gammu/emb/common/device
parentef8a09ce74ad3f0a51484d03fdf009bd5b3677bf (diff)
downloadkdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.zip
kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.gz
kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.bz2
Initial revision
Diffstat (limited to 'gammu/emb/common/device') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/device/bluetoth/affix.c44
-rw-r--r--gammu/emb/common/device/bluetoth/affix.h3
-rw-r--r--gammu/emb/common/device/bluetoth/blue_w32.c216
-rw-r--r--gammu/emb/common/device/bluetoth/blue_w32.h188
-rw-r--r--gammu/emb/common/device/bluetoth/bluetoth.c85
-rw-r--r--gammu/emb/common/device/bluetoth/bluetoth.h15
-rw-r--r--gammu/emb/common/device/bluetoth/bluez.c207
-rw-r--r--gammu/emb/common/device/bluetoth/bluez.h3
-rw-r--r--gammu/emb/common/device/devfunc.c266
-rw-r--r--gammu/emb/common/device/devfunc.h38
-rw-r--r--gammu/emb/common/device/irda/irda.c187
-rw-r--r--gammu/emb/common/device/irda/irda.h22
-rw-r--r--gammu/emb/common/device/irda/irda_unx.h61
-rw-r--r--gammu/emb/common/device/irda/irda_w32.h35
-rw-r--r--gammu/emb/common/device/serial/ser_djg.c74
-rw-r--r--gammu/emb/common/device/serial/ser_djg.h15
-rw-r--r--gammu/emb/common/device/serial/ser_unx.c291
-rw-r--r--gammu/emb/common/device/serial/ser_unx.h22
-rw-r--r--gammu/emb/common/device/serial/ser_w32.c340
-rw-r--r--gammu/emb/common/device/serial/ser_w32.h19
20 files changed, 2131 insertions, 0 deletions
diff --git a/gammu/emb/common/device/bluetoth/affix.c b/gammu/emb/common/device/bluetoth/affix.c
new file mode 100644
index 0000000..30a917b
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/affix.c
@@ -0,0 +1,44 @@
+/* (c) 2004 by Marcin Wiacek */
+
+#include "../../gsmstate.h"
+
+#ifdef GSM_ENABLE_BLUETOOTHDEVICE
+#ifdef GSM_ENABLE_AFFIX
+
+#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 "../../gsmcomon.h"
+#include "../devfunc.h"
+#include "bluetoth.h"
+
+GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device)
+{
+ d->hPhone = fd;
+ return ERR_NONE;
+}
+
+#ifdef BLUETOOTH_RF_SEARCHING
+
+static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, bdaddr_t *bdaddr, struct search_context *context)
+{
+}
+
+GSM_Error bluetooth_findchannel(GSM_StateMachine *s)
+{
+ 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/bluetoth/affix.h b/gammu/emb/common/device/bluetoth/affix.h
new file mode 100644
index 0000000..896ecbe
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/affix.h
@@ -0,0 +1,3 @@
+
+GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device);
+GSM_Error bluetooth_findchannel(GSM_StateMachine *s);
diff --git a/gammu/emb/common/device/bluetoth/blue_w32.c b/gammu/emb/common/device/bluetoth/blue_w32.c
new file mode 100644
index 0000000..a631c9f
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/blue_w32.c
@@ -0,0 +1,216 @@
+/* (c) 2003-2004 by Marcin Wiacek and Intra */
+
+#include "../../gsmstate.h"
+
+#ifdef GSM_ENABLE_BLUETOOTHDEVICE
+#ifdef WIN32
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <windows.h>
+#include <io.h>
+
+#include "../../misc/coding/coding.h"
+#include "../../gsmcomon.h"
+#include "../devfunc.h"
+#include "bluetoth.h"
+#include "blue_w32.h"
+
+GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device)
+{
+ GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth;
+ WSADATA wsaData;
+ SOCKADDR_BTH sab;
+ int i;
+
+ smprintf(s, "Connecting to RF channel %i\n",port);
+
+ WSAStartup(MAKEWORD(1,1), &wsaData);
+
+ d->hPhone = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
+ if (d->hPhone == INVALID_SOCKET) {
+ i = GetLastError();
+ GSM_OSErrorInfo(s, "Socket in bluetooth_open");
+ if (i == 10041) return ERR_DEVICENODRIVER;//unknown socket type
+ return ERR_UNKNOWN;
+ }
+
+ memset (&sab, 0, sizeof(sab));
+ sab.port = port;
+ sab.addressFamily = AF_BTH;
+ sab.btAddr = 0;
+ for (i=0;i<(int)strlen(device);i++) {
+ if (device[i] >='0' && device[i] <='9') {
+ sab.btAddr = sab.btAddr * 16;
+ sab.btAddr = sab.btAddr + (device[i]-'0');
+ }
+ if (device[i] >='a' && device[i] <='f') {
+ sab.btAddr = sab.btAddr * 16;
+ sab.btAddr = sab.btAddr + (device[i]-'a'+10);
+ }
+ if (device[i] >='A' && device[i] <='F') {
+ sab.btAddr = sab.btAddr * 16;
+ sab.btAddr = sab.btAddr + (device[i]-'A'+10);
+ }
+ }
+ dbgprintf("Remote Bluetooth device is %04x%08x\n",
+ GET_NAP(sab.btAddr), GET_SAP(sab.btAddr));
+
+ if (connect (d->hPhone, (struct sockaddr *)&sab, sizeof(sab)) != 0) {
+ i = GetLastError();
+ GSM_OSErrorInfo(s, "Connect in bluetooth_open");
+ if (i == 10060) return ERR_TIMEOUT; //remote device failed to respond
+ if (i == 10050) return ERR_DEVICENOTWORK; //socket operation connected with dead network
+ //noauth
+ close(d->hPhone);
+ return ERR_UNKNOWN;
+ }
+
+ return ERR_NONE;
+}
+
+#ifdef BLUETOOTH_RF_SEARCHING
+
+#pragma comment(lib, "irprops.lib")
+#pragma comment(lib, "ws2_32.lib")
+
+static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, char *address, WSAPROTOCOL_INFO *protocolInfo)
+{
+ GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth;
+ WSAQUERYSET querySet;
+ DWORD flags;
+ GUID protocol;
+ int i, result;
+ BYTE buffer[2000];
+ char addressAsString[1000];
+ DWORD bufferLength, addressSize;
+ WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
+ HANDLE handle;
+ GSM_Error error;
+
+ memset(&querySet, 0, sizeof(querySet));
+ querySet.dwSize = sizeof(querySet);
+ protocol = L2CAP_PROTOCOL_UUID;
+ querySet.lpServiceClassId = &protocol;
+ querySet.dwNameSpace = NS_BTH;
+ querySet.lpszContext = address;
+
+ flags = LUP_FLUSHCACHE | LUP_RETURN_NAME |
+ LUP_RETURN_TYPE | LUP_RETURN_ADDR |
+ LUP_RETURN_BLOB | LUP_RETURN_COMMENT;
+
+ result = WSALookupServiceBegin(&querySet, flags, &handle);
+ if (result != 0) return ERR_UNKNOWN;
+
+ bufferLength = sizeof(buffer);
+ while (1) {
+ result = WSALookupServiceNext(handle, flags, &bufferLength, pResults);
+ if (result != 0) break;
+ addressSize = sizeof(addressAsString);
+ addressAsString[0] = 0;
+ if (WSAAddressToString(pResults->lpcsaBuffer->RemoteAddr.lpSockaddr,
+ pResults->lpcsaBuffer->RemoteAddr.iSockaddrLength, protocolInfo,
+ addressAsString,&addressSize)==0) {
+ smprintf(s, "%s - ", addressAsString);
+ }
+ smprintf(s, "\"%s\"\n", pResults->lpszServiceInstanceName);
+ if (addressAsString[0] != 0) {
+ for (i=strlen(addressAsString)-1;i>0;i--) {
+ if (addressAsString[i] == ':') break;
+ }
+ if (bluetooth_checkservicename(s, pResults->lpszServiceInstanceName) == ERR_NONE) {
+ error = bluetooth_connect(s,atoi(addressAsString+i+1),address+1);
+ result = WSALookupServiceEnd(handle);
+ return error;
+ }
+ }
+ }
+ result = WSALookupServiceEnd(handle);
+ return ERR_NOTSUPPORTED;
+}
+
+GSM_Error bluetooth_findchannel(GSM_StateMachine *s)
+{
+ GSM_Device_BlueToothData *d = &s->Device.Data.BlueTooth;
+ WSADATA wsaData;
+ int i, protocolInfoSize, result;
+ WSAPROTOCOL_INFO protocolInfo;
+ HANDLE handle;
+ DWORD flags;
+ WSAQUERYSET querySet;
+ BYTE buffer[2000];
+ char addressAsString[1000];
+ DWORD bufferLength, addressSize;
+ WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
+ GSM_Error error;
+
+ if (WSAStartup(MAKEWORD(2,2), &wsaData)!=0x00) return ERR_DEVICENODRIVER;
+
+ d->hPhone = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
+ if (d->hPhone == INVALID_SOCKET) {
+ i = GetLastError();
+ GSM_OSErrorInfo(s, "Socket in bluetooth_open");
+ if (i == 10041) return ERR_DEVICENODRIVER;//unknown socket type
+ return ERR_UNKNOWN;
+ }
+
+ protocolInfoSize = sizeof(protocolInfo);
+ if (getsockopt(d->hPhone, SOL_SOCKET, SO_PROTOCOL_INFO,
+ (char*)&protocolInfo, &protocolInfoSize) != 0)
+ {
+ close(d->hPhone);
+ return ERR_UNKNOWN;
+ }
+ close(d->hPhone);
+
+ if (!strcmp(s->CurrentConfig->Device,"com2:")) {
+ bufferLength = sizeof(buffer);
+
+ flags = LUP_RETURN_NAME | LUP_CONTAINERS |
+ LUP_RETURN_ADDR | LUP_FLUSHCACHE |
+ LUP_RETURN_TYPE | LUP_RETURN_BLOB | LUP_RES_SERVICE;
+
+ memset(&querySet, 0, sizeof(querySet));
+ querySet.dwSize = sizeof(querySet);
+ querySet.dwNameSpace = NS_BTH;
+
+ result = WSALookupServiceBegin(&querySet, flags, &handle);
+ if (result != 0) return ERR_UNKNOWN;
+
+ while (1) {
+ result = WSALookupServiceNext(handle, flags, &bufferLength, pResults);
+ if (result != 0) break;
+
+ smprintf(s, "\"%s\"", pResults->lpszServiceInstanceName);
+
+ addressSize = sizeof(addressAsString);
+ addressAsString[0] = 0;
+ if (WSAAddressToString(pResults->lpcsaBuffer->RemoteAddr.lpSockaddr,
+ pResults->lpcsaBuffer->RemoteAddr.iSockaddrLength, &protocolInfo,
+ addressAsString,&addressSize)==0) {
+ smprintf(s, " - %s\n", addressAsString);
+ error = bluetooth_checkdevice(s, addressAsString,&protocolInfo);
+ if (error == ERR_NONE) {
+ result = WSALookupServiceEnd(handle);
+ return error;
+ }
+ } else smprintf(s, "\n");
+ }
+
+ result = WSALookupServiceEnd(handle);
+ return ERR_NOTSUPPORTED;
+ } else {
+ return bluetooth_checkdevice(s, s->CurrentConfig->Device,&protocolInfo);
+ }
+}
+
+#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/bluetoth/blue_w32.h b/gammu/emb/common/device/bluetoth/blue_w32.h
new file mode 100644
index 0000000..e457c92
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/blue_w32.h
@@ -0,0 +1,188 @@
+
+GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device);
+GSM_Error bluetooth_findchannel(GSM_StateMachine *s);
+
+/* MS Platform SDK */
+
+#ifndef __blue_w32_h
+#define __blue_w32_h
+
+#include <pshpack1.h> // Without it compiled code hangs up BT stack
+
+typedef ULONGLONG BTH_ADDR, *PBTH_ADDR;
+
+#define NAP_MASK ((ULONGLONG) 0xFFFF00000000)
+#define SAP_MASK ((ULONGLONG) 0x0000FFFFFFFF)
+
+#define NAP_BIT_OFFSET (8 * 4)
+#define SAP_BIT_OFFSET (0)
+
+#define GET_NAP(_bth_addr) ((USHORT) (((_bth_addr) & NAP_MASK) >> NAP_BIT_OFFSET))
+#define GET_SAP(_bth_addr) ((ULONG) (((_bth_addr) & SAP_MASK) >> SAP_BIT_OFFSET))
+
+#ifndef AF_BTH
+#define AF_BTH 32
+#endif
+
+typedef struct _SOCKADDR_BTH {
+ USHORT addressFamily; // Always AF_BTH
+ BTH_ADDR btAddr; // Bluetooth device address
+ GUID serviceClassId; // [OPTIONAL] system will query SDP for port
+ ULONG port; // RFCOMM channel or L2CAP PSM
+} SOCKADDR_BTH, *PSOCKADDR_BTH;
+
+#define BTHPROTO_RFCOMM 0x0003
+
+#ifdef BLUETOOTH_RF_SEARCHING
+
+typedef struct _SOCKET_ADDRESS {
+ LPSOCKADDR lpSockaddr ;
+ INT iSockaddrLength ;
+} SOCKET_ADDRESS, *PSOCKET_ADDRESS, FAR * LPSOCKET_ADDRESS ;
+
+typedef struct _CSADDR_INFO {
+ SOCKET_ADDRESS LocalAddr ;
+ SOCKET_ADDRESS RemoteAddr ;
+ INT iSocketType ;
+ INT iProtocol ;
+} CSADDR_INFO, *PCSADDR_INFO, FAR * LPCSADDR_INFO ;
+
+typedef struct _AFPROTOCOLS {
+ INT iAddressFamily;
+ INT iProtocol;
+} AFPROTOCOLS, *PAFPROTOCOLS, *LPAFPROTOCOLS;
+
+typedef enum _WSAEcomparator
+{
+ COMP_EQUAL = 0,
+ COMP_NOTLESS
+} WSAECOMPARATOR, *PWSAECOMPARATOR, *LPWSAECOMPARATOR;
+
+typedef struct _WSAVersion
+{
+ DWORD dwVersion;
+ WSAECOMPARATOR ecHow;
+}WSAVERSION, *PWSAVERSION, *LPWSAVERSION;
+
+typedef struct _WSAQuerySetA
+{
+ DWORD dwSize;
+ LPSTR lpszServiceInstanceName;
+ LPGUID lpServiceClassId;
+ LPWSAVERSION lpVersion;
+ LPSTR lpszComment;
+ DWORD dwNameSpace;
+ LPGUID lpNSProviderId;
+ LPSTR lpszContext;
+ DWORD dwNumberOfProtocols;
+ LPAFPROTOCOLS lpafpProtocols;
+ LPSTR lpszQueryString;
+ DWORD dwNumberOfCsAddrs;
+ LPCSADDR_INFO lpcsaBuffer;
+ DWORD dwOutputFlags;
+ LPBLOB lpBlob;
+} WSAQUERYSET, WSAQUERYSETA, *PWSAQUERYSETA, *LPWSAQUERYSETA;
+
+DEFINE_GUID(L2CAP_PROTOCOL_UUID, 0x00000100, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB);
+
+#ifndef NS_BTH
+# define NS_BTH 16
+#endif
+
+#define LUP_CONTAINERS 0x0002
+#define LUP_RETURN_NAME 0x0010
+#define LUP_RETURN_TYPE 0x0020
+#define LUP_RETURN_COMMENT 0x0080
+#define LUP_RETURN_ADDR 0x0100
+#define LUP_RETURN_BLOB 0x0200
+#define LUP_FLUSHCACHE 0x1000
+#define LUP_RES_SERVICE 0x8000
+
+#define WSAAPI FAR PASCAL
+
+#ifndef WINSOCK_API_LINKAGE
+#ifdef DECLSPEC_IMPORT
+#define WINSOCK_API_LINKAGE DECLSPEC_IMPORT
+#else
+#define WINSOCK_API_LINKAGE
+#endif
+#endif
+
+WINSOCK_API_LINKAGE INT WSAAPI
+WSALookupServiceBeginA(
+ IN LPWSAQUERYSETA lpqsRestrictions,
+ IN DWORD dwControlFlags,
+ OUT LPHANDLE lphLookup
+ );
+
+#define WSALookupServiceBegin WSALookupServiceBeginA
+
+WINSOCK_API_LINKAGE INT WSAAPI
+WSALookupServiceNextA(
+ IN HANDLE hLookup,
+ IN DWORD dwControlFlags,
+ IN OUT LPDWORD lpdwBufferLength,
+ OUT LPWSAQUERYSETA lpqsResults
+ );
+
+#define WSALookupServiceNext WSALookupServiceNextA
+
+WINSOCK_API_LINKAGE INT WSAAPI WSALookupServiceEnd(IN HANDLE hLookup);
+
+#define MAX_PROTOCOL_CHAIN 7
+
+typedef struct _WSAPROTOCOLCHAIN {
+ int ChainLen; /* the length of the chain, */
+ /* length = 0 means layered protocol, */
+ /* length = 1 means base protocol, */
+ /* length > 1 means protocol chain */
+ DWORD ChainEntries[MAX_PROTOCOL_CHAIN]; /* a list of dwCatalogEntryIds */
+} WSAPROTOCOLCHAIN, FAR * LPWSAPROTOCOLCHAIN;
+
+#define WSAPROTOCOL_LEN 255
+
+typedef struct _WSAPROTOCOL_INFOA {
+ DWORD dwServiceFlags1;
+ DWORD dwServiceFlags2;
+ DWORD dwServiceFlags3;
+ DWORD dwServiceFlags4;
+ DWORD dwProviderFlags;
+ GUID ProviderId;
+ DWORD dwCatalogEntryId;
+ WSAPROTOCOLCHAIN ProtocolChain;
+ int iVersion;
+ int iAddressFamily;
+ int iMaxSockAddr;
+ int iMinSockAddr;
+ int iSocketType;
+ int iProtocol;
+ int iProtocolMaxOffset;
+ int iNetworkByteOrder;
+ int iSecurityScheme;
+ DWORD dwMessageSize;
+ DWORD dwProviderReserved;
+ CHAR szProtocol[WSAPROTOCOL_LEN+1];
+} WSAPROTOCOL_INFOA, FAR * LPWSAPROTOCOL_INFOA;
+
+typedef WSAPROTOCOL_INFOA WSAPROTOCOL_INFO;
+
+#define SO_PROTOCOL_INFOA 0x2004 /* WSAPROTOCOL_INFOA structure */
+#define SO_PROTOCOL_INFO SO_PROTOCOL_INFOA
+
+WINSOCK_API_LINKAGE INT WSAAPI
+WSAAddressToStringA(
+ IN LPSOCKADDR lpsaAddress,
+ IN DWORD dwAddressLength,
+ IN LPWSAPROTOCOL_INFOA lpProtocolInfo,
+ IN OUT LPSTR lpszAddressString,
+ IN OUT LPDWORD lpdwAddressStringLength
+ );
+
+#define WSAAddressToString WSAAddressToStringA
+
+#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/bluetoth/bluetoth.c b/gammu/emb/common/device/bluetoth/bluetoth.c
new file mode 100644
index 0000000..c20e04b
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/bluetoth.c
@@ -0,0 +1,85 @@
+/* (c) 2003-2004 by Marcin Wiacek and Marcel Holtmann and others */
+
+#include "../../gsmstate.h"
+
+#ifdef GSM_ENABLE_BLUETOOTHDEVICE
+#ifndef DJGPP
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include "../../misc/coding/coding.h"
+#include "../../gsmcomon.h"
+#include "../devfunc.h"
+#include "bluetoth.h"
+
+#ifdef GSM_ENABLE_BLUEZ
+# include "bluez.h"
+#endif
+#ifdef GSM_ENABLE_AFFIX
+# include "affix.h"
+#endif
+#ifdef WIN32
+# include "blue_w32.h"
+#endif
+
+GSM_Error bluetooth_findrfchannel(GSM_StateMachine *s)
+{
+ GSM_Error error;
+
+#ifdef BLUETOOTH_RF_SEARCHING
+ if (!mystrncasecmp(s->CurrentConfig->Connection, "bluerf", 6)) return bluetooth_findchannel(s);
+#endif
+
+ switch (s->ConnectionType) {
+ case GCT_BLUEAT:
+ return bluetooth_connect(s,1,s->CurrentConfig->Device);
+ case GCT_BLUEOBEX:
+ return bluetooth_connect(s,9,s->CurrentConfig->Device);
+ case GCT_BLUEPHONET:
+ error = bluetooth_connect(s,14,s->CurrentConfig->Device); //older Series 40 - 8910, 6310
+ if (error == ERR_NONE) return error;
+ return bluetooth_connect(s,15,s->CurrentConfig->Device); //new Series 40 - 6310i, 6230
+ default:
+ return ERR_UNKNOWN;
+ }
+}
+
+static int bluetooth_read(GSM_StateMachine *s, void *buf, size_t nbytes)
+{
+ return socket_read(s, buf, nbytes, s->Device.Data.BlueTooth.hPhone);
+}
+
+#ifdef WIN32
+static int bluetooth_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes)
+#else
+static int bluetooth_write(GSM_StateMachine *s, void *buf, size_t nbytes)
+#endif
+{
+ return socket_write(s, buf, nbytes, s->Device.Data.BlueTooth.hPhone);
+}
+
+static GSM_Error bluetooth_close(GSM_StateMachine *s)
+{
+ return socket_close(s, s->Device.Data.BlueTooth.hPhone);
+}
+
+GSM_Device_Functions BlueToothDevice = {
+ bluetooth_findrfchannel,
+ bluetooth_close,
+ NONEFUNCTION,
+ NONEFUNCTION,
+ NONEFUNCTION,
+ bluetooth_read,
+ bluetooth_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/bluetoth/bluetoth.h b/gammu/emb/common/device/bluetoth/bluetoth.h
new file mode 100644
index 0000000..8a7fdf4
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/bluetoth.h
@@ -0,0 +1,15 @@
+
+#ifndef DJGPP
+#ifndef unixbluetooth_h
+#define unixbluetooth_h
+
+typedef struct {
+ int hPhone;
+} GSM_Device_BlueToothData;
+
+#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/bluetoth/bluez.c b/gammu/emb/common/device/bluetoth/bluez.c
new file mode 100644
index 0000000..8a4807e
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/bluez.c
@@ -0,0 +1,207 @@
+/* Based on work by Marcel Holtmann and other authors of Bluez */
+
+#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);
+ 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_data_t *d;
+ bdaddr_t interface;
+ struct search_context subcontext;
+ 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) {
+ channel = -1;
+ sdp_list_foreach(proto,print_access_protos,&channel);
+ //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_close(sess);
+
+ if (channel2 != -1) return bluetooth_connect(s, channel2, str);
+
+ return ERR_UNKNOWN;
+}
+
+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);
+
+ 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/bluetoth/bluez.h b/gammu/emb/common/device/bluetoth/bluez.h
new file mode 100644
index 0000000..896ecbe
--- a/dev/null
+++ b/gammu/emb/common/device/bluetoth/bluez.h
@@ -0,0 +1,3 @@
+
+GSM_Error bluetooth_connect(GSM_StateMachine *s, int port, char *device);
+GSM_Error bluetooth_findchannel(GSM_StateMachine *s);
diff --git a/gammu/emb/common/device/devfunc.c b/gammu/emb/common/device/devfunc.c
new file mode 100644
index 0000000..d31ebbf
--- a/dev/null
+++ b/gammu/emb/common/device/devfunc.c
@@ -0,0 +1,266 @@
+
+#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
+ 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
+ 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/devfunc.h b/gammu/emb/common/device/devfunc.h
new file mode 100644
index 0000000..6e8fb62
--- a/dev/null
+++ b/gammu/emb/common/device/devfunc.h
@@ -0,0 +1,38 @@
+
+#ifndef device_functions_h
+#define device_functions_h
+
+#include "../gsmstate.h"
+
+#ifdef GSM_ENABLE_BLUETOOTHDEVICE
+#ifdef BLUETOOTH_RF_SEARCHING
+
+GSM_Error bluetooth_checkservicename(GSM_StateMachine *s, char *name);
+
+#endif
+#endif
+
+#if defined (GSM_ENABLE_BLUETOOTHDEVICE) || defined (GSM_ENABLE_IRDADEVICE)
+
+int socket_read(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone);
+
+#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
+
+GSM_Error socket_close(GSM_StateMachine *s, int hPhone);
+
+#endif
+
+GSM_Error lock_device (const char* port, char **lock_device);
+bool unlock_device (char **lock_file);
+
+int FindSerialSpeed(char *buffer);
+
+#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/irda/irda.c b/gammu/emb/common/device/irda/irda.c
new file mode 100644
index 0000000..fef50ac
--- a/dev/null
+++ b/gammu/emb/common/device/irda/irda.c
@@ -0,0 +1,187 @@
+/* (c) 2001-2004 by Marcin Wiacek */
+/* based on some work from Ralf Thelen and MyGnokii */
+/* based on some work from Gnokii and MSDN */
+
+/* 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;
+ WSADATA wsaData;
+
+ WSAStartup(MAKEWORD(1,1), &wsaData);
+#else
+ if (s->ConnectionType == GCT_IRDAAT) return ERR_SOURCENOTAVAILABLE;
+#endif
+
+ /* discovering devices */
+ if (irda_discover_device(s)==false) return ERR_TIMEOUT;
+
+ /* Creating socket */
+ fd = socket(AF_IRDA, SOCK_STREAM, 0);
+
+ d->peer.irdaAddressFamily = AF_IRDA;
+#ifndef WIN32
+ d->peer.sir_lsap_sel = LSAP_ANY;
+#endif
+ switch (s->ConnectionType) {
+ case GCT_IRDAAT:
+ strcpy(d->peer.irdaServiceName, "IrDA:IrCOMM");
+
+#ifdef WIN32
+ if (setsockopt(fd, SOL_IRLMP, IRLMP_9WIRE_MODE, (const char *) &Enable9WireMode,
+ sizeof(int))==SOCKET_ERROR) return ERR_UNKNOWN;
+#endif
+ break;
+ case GCT_IRDAPHONET:
+ strcpy(d->peer.irdaServiceName, "Nokia:PhoNet");
+ break;
+ case GCT_IRDAOBEX:
+ /* IrDA:OBEX not supported by N3650 */
+// strcpy(d->peer.irdaServiceName, "IrDA:OBEX");
+
+ strcpy(d->peer.irdaServiceName, "OBEX");
+
+ /* Alternative server is "OBEX:IrXfer" */
+ break;
+ default:
+ return ERR_UNKNOWN;
+ }
+
+ /* Connecting to service */
+ if (connect(fd, (struct sockaddr *)&d->peer, sizeof(d->peer))) {
+ dbgprintf("Can't connect to service %s\n",d->peer.irdaServiceName);
+ close(fd);
+ return ERR_NOTSUPPORTED;
+ }
+
+ d->hPhone=fd;
+
+ return ERR_NONE;
+}
+
+static int irda_read(GSM_StateMachine *s, void *buf, size_t nbytes)
+{
+ return socket_read(s, buf, nbytes, s->Device.Data.Irda.hPhone);
+}
+
+#ifdef WIN32
+static int irda_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes)
+#else
+static int irda_write(GSM_StateMachine *s, void *buf, size_t nbytes)
+#endif
+{
+ return socket_write(s, buf, nbytes, s->Device.Data.Irda.hPhone);
+}
+
+static GSM_Error irda_close(GSM_StateMachine *s)
+{
+ return socket_close(s, s->Device.Data.Irda.hPhone);
+}
+
+GSM_Device_Functions IrdaDevice = {
+ irda_open,
+ irda_close,
+ NONEFUNCTION,
+ NONEFUNCTION,
+ NONEFUNCTION,
+ irda_read,
+ irda_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/irda/irda.h b/gammu/emb/common/device/irda/irda.h
new file mode 100644
index 0000000..455e6af
--- a/dev/null
+++ b/gammu/emb/common/device/irda/irda.h
@@ -0,0 +1,22 @@
+
+#ifndef DJGPP
+#ifndef unixirda_h
+#define unixirda_h
+
+#ifndef WIN32
+# include "irda_unx.h"
+#else
+# include "irda_w32.h"
+#endif
+
+typedef struct {
+ int hPhone;
+ struct sockaddr_irda peer;
+} GSM_Device_IrdaData;
+
+#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/irda/irda_unx.h b/gammu/emb/common/device/irda/irda_unx.h
new file mode 100644
index 0000000..8dbcb97
--- a/dev/null
+++ b/gammu/emb/common/device/irda/irda_unx.h
@@ -0,0 +1,61 @@
+/* part of irda.h available in Linux kernel source */
+
+/*********************************************************************
+ *
+ * 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/irda/irda_w32.h b/gammu/emb/common/device/irda/irda_w32.h
new file mode 100644
index 0000000..daffa37
--- a/dev/null
+++ b/gammu/emb/common/device/irda/irda_w32.h
@@ -0,0 +1,35 @@
+
+/* MS Platform SDK */
+
+#ifndef __irda_w32_h
+#define __irda_w32_h
+
+#define AF_IRDA 26
+#define SOL_IRLMP 0x00FF
+#define IRLMP_ENUMDEVICES 0x00000010
+#define IRLMP_9WIRE_MODE 0x00000016
+
+struct sockaddr_irda {
+ unsigned short irdaAddressFamily;
+ unsigned char irdaDeviceID[4];
+ char irdaServiceName[25];
+};
+
+struct irda_device_info {
+ unsigned char irdaDeviceID[4];
+ char irdaDeviceName[22];
+ unsigned char irdaDeviceHints1;
+ unsigned char irdaDeviceHints2;
+ unsigned char irdaCharSet;
+};
+
+struct irda_device_list {
+ ULONG 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
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:
+ */