--- /dev/null
+/*
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for Nokia mobile phones.
+
+ Released under the terms of the GNU GPL, see file COPYING for more details.
+
+*/
+
+#ifndef WIN32
+ #include "devices/unixserial.h"
+ #include "devices/unixirda.h"
+ #include "devices/tekram.h"
+ #include <sys/ioctl.h>
+ #include <pthread.h>
+ #include <termios.h>
+ #include <signal.h>
+ #include <errno.h>
+#else
+ #include <windows.h>
+ #include "devices/winserial.h"
+#endif
+
+#include "gsm-api.h"
+#include "devices/device.h"
+
+#include <string.h>
+
+#ifdef VC6
+ /* for VC6 make scripts save VERSION constant in mversion.h file */
+ #include "mversion.h"
+#endif
+
+char PortDevice[GSM_MAX_DEVICE_NAME_LENGTH]={0x00};
+
+bool duringwrite;
+
+#ifndef WIN32
+
+//pthread_t Thread;
+#if defined(__svr4__) || defined(__FreeBSD__)
+ pthread_t selThread;
+#endif
+
+int device_portfd = -1;
+
+/*
+ * Structure to store the filedescriptor we use.
+ *
+ */
+int device_getfd(void)
+{
+ return device_portfd;
+}
+
+int device_open(__const char *__file, int __with_odd_parity) {
+
+ switch (CurrentConnectionType) {
+ case GCT_Tekram:
+ device_portfd = tekram_open(__file);
+ break;
+ case GCT_Irda:
+ device_portfd = irda_open();
+ break;
+ default:
+ device_portfd = serial_opendevice(__file, __with_odd_parity, true, false);
+ break;
+ }
+
+ return (device_portfd >= 0);
+}
+
+void device_close(void)
+{
+ AppendLogText("CLOSE\n",false);
+
+ /* Now wait for thread to terminate. */
+ //pthread_join(Thread, NULL);
+
+ switch (CurrentConnectionType) {
+ case GCT_Tekram: tekram_close(device_portfd); break;
+ case GCT_Irda : irda_close(device_portfd); break;
+ default : serial_close(device_portfd); break;
+ }
+
+ PortDevice[0]=0x00;
+}
+
+void device_reset(void) {
+}
+
+void device_setdtrrts(int __dtr, int __rts)
+{
+ switch (CurrentConnectionType) {
+ case GCT_Tekram:
+ case GCT_Irda:
+ break;
+ default:
+ serial_setdtrrts(device_portfd, __dtr, __rts);
+#ifdef DEBUG
+ device_dumpserial();
+#endif
+ break;
+ }
+}
+
+void device_changespeed(int __speed)
+{
+ switch (CurrentConnectionType) {
+ case GCT_Irda:
+ break;
+ case GCT_Tekram:
+ tekram_changespeed(device_portfd, __speed);
+ break;
+ default:
+ serial_changespeed(device_portfd, __speed);
+#ifdef DEBUG
+ fprintf(stdout,_("Serial device: changing speed to %i\n"),__speed);
+#endif
+ break;
+ }
+}
+
+size_t device_read(__ptr_t __buf, size_t __nbytes)
+{
+ switch (CurrentConnectionType) {
+ case GCT_Tekram: return (tekram_read(device_portfd, __buf, __nbytes)); break;
+ case GCT_Irda : return ( irda_read(device_portfd, __buf, __nbytes)); break;
+ default : return (serial_read(device_portfd, __buf, __nbytes)); break;
+ }
+}
+
+size_t device_write(__const __ptr_t __buf, size_t __n) {
+ u8 buffer[300];
+ size_t mysize;
+
+ while (duringwrite) {}
+
+ memcpy(buffer,__buf,__n);
+ AppendLog(buffer,__n,true);
+
+ duringwrite=true;
+ switch (CurrentConnectionType) {
+ case GCT_Irda : mysize = irda_write(device_portfd, __buf, __n); break;
+ case GCT_Tekram: mysize = tekram_write(device_portfd, __buf, __n); break;
+ default : mysize = serial_write(device_portfd, __buf, __n); break;
+ }
+ duringwrite=false;
+ return mysize;
+}
+
+#ifdef DEBUG
+void device_dumpserial(void)
+{
+ int PortFD;
+ unsigned int Flags=0;
+
+ PortFD = device_getfd();
+
+ ioctl(PortFD, TIOCMGET, &Flags);
+
+ fprintf(stdout, _("Serial device:"));
+ fprintf(stdout, _(" DTR is %s"), Flags&TIOCM_DTR?_("up"):_("down"));
+ fprintf(stdout, _(", RTS is %s"), Flags&TIOCM_RTS?_("up"):_("down"));
+ fprintf(stdout, _(", CAR is %s"), Flags&TIOCM_CAR?_("up"):_("down"));
+ fprintf(stdout, _(", CTS is %s\n"), Flags&TIOCM_CTS?_("up"):_("down"));
+}
+#endif /* DEBUG */
+
+void SigHandler(int status)
+{
+
+ unsigned char buffer[2048];
+
+ int count, res;
+
+ res = device_read(buffer, 255);
+
+ for (count = 0; count < res ; count ++) {
+ Protocol->StateMachine(buffer[count]);
+ }
+}
+
+
+#if defined(__svr4__) || defined(__FreeBSD__)
+/* thread for handling incoming data */
+void SelectLoop() {
+ int err;
+ fd_set readfds;
+ struct timeval timeout;
+
+ FD_ZERO(&readfds);
+ FD_SET(device_portfd,&readfds);
+ /* set timeout to 15 seconds */
+ timeout.tv_sec=15;
+ timeout.tv_usec=0;
+ while (!CurrentRequestTerminate) {
+ err=select(device_portfd+1,&readfds,NULL,NULL,&timeout);
+ if ( err > 0 ) {
+ /* call singal handler to process incoming data */
+ SigHandler(0);
+ /* refresh timeout, just for linux :-( */\r
+ /* required for irda */
+ timeout.tv_sec=15;\r
+ } else {
+ if (err == -1)
+ perror("Error in SelectLoop");
+ }
+ }
+}
+#endif
+
+bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionType con)
+{
+ int result;
+
+ char text[100];
+
+#if defined(__svr4__) || defined(__FreeBSD__)
+ int rtn;
+#else
+ struct sigaction sig_io;
+#endif
+
+#ifdef DEBUG
+ if ((strstr(GSM_Info->IrdaModels,"decode")!=NULL) && (CurrentConnectionType == GCT_Irda))
+ {
+ printf("DEBUG and Irda decode Model -> not realy open ;-)\n");
+ return true;
+ }
+#endif
+
+ if (PortDevice[0]!=0x00) return true;
+
+ duringwrite=false;
+
+ strncpy(PortDevice, port_device, GSM_MAX_DEVICE_NAME_LENGTH);
+
+#ifdef DEBUG
+ fprintf(stdout,_("Opening \"%s\" device...\n"),PortDevice);
+#endif
+
+ strcpy(text,"\n\n\nMygnokii ");
+ sprintf(text+strlen(text), "%s",VERSION);
+ strcpy(text+strlen(text),"\n");
+ AppendLogText(text,false);
+
+ strcpy(text,"Port ");
+ strcpy(text+strlen(text),PortDevice);
+ strcpy(text+strlen(text),"\n");
+ AppendLogText(text,false);
+
+ strcpy(text,"Connection ");
+ switch (con) {
+ case GCT_FBUS :strcpy(text+strlen(text),"FBUS");break;
+ case GCT_Infrared:strcpy(text+strlen(text),"infrared");break;
+ case GCT_Irda :strcpy(text+strlen(text),"irda sockets");break;
+ case GCT_MBUS :strcpy(text+strlen(text),"MBUS");break;
+ case GCT_DLR3 :strcpy(text+strlen(text),"DLR3");break;
+ case GCT_Tekram :strcpy(text+strlen(text),"Tekram");break;
+ case GCT_AT :strcpy(text+strlen(text),"AT");break;
+ default :strcpy(text+strlen(text),"unknown");break;
+ }
+ strcpy(text+strlen(text),"\n");
+ AppendLogText(text,false);
+
+ /* Ralf Thelen: In this moment there is NO method of communication,
+ which require keepalive packets and GSM->KeepAlive is
+ always NULL_KeepAlive, I comment this thread, */
+
+ /* Create and start main thread. */
+// rtn = pthread_create(&Thread, NULL,(void*)GSM->KeepAlive, (void *)NULL);
+//
+// if (rtn != 0) {
+// fprintf(stdout,_("Error\n"));
+// return false;
+// }
+
+#if defined(__svr4__) || defined(__FreeBSD__)
+#else
+ /* Set up and install handler before enabling async IO on port. */
+ sig_io.sa_handler = SigHandler;
+ sig_io.sa_flags = 0;
+ sigaction (SIGIO, &sig_io, NULL);
+#endif
+
+ /* Open device. */
+ result = device_open(PortDevice, with_odd_parity);
+
+ if (!result) {
+ fprintf(stdout,_("Error\n"));
+ return false;
+ }
+
+#if defined(__svr4__) || defined(__FreeBSD__)
+ /* create a thread to handle incoming data from mobile phone */
+ rtn=pthread_create(&selThread,NULL,(void*)SelectLoop,(void*)NULL);
+ if (rtn != 0) {
+ fprintf(stdout,_("Error\n"));
+ return false;
+ }
+#endif
+
+ return true;
+}
+
+/* ---------------- RTH: #ifdef WIN32 ------------------ */
+
+#else
+
+ extern HANDLE hPhone;
+
+void device_close(void)
+{
+ AppendLogText("CLOSE\n",false);
+
+ CloseConnection();
+
+ PortDevice[0]=0x00;
+}
+
+#ifdef DEBUG
+void device_dumpserial(void)
+{
+ DCB dcb;
+
+ dcb.DCBlength = sizeof(DCB);
+ GetCommState(hPhone, &dcb);
+
+ fprintf(stdout, _("Serial device:"));
+ fprintf(stdout, _(" DTR is "));
+ switch (dcb.fDtrControl) {
+ case DTR_CONTROL_ENABLE : fprintf(stdout, _("up")); break;
+ case DTR_CONTROL_DISABLE : fprintf(stdout, _("down")); break;
+ case DTR_CONTROL_HANDSHAKE: fprintf(stdout, _("handshake"));break;
+ }
+ fprintf(stdout, _(", RTS is "));
+ switch (dcb.fRtsControl) {
+ case RTS_CONTROL_ENABLE : fprintf(stdout, _("up\n")); break;
+ case RTS_CONTROL_DISABLE : fprintf(stdout, _("down\n")); break;
+ case RTS_CONTROL_HANDSHAKE: fprintf(stdout, _("handshake\n"));break;
+ case RTS_CONTROL_TOGGLE : fprintf(stdout, _("toggle\n")); break;
+ }
+}
+#endif /* DEBUG */
+
+void device_setdtrrts(int __dtr, int __rts)
+{
+ DCB dcb;
+
+ dcb.DCBlength = sizeof(DCB);
+ GetCommState(hPhone, &dcb);
+
+ if (__dtr==1) dcb.fDtrControl = DTR_CONTROL_ENABLE;
+ else dcb.fDtrControl = DTR_CONTROL_DISABLE;
+
+ if (__rts==1) dcb.fRtsControl = RTS_CONTROL_ENABLE;
+ else dcb.fRtsControl = RTS_CONTROL_DISABLE;
+
+ SetCommState(hPhone, &dcb);
+
+#ifdef DEBUG
+ device_dumpserial();
+#endif
+}
+
+void device_changespeed(int __speed)
+{
+
+ DCB dcb;
+
+ dcb.DCBlength = sizeof(DCB);
+ GetCommState(hPhone, &dcb);
+
+ switch (__speed) {
+ case 115200: dcb.BaudRate=CBR_115200; break;
+ case 19200 : dcb.BaudRate=CBR_19200; break;
+ case 9600 : dcb.BaudRate=CBR_9600; break;
+ }
+
+ SetCommState(hPhone, &dcb);
+
+#ifdef DEBUG
+ fprintf(stdout,_("Serial device: changing speed to %i\n"),__speed);
+#endif
+}
+
+bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionType con)
+{
+ DCB dcb;
+ char text[100];
+
+ int rtn;
+
+ if (PortDevice[0]!=0x00) return true;
+
+ duringwrite=false;
+ strncpy(PortDevice, port_device, GSM_MAX_DEVICE_NAME_LENGTH);
+
+#ifdef DEBUG
+ fprintf(stdout,_("Opening \"%s\" device...\n"),PortDevice);
+#endif
+
+ strcpy(text,"\n\n\nMygnokii ");
+ sprintf(text+strlen(text), "%s",VERSION);
+ strcpy(text+strlen(text),"\n");
+ AppendLogText(text,false);
+
+ strcpy(text,"Port ");
+ strcpy(text+strlen(text),PortDevice);
+ strcpy(text+strlen(text),"\n");
+ AppendLogText(text,false);
+
+ strcpy(text,"Connection ");
+ switch (con) {
+ case GCT_FBUS :strcpy(text+strlen(text),"FBUS");break;
+ case GCT_Infrared:strcpy(text+strlen(text),"infrared");break;
+ case GCT_Irda :strcpy(text+strlen(text),"irda sockets");break;
+ case GCT_MBUS :strcpy(text+strlen(text),"MBUS");break;
+ case GCT_DLR3 :strcpy(text+strlen(text),"DLR3");break;
+ case GCT_Tekram :strcpy(text+strlen(text),"Tekram");break;
+ case GCT_AT :strcpy(text+strlen(text),"AT");break;
+ default :strcpy(text+strlen(text),"unknown");break;
+ }
+ strcpy(text+strlen(text),"\n");
+ AppendLogText(text,false);
+
+ CurrentDisableKeepAlive = true;
+
+ /* Create and start main thread. */
+ rtn = ! OpenConnection(PortDevice, Protocol->StateMachine, GSM->KeepAlive);
+
+ if (rtn != 0) {
+
+ fprintf(stdout,_("Error\n"));
+ return false;
+ } else {
+ CurrentDisableKeepAlive = false;
+ }
+
+ if (with_odd_parity) {
+ dcb.DCBlength = sizeof(DCB);
+ GetCommState(hPhone, &dcb);
+
+ dcb.Parity=ODDPARITY;
+
+ SetCommState(hPhone, &dcb);
+ }
+
+ return true;
+}
+
+size_t device_write(const __ptr_t __buf, size_t __n) {
+ int i;
+ while (duringwrite) {}
+ duringwrite=true;
+ AppendLog(__buf,__n,true);
+ i=WriteCommBlock(__buf,__n);
+ duringwrite=false;
+ if (i) return __n; else return 0;
+}
+
+#endif /*WIN32*/