summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/device/devfunc.c
Side-by-side diff
Diffstat (limited to 'gammu/emb/common/device/devfunc.c') (more/less context) (ignore 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 @@
+
+#include <string.h>
+#ifdef WIN32
+# include <io.h>
+#else
+# include <errno.h>
+# include <signal.h>
+#endif
+
+#include "../gsmstate.h"
+
+#ifdef GSM_ENABLE_BLUETOOTHDEVICE
+#ifdef BLUETOOTH_RF_SEARCHING
+
+GSM_Error bluetooth_checkservicename(GSM_StateMachine *s, char *name)
+{
+ if (s->ConnectionType == GCT_BLUEPHONET && strstr(name,"Nokia PC Suite")!=NULL) return ERR_NONE;
+ if (s->ConnectionType == GCT_BLUEOBEX && strstr(name,"OBEX") !=NULL) return ERR_NONE;
+ if (s->ConnectionType == GCT_BLUEAT && strstr(name,"COM 1") !=NULL) return ERR_NONE;
+ return ERR_UNKNOWN;
+}
+
+#endif
+#endif
+
+#if defined (GSM_ENABLE_BLUETOOTHDEVICE) || defined (GSM_ENABLE_IRDADEVICE)
+
+int socket_read(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone)
+{
+ fd_set readfds;
+#ifdef WIN32
+ struct timeval timer;
+#endif
+
+ FD_ZERO(&readfds);
+ FD_SET(hPhone, &readfds);
+#ifndef WIN32
+ if (select(hPhone+1, &readfds, NULL, NULL, 0)) {
+ return(read(hPhone, buf, nbytes));
+ }
+#else
+ memset(&timer,0,sizeof(timer));
+ if (select(0, &readfds, NULL, NULL, &timer) != 0) {
+ return(recv(hPhone, buf, nbytes, 0));
+ }
+#endif
+ return 0;
+}
+
+#ifdef WIN32
+int socket_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes, int hPhone)
+#else
+int socket_write(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone)
+#endif
+{
+ int ret;
+ size_t actual = 0;
+
+ do {
+ ret = send(hPhone, buf, nbytes - actual, 0);
+ if (ret < 0) {
+ if (actual != nbytes) GSM_OSErrorInfo(s,"socket_write");
+ return actual;
+ }
+ actual += ret;
+ buf += ret;
+ } while (actual < nbytes);
+
+ return actual;
+}
+
+GSM_Error socket_close(GSM_StateMachine *s, int hPhone)
+{
+ shutdown(hPhone, 0);
+#ifdef WIN32
+ closesocket(hPhone); /*FIXME: error checking */
+#else
+ close(hPhone); /*FIXME: error checking */
+#endif
+ return ERR_NONE;
+}
+
+#endif
+
+#ifdef ENABLE_LGPL
+
+GSM_Error lock_device(const char* port, char **lock_device)
+{
+ *lock_device = 0;
+ return ERR_NONE;
+}
+
+bool unlock_device(char **lock_file)
+{
+ return true;
+}
+
+#else
+
+#define max_buf_len 128
+#define lock_path "/var/lock/LCK.."
+
+/* Lock the device. Allocated string with a lock name is returned
+ * in lock_device
+ */
+GSM_Error lock_device(const char* port, char **lock_device)
+{
+#ifndef WIN32
+ char *lock_file = NULL;
+ char buffer[max_buf_len];
+ const char *aux;
+ int fd, len;
+ GSM_Error error = ERR_NONE;
+
+ dbgprintf("Locking device\n");
+
+ aux = strrchr(port, '/');
+ /* Remove leading '/' */
+ if (aux) {
+ aux++;
+ } else {
+ /* No / in port */
+ aux = port;
+ }
+ len = strlen(aux) + strlen(lock_path);
+
+ memset(buffer, 0, sizeof(buffer));
+ lock_file = calloc(len + 1, 1);
+ if (!lock_file) {
+ dbgprintf("Out of memory error while locking device\n");
+ return ERR_MOREMEMORY;
+ }
+ /* I think we don't need to use strncpy, as we should have enough
+ * buffer due to strlen results
+ */
+ strcpy(lock_file, lock_path);
+ strcat(lock_file, aux);
+
+ /* Check for the stale lockfile.
+ * The code taken from minicom by Miquel van Smoorenburg */
+ if ((fd = open(lock_file, O_RDONLY)) >= 0) {
+ char buf[max_buf_len];
+ int pid, n = 0;
+
+ n = read(fd, buf, sizeof(buf) - 1);
+ close(fd);
+ if (n > 0) {
+ pid = -1;
+ if (n == 4)
+ /* Kermit-style lockfile. */
+ pid = *(int *)buf;
+ else {
+ /* Ascii lockfile. */
+ buf[n] = 0;
+ sscanf(buf, "%d", &pid);
+ }
+ if (pid > 0 && kill((pid_t)pid, 0) < 0 && errno == ESRCH) {
+ dbgprintf("Lockfile %s is stale. Overriding it..\n", lock_file);
+ sleep(1);
+ if (unlink(lock_file) == -1) {
+ dbgprintf("Overriding failed, please check the permissions\n");
+ dbgprintf("Cannot lock device\n");
+ error = ERR_PERMISSION;
+ goto failed;
+ }
+ } else {
+ dbgprintf("Device already locked by PID %d.\n", pid);
+ error = ERR_DEVICELOCKED;
+ goto failed;
+ }
+ }
+ /* this must not happen. because we could open the file */
+ /* no wrong permissions are set. only reason could be */
+ /* flock/lockf or a empty lockfile due to a broken binary */
+ /* which is more likely */
+ if (n == 0) {
+ dbgprintf("Unable to read lockfile %s.\n", lock_file);
+ dbgprintf("Please check for reason and remove the lockfile by hand.\n");
+ dbgprintf("Cannot lock device\n");
+ error = ERR_UNKNOWN;
+ goto failed;
+ }
+ }
+
+ /* Try to create a new file, with 0644 mode */
+ fd = open(lock_file, O_CREAT | O_EXCL | O_WRONLY, 0644);
+ if (fd == -1) {
+ if (errno == EEXIST) {
+ dbgprintf("Device seems to be locked by unknown process\n");
+ error = ERR_DEVICEOPENERROR;
+ } else if (errno == EACCES) {
+ dbgprintf("Please check permission on lock directory\n");
+ error = ERR_PERMISSION;
+ } else if (errno == ENOENT) {
+ dbgprintf("Cannot create lockfile %s. Please check for existence of path\n", lock_file);
+ error = ERR_UNKNOWN;
+ } else {
+ dbgprintf("Unknown error with creating lockfile %s\n", lock_file);
+ error = ERR_UNKNOWN;
+ }
+ goto failed;
+ }
+ sprintf(buffer, "%10ld gammu\n", (long)getpid());
+ write(fd, buffer, strlen(buffer));
+ close(fd);
+ *lock_device = lock_file;
+ return ERR_NONE;
+failed:
+ free(lock_file);
+ *lock_device = 0;
+ return error;
+#else
+ *lock_device = 0;
+ return ERR_NONE;
+#endif
+}
+
+/* Removes lock and frees memory */
+bool unlock_device(char **lock_file)
+{
+#ifndef WIN32
+ int err;
+
+ if (!lock_file) {
+ dbgprintf("Cannot unlock device\n");
+ return false;
+ }
+ err = unlink(*lock_file);
+ free(*lock_file);
+ *lock_file = NULL;
+ return (err + 1);
+#else
+ return true;
+#endif
+}
+
+#endif
+
+int FindSerialSpeed(char *buffer)
+{
+ switch (atoi(buffer)) {
+ case 50 : return 50;
+ case 75 : return 75;
+ case 110 : return 110;
+ case 134 : return 134;
+ case 150 : return 150;
+ case 200 : return 200;
+ case 300 : return 300;
+ case 600 : return 600;
+ case 1200 : return 1200;
+ case 1800 : return 1800;
+ case 2400 : return 2400;
+ case 4800 : return 4800;
+ case 9600 : return 9600;
+ case 19200 : return 19200;
+ case 38400 : return 38400;
+ case 57600 : return 57600;
+ case 115200 : return 115200;
+ case 230400 : return 230400;
+ default : return 0;
+ }
+}
+
+/* How should editor hadle tabs in this file? Add editor commands here.
+ * vim: noexpandtab sw=8 ts=8 sts=8:
+ */