5 A Linux/Unix toolset and driver for Nokia mobile phones.
7 Released under the terms of the GNU GPL, see file COPYING for more details.
14 #include "devices/unixserial.h"
15 #include <sys/ioctl.h>
21 #include "devices/winserial.h"
25 #include "devices/device.h"
30 /* for VC6 make scripts save VERSION constant in mversion.h file */
34 static char PortDevice[GSM_MAX_DEVICE_NAME_LENGTH]={0x00};
36 static bool duringwrite;
41 #if defined(__svr4__) || defined(__FreeBSD__)
45 int device_portfd = -1;
48 * Structure to store the filedescriptor we use.
52 static int device_getfd(void)
58 static int device_open(__const char *__file, int __with_odd_parity) {
60 switch (CurrentConnectionType) {
62 device_portfd = serial_opendevice(__file, __with_odd_parity, true, false);
66 return (device_portfd >= 0);
69 void device_close(void)
71 AppendLogText("CLOSE\n",false);
73 /* Now wait for thread to terminate. */
74 //pthread_join(Thread, NULL);
76 switch (CurrentConnectionType) {
77 default : serial_close(device_portfd); break;
85 void device_reset(void) {
91 static void device_dumpserial(void);
94 void device_setdtrrts(int __dtr, int __rts)
96 switch (CurrentConnectionType) {
98 serial_setdtrrts(device_portfd, __dtr, __rts);
106 void device_changespeed(int __speed)
108 switch (CurrentConnectionType) {
110 serial_changespeed(device_portfd, __speed);
112 fprintf(stdout,_("Serial device: changing speed to %i\n"),__speed);
118 static size_t device_read(__ptr_t __buf, size_t __nbytes)
120 switch (CurrentConnectionType) {
121 default : return (serial_read(device_portfd, __buf, __nbytes)); break;
125 size_t device_write(__const __ptr_t __buf, size_t __n) {
129 while (duringwrite) {
130 fprintf(stderr,"device_write: reentrance violation!\n");
134 memcpy(buffer,__buf,__n);
135 AppendLog(buffer,__n,true);
138 switch (CurrentConnectionType) {
139 default : mysize = serial_write(device_portfd, __buf, __n); break;
143 fprintf(stderr,"WARNING: device_write(__n=%ld)=%ld\n",(long)__n,(long)mysize);
148 static void device_dumpserial(void)
151 unsigned int Flags=0;
153 PortFD = device_getfd();
155 ioctl(PortFD, TIOCMGET, &Flags);
157 fprintf(stdout, _("Serial device:"));
158 fprintf(stdout, _(" DTR is %s"), Flags&TIOCM_DTR?_("up"):_("down"));
159 fprintf(stdout, _(", RTS is %s"), Flags&TIOCM_RTS?_("up"):_("down"));
160 fprintf(stdout, _(", CAR is %s"), Flags&TIOCM_CAR?_("up"):_("down"));
161 fprintf(stdout, _(", CTS is %s\n"), Flags&TIOCM_CTS?_("up"):_("down"));
165 static char SigHandler_buffer[255];
167 void SigHandler(int status)
174 res = device_read(SigHandler_buffer, sizeof(SigHandler_buffer));
176 for (count = 0; count < res ; count ++) {
177 Protocol->StateMachine(SigHandler_buffer[count]);
183 void usleep_watchdevice(unsigned long usecs)
187 struct timeval target,timeout;
188 long timeout_sec,timeout_usec; /* signed! */
190 if (gettimeofday(&target/*tv*/,NULL/*tz*/))
191 perror("usleep_watchdevice()/gettimeofday(2) init");
192 target.tv_usec+=usecs%1000000;
193 target.tv_sec +=usecs/1000000 + (target.tv_usec/1000000);
194 target.tv_usec%=1000000;
197 if (gettimeofday(&timeout/*tv*/,NULL/*tz*/))
198 perror("usleep_watchdevice()/gettimeofday(2) loop");
200 timeout_sec =target.tv_sec -(long)timeout.tv_sec ;
201 timeout_usec=target.tv_usec-(long)timeout.tv_usec;
203 if (timeout_usec<0) {
205 timeout_usec+=1000000;
210 timeout.tv_sec =timeout_sec ;
211 timeout.tv_usec=timeout_usec;
214 if (device_portfd>=0)
215 FD_SET(device_portfd,&readfds);
217 err=select((device_portfd<0 ? 0 : device_portfd+1),&readfds,NULL,NULL,&timeout);
219 if (device_portfd>=0 && FD_ISSET(device_portfd,&readfds)) {
220 /* call singal handler to process incoming data */
225 perror("Error in SelectLoop");
231 #if defined(__svr4__) || defined(__FreeBSD__)
232 /* thread for handling incoming data */
236 struct timeval timeout;
239 FD_SET(device_portfd,&readfds);
240 /* set timeout to 15 seconds */
243 while (!CurrentRequestTerminate) {
244 err=select(device_portfd+1,&readfds,NULL,NULL,&timeout);
246 /* call singal handler to process incoming data */
248 /* refresh timeout, just for linux :-( */
249 /* required for irda */
253 perror("Error in SelectLoop");
259 bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionType con)
266 #if defined(__svr4__) || defined(__FreeBSD__)
269 struct sigaction sig_io;
275 if ((strstr(GSM_Info->IrdaModels,"decode")!=NULL) && (CurrentConnectionType == GCT_Irda))
277 printf("DEBUG and Irda decode Model -> not realy open ;-)\n");
283 if (PortDevice[0]!=0x00) return true;
287 strncpy(PortDevice, port_device, GSM_MAX_DEVICE_NAME_LENGTH);
290 fprintf(stdout,_("Opening \"%s\" device...\n"),PortDevice);
293 strcpy(text,"\n\n\nMygnokii ");
294 sprintf(text+strlen(text), "%s",VERSION);
295 strcpy(text+strlen(text),"\n");
296 AppendLogText(text,false);
298 strcpy(text,"Port ");
299 strcpy(text+strlen(text),PortDevice);
300 strcpy(text+strlen(text),"\n");
301 AppendLogText(text,false);
303 strcpy(text,"Connection ");
305 case GCT_FBUS :strcpy(text+strlen(text),"FBUS");break;
307 case GCT_MBUS :strcpy(text+strlen(text),"MBUS");break;
308 case GCT_DLR3 :strcpy(text+strlen(text),"DLR3");break;
309 case GCT_AT :strcpy(text+strlen(text),"AT");break;
310 default :strcpy(text+strlen(text),"unknown");break;
313 strcpy(text+strlen(text),"\n");
314 AppendLogText(text,false);
316 /* Ralf Thelen: In this moment there is NO method of communication,
317 which require keepalive packets and GSM->KeepAlive is
318 always NULL_KeepAlive, I comment this thread, */
320 /* Create and start main thread. */
321 // rtn = pthread_create(&Thread, NULL,(void*)GSM->KeepAlive, (void *)NULL);
324 // fprintf(stdout,_("Error\n"));
329 #if defined(__svr4__) || defined(__FreeBSD__)
331 /* Set up and install handler before enabling async IO on port. */
332 sig_io.sa_handler = SigHandler;
334 sigaction (SIGIO, &sig_io, NULL);
339 result = device_open(PortDevice, with_odd_parity);
342 fprintf(stdout,_("Error\n"));
347 #if defined(__svr4__) || defined(__FreeBSD__)
348 /* create a thread to handle incoming data from mobile phone */
349 rtn=pthread_create(&selThread,NULL,(void*)SelectLoop,(void*)NULL);
351 fprintf(stdout,_("Error\n"));
360 /* ---------------- RTH: #ifdef WIN32 ------------------ */
364 extern HANDLE hPhone;
366 void device_close(void)
368 AppendLogText("CLOSE\n",false);
376 void device_dumpserial(void)
380 dcb.DCBlength = sizeof(DCB);
381 GetCommState(hPhone, &dcb);
383 fprintf(stdout, _("Serial device:"));
384 fprintf(stdout, _(" DTR is "));
385 switch (dcb.fDtrControl) {
386 case DTR_CONTROL_ENABLE : fprintf(stdout, _("up")); break;
387 case DTR_CONTROL_DISABLE : fprintf(stdout, _("down")); break;
388 case DTR_CONTROL_HANDSHAKE: fprintf(stdout, _("handshake"));break;
390 fprintf(stdout, _(", RTS is "));
391 switch (dcb.fRtsControl) {
392 case RTS_CONTROL_ENABLE : fprintf(stdout, _("up\n")); break;
393 case RTS_CONTROL_DISABLE : fprintf(stdout, _("down\n")); break;
394 case RTS_CONTROL_HANDSHAKE: fprintf(stdout, _("handshake\n"));break;
395 case RTS_CONTROL_TOGGLE : fprintf(stdout, _("toggle\n")); break;
400 void device_setdtrrts(int __dtr, int __rts)
404 dcb.DCBlength = sizeof(DCB);
405 GetCommState(hPhone, &dcb);
407 if (__dtr==1) dcb.fDtrControl = DTR_CONTROL_ENABLE;
408 else dcb.fDtrControl = DTR_CONTROL_DISABLE;
410 if (__rts==1) dcb.fRtsControl = RTS_CONTROL_ENABLE;
411 else dcb.fRtsControl = RTS_CONTROL_DISABLE;
413 SetCommState(hPhone, &dcb);
420 void device_changespeed(int __speed)
425 dcb.DCBlength = sizeof(DCB);
426 GetCommState(hPhone, &dcb);
429 case 115200: dcb.BaudRate=CBR_115200; break;
430 case 19200 : dcb.BaudRate=CBR_19200; break;
431 case 9600 : dcb.BaudRate=CBR_9600; break;
434 SetCommState(hPhone, &dcb);
437 fprintf(stdout,_("Serial device: changing speed to %i\n"),__speed);
441 bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionType con)
448 if (PortDevice[0]!=0x00) return true;
451 strncpy(PortDevice, port_device, GSM_MAX_DEVICE_NAME_LENGTH);
454 fprintf(stdout,_("Opening \"%s\" device...\n"),PortDevice);
457 strcpy(text,"\n\n\nMygnokii ");
458 sprintf(text+strlen(text), "%s",VERSION);
459 strcpy(text+strlen(text),"\n");
460 AppendLogText(text,false);
462 strcpy(text,"Port ");
463 strcpy(text+strlen(text),PortDevice);
464 strcpy(text+strlen(text),"\n");
465 AppendLogText(text,false);
467 strcpy(text,"Connection ");
469 case GCT_FBUS :strcpy(text+strlen(text),"FBUS");break;
470 case GCT_MBUS :strcpy(text+strlen(text),"MBUS");break;
471 case GCT_DLR3 :strcpy(text+strlen(text),"DLR3");break;
472 case GCT_AT :strcpy(text+strlen(text),"AT");break;
473 default :strcpy(text+strlen(text),"unknown");break;
475 strcpy(text+strlen(text),"\n");
476 AppendLogText(text,false);
478 CurrentDisableKeepAlive = true;
480 /* Create and start main thread. */
481 rtn = ! OpenConnection(PortDevice, Protocol->StateMachine, GSM->KeepAlive);
485 fprintf(stdout,_("Error\n"));
488 CurrentDisableKeepAlive = false;
491 if (with_odd_parity) {
492 dcb.DCBlength = sizeof(DCB);
493 GetCommState(hPhone, &dcb);
495 dcb.Parity=ODDPARITY;
497 SetCommState(hPhone, &dcb);
503 size_t device_write(const __ptr_t __buf, size_t __n) {
505 while (duringwrite) {}
507 AppendLog(__buf,__n,true);
508 i=WriteCommBlock(__buf,__n);
510 if (i) return __n; else return 0;