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;
197 if (device_portfd>=0)
198 FD_SET(device_portfd,&readfds);
200 if (gettimeofday(&timeout/*tv*/,NULL/*tz*/))
201 perror("usleep_watchdevice()/gettimeofday(2) loop");
202 if (target.tv_sec < timeout.tv_sec)
204 timeout.tv_sec =target.tv_sec - timeout.tv_sec;
205 if (target.tv_usec < timeout.tv_usec) {
206 target.tv_usec+=1000000;
207 if (target.tv_sec <= 0)
211 timeout.tv_usec=target.tv_usec - timeout.tv_usec;
213 err=select((device_portfd<0 ? 0 : device_portfd+1),&readfds,NULL,NULL,&timeout);
215 if (device_portfd>=0 && FD_ISSET(device_portfd,&readfds)) {
216 /* call singal handler to process incoming data */
221 perror("Error in SelectLoop");
226 #if defined(__svr4__) || defined(__FreeBSD__)
227 /* thread for handling incoming data */
231 struct timeval timeout;
234 FD_SET(device_portfd,&readfds);
235 /* set timeout to 15 seconds */
238 while (!CurrentRequestTerminate) {
239 err=select(device_portfd+1,&readfds,NULL,NULL,&timeout);
241 /* call singal handler to process incoming data */
243 /* refresh timeout, just for linux :-( */
244 /* required for irda */
248 perror("Error in SelectLoop");
254 bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionType con)
261 #if defined(__svr4__) || defined(__FreeBSD__)
264 struct sigaction sig_io;
270 if ((strstr(GSM_Info->IrdaModels,"decode")!=NULL) && (CurrentConnectionType == GCT_Irda))
272 printf("DEBUG and Irda decode Model -> not realy open ;-)\n");
278 if (PortDevice[0]!=0x00) return true;
282 strncpy(PortDevice, port_device, GSM_MAX_DEVICE_NAME_LENGTH);
285 fprintf(stdout,_("Opening \"%s\" device...\n"),PortDevice);
288 strcpy(text,"\n\n\nMygnokii ");
289 sprintf(text+strlen(text), "%s",VERSION);
290 strcpy(text+strlen(text),"\n");
291 AppendLogText(text,false);
293 strcpy(text,"Port ");
294 strcpy(text+strlen(text),PortDevice);
295 strcpy(text+strlen(text),"\n");
296 AppendLogText(text,false);
298 strcpy(text,"Connection ");
300 case GCT_FBUS :strcpy(text+strlen(text),"FBUS");break;
302 case GCT_MBUS :strcpy(text+strlen(text),"MBUS");break;
303 case GCT_DLR3 :strcpy(text+strlen(text),"DLR3");break;
304 case GCT_AT :strcpy(text+strlen(text),"AT");break;
305 default :strcpy(text+strlen(text),"unknown");break;
308 strcpy(text+strlen(text),"\n");
309 AppendLogText(text,false);
311 /* Ralf Thelen: In this moment there is NO method of communication,
312 which require keepalive packets and GSM->KeepAlive is
313 always NULL_KeepAlive, I comment this thread, */
315 /* Create and start main thread. */
316 // rtn = pthread_create(&Thread, NULL,(void*)GSM->KeepAlive, (void *)NULL);
319 // fprintf(stdout,_("Error\n"));
324 #if defined(__svr4__) || defined(__FreeBSD__)
326 /* Set up and install handler before enabling async IO on port. */
327 sig_io.sa_handler = SigHandler;
329 sigaction (SIGIO, &sig_io, NULL);
334 result = device_open(PortDevice, with_odd_parity);
337 fprintf(stdout,_("Error\n"));
342 #if defined(__svr4__) || defined(__FreeBSD__)
343 /* create a thread to handle incoming data from mobile phone */
344 rtn=pthread_create(&selThread,NULL,(void*)SelectLoop,(void*)NULL);
346 fprintf(stdout,_("Error\n"));
355 /* ---------------- RTH: #ifdef WIN32 ------------------ */
359 extern HANDLE hPhone;
361 void device_close(void)
363 AppendLogText("CLOSE\n",false);
371 void device_dumpserial(void)
375 dcb.DCBlength = sizeof(DCB);
376 GetCommState(hPhone, &dcb);
378 fprintf(stdout, _("Serial device:"));
379 fprintf(stdout, _(" DTR is "));
380 switch (dcb.fDtrControl) {
381 case DTR_CONTROL_ENABLE : fprintf(stdout, _("up")); break;
382 case DTR_CONTROL_DISABLE : fprintf(stdout, _("down")); break;
383 case DTR_CONTROL_HANDSHAKE: fprintf(stdout, _("handshake"));break;
385 fprintf(stdout, _(", RTS is "));
386 switch (dcb.fRtsControl) {
387 case RTS_CONTROL_ENABLE : fprintf(stdout, _("up\n")); break;
388 case RTS_CONTROL_DISABLE : fprintf(stdout, _("down\n")); break;
389 case RTS_CONTROL_HANDSHAKE: fprintf(stdout, _("handshake\n"));break;
390 case RTS_CONTROL_TOGGLE : fprintf(stdout, _("toggle\n")); break;
395 void device_setdtrrts(int __dtr, int __rts)
399 dcb.DCBlength = sizeof(DCB);
400 GetCommState(hPhone, &dcb);
402 if (__dtr==1) dcb.fDtrControl = DTR_CONTROL_ENABLE;
403 else dcb.fDtrControl = DTR_CONTROL_DISABLE;
405 if (__rts==1) dcb.fRtsControl = RTS_CONTROL_ENABLE;
406 else dcb.fRtsControl = RTS_CONTROL_DISABLE;
408 SetCommState(hPhone, &dcb);
415 void device_changespeed(int __speed)
420 dcb.DCBlength = sizeof(DCB);
421 GetCommState(hPhone, &dcb);
424 case 115200: dcb.BaudRate=CBR_115200; break;
425 case 19200 : dcb.BaudRate=CBR_19200; break;
426 case 9600 : dcb.BaudRate=CBR_9600; break;
429 SetCommState(hPhone, &dcb);
432 fprintf(stdout,_("Serial device: changing speed to %i\n"),__speed);
436 bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionType con)
443 if (PortDevice[0]!=0x00) return true;
446 strncpy(PortDevice, port_device, GSM_MAX_DEVICE_NAME_LENGTH);
449 fprintf(stdout,_("Opening \"%s\" device...\n"),PortDevice);
452 strcpy(text,"\n\n\nMygnokii ");
453 sprintf(text+strlen(text), "%s",VERSION);
454 strcpy(text+strlen(text),"\n");
455 AppendLogText(text,false);
457 strcpy(text,"Port ");
458 strcpy(text+strlen(text),PortDevice);
459 strcpy(text+strlen(text),"\n");
460 AppendLogText(text,false);
462 strcpy(text,"Connection ");
464 case GCT_FBUS :strcpy(text+strlen(text),"FBUS");break;
465 case GCT_MBUS :strcpy(text+strlen(text),"MBUS");break;
466 case GCT_DLR3 :strcpy(text+strlen(text),"DLR3");break;
467 case GCT_AT :strcpy(text+strlen(text),"AT");break;
468 default :strcpy(text+strlen(text),"unknown");break;
470 strcpy(text+strlen(text),"\n");
471 AppendLogText(text,false);
473 CurrentDisableKeepAlive = true;
475 /* Create and start main thread. */
476 rtn = ! OpenConnection(PortDevice, Protocol->StateMachine, GSM->KeepAlive);
480 fprintf(stdout,_("Error\n"));
483 CurrentDisableKeepAlive = false;
486 if (with_odd_parity) {
487 dcb.DCBlength = sizeof(DCB);
488 GetCommState(hPhone, &dcb);
490 dcb.Parity=ODDPARITY;
492 SetCommState(hPhone, &dcb);
498 size_t device_write(const __ptr_t __buf, size_t __n) {
500 while (duringwrite) {}
502 AppendLog(__buf,__n,true);
503 i=WriteCommBlock(__buf,__n);
505 if (i) return __n; else return 0;