Diffstat (limited to 'gammu/emb/common/device/devfunc.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | gammu/emb/common/device/devfunc.c | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/gammu/emb/common/device/devfunc.c b/gammu/emb/common/device/devfunc.c new file mode 100644 index 0000000..d31ebbf --- a/dev/null +++ b/gammu/emb/common/device/devfunc.c | |||
@@ -0,0 +1,266 @@ | |||
1 | |||
2 | #include <string.h> | ||
3 | #ifdef WIN32 | ||
4 | # include <io.h> | ||
5 | #else | ||
6 | # include <errno.h> | ||
7 | # include <signal.h> | ||
8 | #endif | ||
9 | |||
10 | #include "../gsmstate.h" | ||
11 | |||
12 | #ifdef GSM_ENABLE_BLUETOOTHDEVICE | ||
13 | #ifdef BLUETOOTH_RF_SEARCHING | ||
14 | |||
15 | GSM_Error bluetooth_checkservicename(GSM_StateMachine *s, char *name) | ||
16 | { | ||
17 | if (s->ConnectionType == GCT_BLUEPHONET && strstr(name,"Nokia PC Suite")!=NULL) return ERR_NONE; | ||
18 | if (s->ConnectionType == GCT_BLUEOBEX && strstr(name,"OBEX") !=NULL) return ERR_NONE; | ||
19 | if (s->ConnectionType == GCT_BLUEAT && strstr(name,"COM 1") !=NULL) return ERR_NONE; | ||
20 | return ERR_UNKNOWN; | ||
21 | } | ||
22 | |||
23 | #endif | ||
24 | #endif | ||
25 | |||
26 | #if defined (GSM_ENABLE_BLUETOOTHDEVICE) || defined (GSM_ENABLE_IRDADEVICE) | ||
27 | |||
28 | int socket_read(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone) | ||
29 | { | ||
30 | fd_set readfds; | ||
31 | #ifdef WIN32 | ||
32 | struct timeval timer; | ||
33 | #endif | ||
34 | |||
35 | FD_ZERO(&readfds); | ||
36 | FD_SET(hPhone, &readfds); | ||
37 | #ifndef WIN32 | ||
38 | if (select(hPhone+1, &readfds, NULL, NULL, 0)) { | ||
39 | return(read(hPhone, buf, nbytes)); | ||
40 | } | ||
41 | #else | ||
42 | memset(&timer,0,sizeof(timer)); | ||
43 | if (select(0, &readfds, NULL, NULL, &timer) != 0) { | ||
44 | return(recv(hPhone, buf, nbytes, 0)); | ||
45 | } | ||
46 | #endif | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | #ifdef WIN32 | ||
51 | int socket_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes, int hPhone) | ||
52 | #else | ||
53 | int socket_write(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone) | ||
54 | #endif | ||
55 | { | ||
56 | int ret; | ||
57 | size_t actual = 0; | ||
58 | |||
59 | do { | ||
60 | ret = send(hPhone, buf, nbytes - actual, 0); | ||
61 | if (ret < 0) { | ||
62 | if (actual != nbytes) GSM_OSErrorInfo(s,"socket_write"); | ||
63 | return actual; | ||
64 | } | ||
65 | actual += ret; | ||
66 | buf += ret; | ||
67 | } while (actual < nbytes); | ||
68 | |||
69 | return actual; | ||
70 | } | ||
71 | |||
72 | GSM_Error socket_close(GSM_StateMachine *s, int hPhone) | ||
73 | { | ||
74 | shutdown(hPhone, 0); | ||
75 | #ifdef WIN32 | ||
76 | closesocket(hPhone); /*FIXME: error checking */ | ||
77 | #else | ||
78 | close(hPhone); /*FIXME: error checking */ | ||
79 | #endif | ||
80 | return ERR_NONE; | ||
81 | } | ||
82 | |||
83 | #endif | ||
84 | |||
85 | #ifdef ENABLE_LGPL | ||
86 | |||
87 | GSM_Error lock_device(const char* port, char **lock_device) | ||
88 | { | ||
89 | *lock_device = 0; | ||
90 | return ERR_NONE; | ||
91 | } | ||
92 | |||
93 | bool unlock_device(char **lock_file) | ||
94 | { | ||
95 | return true; | ||
96 | } | ||
97 | |||
98 | #else | ||
99 | |||
100 | #define max_buf_len 128 | ||
101 | #define lock_path "/var/lock/LCK.." | ||
102 | |||
103 | /* Lock the device. Allocated string with a lock name is returned | ||
104 | * in lock_device | ||
105 | */ | ||
106 | GSM_Error lock_device(const char* port, char **lock_device) | ||
107 | { | ||
108 | #ifndef WIN32 | ||
109 | char *lock_file = NULL; | ||
110 | char buffer[max_buf_len]; | ||
111 | const char *aux; | ||
112 | int fd, len; | ||
113 | GSM_Errorerror = ERR_NONE; | ||
114 | |||
115 | dbgprintf("Locking device\n"); | ||
116 | |||
117 | aux = strrchr(port, '/'); | ||
118 | /* Remove leading '/' */ | ||
119 | if (aux) { | ||
120 | aux++; | ||
121 | } else { | ||
122 | /* No / in port */ | ||
123 | aux = port; | ||
124 | } | ||
125 | len = strlen(aux) + strlen(lock_path); | ||
126 | |||
127 | memset(buffer, 0, sizeof(buffer)); | ||
128 | lock_file = calloc(len + 1, 1); | ||
129 | if (!lock_file) { | ||
130 | dbgprintf("Out of memory error while locking device\n"); | ||
131 | return ERR_MOREMEMORY; | ||
132 | } | ||
133 | /* I think we don't need to use strncpy, as we should have enough | ||
134 | * buffer due to strlen results | ||
135 | */ | ||
136 | strcpy(lock_file, lock_path); | ||
137 | strcat(lock_file, aux); | ||
138 | |||
139 | /* Check for the stale lockfile. | ||
140 | * The code taken from minicom by Miquel van Smoorenburg */ | ||
141 | if ((fd = open(lock_file, O_RDONLY)) >= 0) { | ||
142 | char buf[max_buf_len]; | ||
143 | int pid, n = 0; | ||
144 | |||
145 | n = read(fd, buf, sizeof(buf) - 1); | ||
146 | close(fd); | ||
147 | if (n > 0) { | ||
148 | pid = -1; | ||
149 | if (n == 4) | ||
150 | /* Kermit-style lockfile. */ | ||
151 | pid = *(int *)buf; | ||
152 | else { | ||
153 | /* Ascii lockfile. */ | ||
154 | buf[n] = 0; | ||
155 | sscanf(buf, "%d", &pid); | ||
156 | } | ||
157 | if (pid > 0 && kill((pid_t)pid, 0) < 0 && errno == ESRCH) { | ||
158 | dbgprintf("Lockfile %s is stale. Overriding it..\n", lock_file); | ||
159 | sleep(1); | ||
160 | if (unlink(lock_file) == -1) { | ||
161 | dbgprintf("Overriding failed, please check the permissions\n"); | ||
162 | dbgprintf("Cannot lock device\n"); | ||
163 | error = ERR_PERMISSION; | ||
164 | goto failed; | ||
165 | } | ||
166 | } else { | ||
167 | dbgprintf("Device already locked by PID %d.\n", pid); | ||
168 | error = ERR_DEVICELOCKED; | ||
169 | goto failed; | ||
170 | } | ||
171 | } | ||
172 | /* this must not happen. because we could open the file */ | ||
173 | /* no wrong permissions are set. only reason could be */ | ||
174 | /* flock/lockf or a empty lockfile due to a broken binary */ | ||
175 | /* which is more likely */ | ||
176 | if (n == 0) { | ||
177 | dbgprintf("Unable to read lockfile %s.\n", lock_file); | ||
178 | dbgprintf("Please check for reason and remove the lockfile by hand.\n"); | ||
179 | dbgprintf("Cannot lock device\n"); | ||
180 | error = ERR_UNKNOWN; | ||
181 | goto failed; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | /* Try to create a new file, with 0644 mode */ | ||
186 | fd = open(lock_file, O_CREAT | O_EXCL | O_WRONLY, 0644); | ||
187 | if (fd == -1) { | ||
188 | if (errno == EEXIST) { | ||
189 | dbgprintf("Device seems to be locked by unknown process\n"); | ||
190 | error = ERR_DEVICEOPENERROR; | ||
191 | } else if (errno == EACCES) { | ||
192 | dbgprintf("Please check permission on lock directory\n"); | ||
193 | error = ERR_PERMISSION; | ||
194 | } else if (errno == ENOENT) { | ||
195 | dbgprintf("Cannot create lockfile %s. Please check for existence of path\n", lock_file); | ||
196 | error = ERR_UNKNOWN; | ||
197 | } else { | ||
198 | dbgprintf("Unknown error with creating lockfile %s\n", lock_file); | ||
199 | error = ERR_UNKNOWN; | ||
200 | } | ||
201 | goto failed; | ||
202 | } | ||
203 | sprintf(buffer, "%10ld gammu\n", (long)getpid()); | ||
204 | write(fd, buffer, strlen(buffer)); | ||
205 | close(fd); | ||
206 | *lock_device = lock_file; | ||
207 | return ERR_NONE; | ||
208 | failed: | ||
209 | free(lock_file); | ||
210 | *lock_device = 0; | ||
211 | return error; | ||
212 | #else | ||
213 | *lock_device = 0; | ||
214 | return ERR_NONE; | ||
215 | #endif | ||
216 | } | ||
217 | |||
218 | /* Removes lock and frees memory */ | ||
219 | bool unlock_device(char **lock_file) | ||
220 | { | ||
221 | #ifndef WIN32 | ||
222 | int err; | ||
223 | |||
224 | if (!lock_file) { | ||
225 | dbgprintf("Cannot unlock device\n"); | ||
226 | return false; | ||
227 | } | ||
228 | err = unlink(*lock_file); | ||
229 | free(*lock_file); | ||
230 | *lock_file = NULL; | ||
231 | return (err + 1); | ||
232 | #else | ||
233 | return true; | ||
234 | #endif | ||
235 | } | ||
236 | |||
237 | #endif | ||
238 | |||
239 | int FindSerialSpeed(char *buffer) | ||
240 | { | ||
241 | switch (atoi(buffer)) { | ||
242 | case 50 : return 50; | ||
243 | case 75 : return 75; | ||
244 | case 110: return 110; | ||
245 | case 134: return 134; | ||
246 | case 150: return 150; | ||
247 | case 200: return 200; | ||
248 | case 300: return 300; | ||
249 | case 600: return 600; | ||
250 | case 1200: return 1200; | ||
251 | case 1800: return 1800; | ||
252 | case 2400: return 2400; | ||
253 | case 4800: return 4800; | ||
254 | case 9600: return 9600; | ||
255 | case 19200: return 19200; | ||
256 | case 38400: return 38400; | ||
257 | case 57600: return 57600; | ||
258 | case 115200: return 115200; | ||
259 | case 230400: return 230400; | ||
260 | default : return 0; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | /* How should editor hadle tabs in this file? Add editor commands here. | ||
265 | * vim: noexpandtab sw=8 ts=8 sts=8: | ||
266 | */ | ||