summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/device/devfunc.c
Unidiff
Diffstat (limited to 'gammu/emb/common/device/devfunc.c') (more/less context) (show whitespace changes)
-rw-r--r--gammu/emb/common/device/devfunc.c266
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
15GSM_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
28int 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
51int socket_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes, int hPhone)
52#else
53int 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
72GSM_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
87GSM_Error lock_device(const char* port, char **lock_device)
88{
89 *lock_device = 0;
90 return ERR_NONE;
91}
92
93bool 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 */
106GSM_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;
208failed:
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 */
219bool 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
239int 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 */