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;
189 if (gettimeofday(&target/*tv*/,NULL/*tz*/))
190 perror("usleep_watchdevice()/gettimeofday(2) init");
191 target.tv_usec+=usecs%1000000;
192 target.tv_sec +=usecs/1000000 + (target.tv_usec/1000000);
193 target.tv_usec%=1000000;
195 target.tv_usec+=1000000;
200 if (device_portfd>=0)
201 FD_SET(device_portfd,&readfds);
203 if (gettimeofday(&timeout/*tv*/,NULL/*tz*/))
204 perror("usleep_watchdevice()/gettimeofday(2) loop");
205 if (target.tv_sec < timeout.tv_sec)
207 timeout.tv_sec =target.tv_sec - timeout.tv_sec;
208 timeout.tv_usec=target.tv_usec - timeout.tv_usec;
209 if (timeout.tv_usec>=1000000) {
210 timeout.tv_usec-=1000000;
216 err=select((device_portfd<0 ? 0 : device_portfd+1),&readfds,NULL,NULL,&timeout);
218 if (device_portfd>=0 && FD_ISSET(device_portfd,&readfds)) {
219 /* call singal handler to process incoming data */
224 perror("Error in SelectLoop");
229 #if defined(__svr4__) || defined(__FreeBSD__)
230 /* thread for handling incoming data */
234 struct timeval timeout;
237 FD_SET(device_portfd,&readfds);
238 /* set timeout to 15 seconds */
241 while (!CurrentRequestTerminate) {
242 err=select(device_portfd+1,&readfds,NULL,NULL,&timeout);
244 /* call singal handler to process incoming data */
246 /* refresh timeout, just for linux :-( */
247 /* required for irda */
251 perror("Error in SelectLoop");
257 bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionType con)
264 #if defined(__svr4__) || defined(__FreeBSD__)
267 struct sigaction sig_io;
273 if ((strstr(GSM_Info->IrdaModels,"decode")!=NULL) && (CurrentConnectionType == GCT_Irda))
275 printf("DEBUG and Irda decode Model -> not realy open ;-)\n");
281 if (PortDevice[0]!=0x00) return true;
285 strncpy(PortDevice, port_device, GSM_MAX_DEVICE_NAME_LENGTH);
288 fprintf(stdout,_("Opening \"%s\" device...\n"),PortDevice);
291 strcpy(text,"\n\n\nMygnokii ");
292 sprintf(text+strlen(text), "%s",VERSION);
293 strcpy(text+strlen(text),"\n");
294 AppendLogText(text,false);
296 strcpy(text,"Port ");
297 strcpy(text+strlen(text),PortDevice);
298 strcpy(text+strlen(text),"\n");
299 AppendLogText(text,false);
301 strcpy(text,"Connection ");
303 case GCT_FBUS :strcpy(text+strlen(text),"FBUS");break;
305 case GCT_MBUS :strcpy(text+strlen(text),"MBUS");break;
306 case GCT_DLR3 :strcpy(text+strlen(text),"DLR3");break;
307 case GCT_AT :strcpy(text+strlen(text),"AT");break;
308 default :strcpy(text+strlen(text),"unknown");break;
311 strcpy(text+strlen(text),"\n");
312 AppendLogText(text,false);
314 /* Ralf Thelen: In this moment there is NO method of communication,
315 which require keepalive packets and GSM->KeepAlive is
316 always NULL_KeepAlive, I comment this thread, */
318 /* Create and start main thread. */
319 // rtn = pthread_create(&Thread, NULL,(void*)GSM->KeepAlive, (void *)NULL);
322 // fprintf(stdout,_("Error\n"));
327 #if defined(__svr4__) || defined(__FreeBSD__)
329 /* Set up and install handler before enabling async IO on port. */
330 sig_io.sa_handler = SigHandler;
332 sigaction (SIGIO, &sig_io, NULL);
337 result = device_open(PortDevice, with_odd_parity);
340 fprintf(stdout,_("Error\n"));
345 #if defined(__svr4__) || defined(__FreeBSD__)
346 /* create a thread to handle incoming data from mobile phone */
347 rtn=pthread_create(&selThread,NULL,(void*)SelectLoop,(void*)NULL);
349 fprintf(stdout,_("Error\n"));
358 /* ---------------- RTH: #ifdef WIN32 ------------------ */
362 extern HANDLE hPhone;
364 void device_close(void)
366 AppendLogText("CLOSE\n",false);
374 void device_dumpserial(void)
378 dcb.DCBlength = sizeof(DCB);
379 GetCommState(hPhone, &dcb);
381 fprintf(stdout, _("Serial device:"));
382 fprintf(stdout, _(" DTR is "));
383 switch (dcb.fDtrControl) {
384 case DTR_CONTROL_ENABLE : fprintf(stdout, _("up")); break;
385 case DTR_CONTROL_DISABLE : fprintf(stdout, _("down")); break;
386 case DTR_CONTROL_HANDSHAKE: fprintf(stdout, _("handshake"));break;
388 fprintf(stdout, _(", RTS is "));
389 switch (dcb.fRtsControl) {
390 case RTS_CONTROL_ENABLE : fprintf(stdout, _("up\n")); break;
391 case RTS_CONTROL_DISABLE : fprintf(stdout, _("down\n")); break;
392 case RTS_CONTROL_HANDSHAKE: fprintf(stdout, _("handshake\n"));break;
393 case RTS_CONTROL_TOGGLE : fprintf(stdout, _("toggle\n")); break;
398 void device_setdtrrts(int __dtr, int __rts)
402 dcb.DCBlength = sizeof(DCB);
403 GetCommState(hPhone, &dcb);
405 if (__dtr==1) dcb.fDtrControl = DTR_CONTROL_ENABLE;
406 else dcb.fDtrControl = DTR_CONTROL_DISABLE;
408 if (__rts==1) dcb.fRtsControl = RTS_CONTROL_ENABLE;
409 else dcb.fRtsControl = RTS_CONTROL_DISABLE;
411 SetCommState(hPhone, &dcb);
418 void device_changespeed(int __speed)
423 dcb.DCBlength = sizeof(DCB);
424 GetCommState(hPhone, &dcb);
427 case 115200: dcb.BaudRate=CBR_115200; break;
428 case 19200 : dcb.BaudRate=CBR_19200; break;
429 case 9600 : dcb.BaudRate=CBR_9600; break;
432 SetCommState(hPhone, &dcb);
435 fprintf(stdout,_("Serial device: changing speed to %i\n"),__speed);
439 bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionType con)
446 if (PortDevice[0]!=0x00) return true;
449 strncpy(PortDevice, port_device, GSM_MAX_DEVICE_NAME_LENGTH);
452 fprintf(stdout,_("Opening \"%s\" device...\n"),PortDevice);
455 strcpy(text,"\n\n\nMygnokii ");
456 sprintf(text+strlen(text), "%s",VERSION);
457 strcpy(text+strlen(text),"\n");
458 AppendLogText(text,false);
460 strcpy(text,"Port ");
461 strcpy(text+strlen(text),PortDevice);
462 strcpy(text+strlen(text),"\n");
463 AppendLogText(text,false);
465 strcpy(text,"Connection ");
467 case GCT_FBUS :strcpy(text+strlen(text),"FBUS");break;
468 case GCT_MBUS :strcpy(text+strlen(text),"MBUS");break;
469 case GCT_DLR3 :strcpy(text+strlen(text),"DLR3");break;
470 case GCT_AT :strcpy(text+strlen(text),"AT");break;
471 default :strcpy(text+strlen(text),"unknown");break;
473 strcpy(text+strlen(text),"\n");
474 AppendLogText(text,false);
476 CurrentDisableKeepAlive = true;
478 /* Create and start main thread. */
479 rtn = ! OpenConnection(PortDevice, Protocol->StateMachine, GSM->KeepAlive);
483 fprintf(stdout,_("Error\n"));
486 CurrentDisableKeepAlive = false;
489 if (with_odd_parity) {
490 dcb.DCBlength = sizeof(DCB);
491 GetCommState(hPhone, &dcb);
493 dcb.Parity=ODDPARITY;
495 SetCommState(hPhone, &dcb);
501 size_t device_write(const __ptr_t __buf, size_t __n) {
503 while (duringwrite) {}
505 AppendLog(__buf,__n,true);
506 i=WriteCommBlock(__buf,__n);
508 if (i) return __n; else return 0;