Imported gammu 0.90.7
[gammu.git] / common / device / devfunc.c
blobb444765244dc8a727b48cfe309fb83939915a1fa
2 #include <string.h>
3 #ifdef WIN32
4 # include <io.h>
5 #else
6 # include <errno.h>
7 # include <signal.h>
8 #endif
10 #include "../gsmstate.h"
12 #if defined (GSM_ENABLE_BLUETOOTHDEVICE) || defined (GSM_ENABLE_IRDADEVICE)
14 int socket_read(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone)
16 #ifndef WIN32
17 fd_set readfds;
19 FD_ZERO(&readfds);
20 FD_SET(hPhone, &readfds);
21 if (select(hPhone+1, &readfds, NULL, NULL, 0)) {
22 return(read(hPhone, buf, nbytes));
23 } else {
24 return 0;
26 #else
27 return(recv(hPhone, buf, nbytes, 0));
28 #endif
31 #ifdef WIN32
32 int socket_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes, int hPhone)
33 #else
34 int socket_write(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone)
35 #endif
37 int ret;
38 size_t actual = 0;
40 do {
41 if ((ret = send(hPhone, buf, nbytes - actual, 0)) < 0) return(actual);
42 actual += ret;
43 buf += ret;
44 } while (actual < nbytes);
45 return (actual);
48 GSM_Error socket_close(GSM_StateMachine *s, int hPhone)
50 shutdown(hPhone, 0);
51 #ifdef WIN32
52 closesocket(hPhone); /*FIXME: error checking */
53 #else
54 close(hPhone); /*FIXME: error checking */
55 #endif
56 return GE_NONE;
59 #endif
61 #ifdef ENABLE_LGPL
63 GSM_Error lock_device(const char* port, char **lock_device)
65 *lock_device = 0;
66 return GE_NONE;
69 bool unlock_device(char **lock_file)
71 return true;
74 #else
76 #define max_buf_len 128
77 #define lock_path "/var/lock/LCK.."
79 /* Lock the device. Allocated string with a lock name is returned
80 * in lock_device
82 GSM_Error lock_device(const char* port, char **lock_device)
84 #ifndef WIN32
85 char *lock_file = NULL;
86 char buffer[max_buf_len];
87 const char *aux;
88 int fd, len;
89 GSM_Error error = GE_NONE;
91 dbgprintf("Locking device\n");
93 aux = strrchr(port, '/');
94 /* Remove leading '/' */
95 if (aux) {
96 aux++;
97 } else {
98 /* No / in port */
99 aux = port;
101 len = strlen(aux) + strlen(lock_path);
103 memset(buffer, 0, sizeof(buffer));
104 lock_file = calloc(len + 1, 1);
105 if (!lock_file) {
106 dbgprintf("Out of memory error while locking device\n");
107 return GE_MOREMEMORY;
109 /* I think we don't need to use strncpy, as we should have enough
110 * buffer due to strlen results
112 strcpy(lock_file, lock_path);
113 strcat(lock_file, aux);
115 /* Check for the stale lockfile.
116 * The code taken from minicom by Miquel van Smoorenburg */
117 if ((fd = open(lock_file, O_RDONLY)) >= 0) {
118 char buf[max_buf_len];
119 int pid, n = 0;
121 n = read(fd, buf, sizeof(buf) - 1);
122 close(fd);
123 if (n > 0) {
124 pid = -1;
125 if (n == 4)
126 /* Kermit-style lockfile. */
127 pid = *(int *)buf;
128 else {
129 /* Ascii lockfile. */
130 buf[n] = 0;
131 sscanf(buf, "%d", &pid);
133 if (pid > 0 && kill((pid_t)pid, 0) < 0 && errno == ESRCH) {
134 dbgprintf("Lockfile %s is stale. Overriding it..\n", lock_file);
135 sleep(1);
136 if (unlink(lock_file) == -1) {
137 dbgprintf("Overriding failed, please check the permissions\n");
138 dbgprintf("Cannot lock device\n");
139 error = GE_PERMISSION;
140 goto failed;
142 } else {
143 dbgprintf("Device already locked by PID %d.\n", pid);
144 error = GE_DEVICELOCKED;
145 goto failed;
148 /* this must not happen. because we could open the file */
149 /* no wrong permissions are set. only reason could be */
150 /* flock/lockf or a empty lockfile due to a broken binary */
151 /* which is more likely */
152 if (n == 0) {
153 dbgprintf("Unable to read lockfile %s.\n", lock_file);
154 dbgprintf("Please check for reason and remove the lockfile by hand.\n");
155 dbgprintf("Cannot lock device\n");
156 error = GE_UNKNOWN;
157 goto failed;
161 /* Try to create a new file, with 0644 mode */
162 fd = open(lock_file, O_CREAT | O_EXCL | O_WRONLY, 0644);
163 if (fd == -1) {
164 if (errno == EEXIST) {
165 dbgprintf("Device seems to be locked by unknown process\n");
166 error = GE_DEVICEOPENERROR;
167 } else if (errno == EACCES) {
168 dbgprintf("Please check permission on lock directory\n");
169 error = GE_PERMISSION;
170 } else if (errno == ENOENT) {
171 dbgprintf("Cannot create lockfile %s. Please check for existence of path\n", lock_file);
172 error = GE_UNKNOWN;
173 } else {
174 dbgprintf("Unknown error with creating lockfile %s\n", lock_file);
175 error = GE_UNKNOWN;
177 goto failed;
179 sprintf(buffer, "%10ld gammu\n", (long)getpid());
180 write(fd, buffer, strlen(buffer));
181 close(fd);
182 *lock_device = lock_file;
183 return GE_NONE;
184 failed:
185 free(lock_file);
186 *lock_device = 0;
187 return error;
188 #else
189 *lock_device = 0;
190 return GE_NONE;
191 #endif
194 /* Removes lock and frees memory */
195 bool unlock_device(char **lock_file)
197 #ifndef WIN32
198 int err;
200 if (!lock_file) {
201 dbgprintf("Cannot unlock device\n");
202 return false;
204 err = unlink(*lock_file);
205 free(*lock_file);
206 *lock_file = NULL;
207 return (err + 1);
208 #else
209 return true;
210 #endif
213 #endif
215 int FindSerialSpeed(char *buffer)
217 switch (atoi(buffer)) {
218 case 50 : return 50;
219 case 75 : return 75;
220 case 110 : return 110;
221 case 134 : return 134;
222 case 150 : return 150;
223 case 200 : return 200;
224 case 300 : return 300;
225 case 600 : return 600;
226 case 1200 : return 1200;
227 case 1800 : return 1800;
228 case 2400 : return 2400;
229 case 4800 : return 4800;
230 case 9600 : return 9600;
231 case 19200 : return 19200;
232 case 38400 : return 38400;
233 case 57600 : return 57600;
234 case 115200 : return 115200;
235 case 230400 : return 230400;
236 default : return 0;
240 /* How should editor hadle tabs in this file? Add editor commands here.
241 * vim: noexpandtab sw=8 ts=8 sts=8: