1 /***************************************************************************
2  *   copyright           : (C) 2002 by Hendrik Sattler                     *
3  *   mail                : post@hendrik-sattler.de                         *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  ***************************************************************************/
11 
12 #include "ttyaccess.h"
13 #include "tty_serial.h"
14 #include "tty_bluetooth.h"
15 
16 #include "scmxx.h"
17 #include "helper.h"
18 #include "atcommand.h"
19 #include "config.h"
20 #include "gtincl.h"
21 #include "w32compat.h"
22 
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <fcntl.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <unistd.h>
32 
33 
tty_open(struct port_args_t * args)34 struct tty_access* tty_open(struct port_args_t* args) {
35   struct tty_access* t = NULL;
36 
37   print_verbose(0,_("Accessing device %s..."),args->device);
38   switch (args->type) {
39   case TTY_TYPE_BLUETOOTH:
40     t = tty_bluetooth_open(args);
41     break;
42   case TTY_TYPE_SERIAL:
43     t = tty_serial_open(args);
44     break;
45   default:
46     break;
47   }
48   if (t == NULL) {
49     print_error(_("Cannot open %s\n"),args->device);
50     exit(EXIT_FAILURE);
51   }
52 
53   print_verbose(0,"%s\n",_("done"));
54   /* The following seems to be needed for C45
55    * which seems to react too slow
56    */
57   if (args->startdelay) {
58     print_verbose(0,_("Waiting for %d seconds as requested...\n"),args->startdelay);
59     sleep(args->startdelay);
60   }
61   return t;
62 }
63 
tty_write(const char * data,size_t count,long (* write_func)(const char * data,long len))64 int tty_write (const char* data, size_t count,
65 	       long (*write_func) (const char* data, long len))
66 {
67   long status = 0;
68   long instatus;
69 
70   do {
71     instatus = write_func(data+status,count-status);
72     if (instatus != -1) {
73       status += instatus;
74     } else {
75 #if ! ( defined(DOS_API) || defined(WINDOWS_API) )
76       if (errno == EAGAIN) usleep(1);
77       else
78 #endif
79 	return 0;
80     }
81   } while (count-status > 0);
82   return 1;
83 }
84 
85 
tty_read(int (* stop_condition)(const char *,const size_t),long (* read_func)(char * buf,long len))86 char* tty_read (int (*stop_condition)(const char*,const size_t),
87 		long (*read_func) (char* buf, long len))
88 {
89   char* retval = NULL;
90   int retvalsize = 0;
91   char buffer; //buffer the read character for checks
92   int counter = 0; //count the read-and-used characters
93   int repeat = 0; //tell the inner loop to loop
94 
95   long status;
96 
97   do {
98     do {
99       status = read_func(&buffer,1);
100       switch (status) {
101       case -1:
102 #if ! ( defined(DOS_API) || defined(WINDOWS_API) )
103         if (errno == EAGAIN) {
104           usleep(1);
105           repeat = 1;
106         } else
107 #endif
108 	{
109           mem_realloc(retval,0);
110           return NULL;
111         }
112       case 0:
113         mem_realloc(retval,0);
114         return str_dup("");
115       default:
116         repeat = 0;
117       }
118     } while (repeat);
119 
120     // allocate space on stack
121     if (counter >= retvalsize) {
122       retvalsize += BUFSIZ;
123       retval = mem_realloc(retval,retvalsize+1);
124       memset(retval+counter,0,retvalsize-counter+1);
125     }
126 
127     /* fix the '@'=0x00 (GSM character set) problem here :-(
128      * we simply set the MSB to 1, so when processing:
129      * only look at the last 7 bits (char&0x7F)
130      */
131     retval[counter++] = (buffer == 0) ? 128 : buffer;
132   } while (!stop_condition(retval,counter));
133   /* There are two types of possible answers:
134    * "> " (2 characters) for data input requests
135    * "....<CR><LF>" for all other things (even empty)
136    */
137   return mem_realloc(retval,strlen(retval)+1);
138 }
139 
140