diff options
author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-18 15:16:21 +0000 |
---|---|---|
committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-05-18 15:16:21 +0000 |
commit | f7544168a7628f67f98da7a7d6db63678a3d9be3 (patch) | |
tree | 8d4db6fdd22d6649252bd4c6e58baae01bbc2f1a /serial/manager.c | |
parent | d0b45fbc214a16bcc0b13f4e37c37a8bfa96b904 (diff) |
serial: keep port_open static since Connect will not be implemented
Diffstat (limited to 'serial/manager.c')
-rw-r--r-- | serial/manager.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/serial/manager.c b/serial/manager.c index 6b60423d..bd0362df 100644 --- a/serial/manager.c +++ b/serial/manager.c @@ -57,6 +57,10 @@ #define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB" +/* Waiting for udev to create the device node */ +#define MAX_OPEN_TRIES 5 +#define OPEN_WAIT 300 /* ms */ + struct pending_connect { DBusConnection *conn; DBusMessage *msg; @@ -89,6 +93,16 @@ static struct { { NULL } }; +typedef void (*open_notify_t) (int fd, int err, void *data); +typedef void (*udata_free_t) (void *data); +struct open_context { + char *dev; + open_notify_t notify; + udata_free_t ufree; + void *udata; + int ntries; +}; + static DBusConnection *connection = NULL; static GSList *pending_connects = NULL; static int rfcomm_ctl = -1; @@ -130,6 +144,58 @@ static struct pending_connect *find_pending_connect_by_pattern(const char *bda, return NULL; } +static gboolean open_continue(struct open_context *oc) +{ + int fd; + + fd = open(oc->dev, O_RDONLY | O_NOCTTY); + if (fd < 0) { + int err = errno; + error("Could not open %s: %s (%d)", + oc->dev, strerror(err), err); + if (++oc->ntries >= MAX_OPEN_TRIES) { + /* Reporting error */ + oc->notify(fd, err, oc->udata); + return FALSE; + } + return TRUE; + } + /* Connection succeeded */ + oc->notify(fd, 0, oc->udata); + return FALSE; +} + +static void open_context_free(void *data) +{ + struct open_context *oc = data; + + if (oc->ufree) + oc->ufree(oc->udata); + g_free(oc->dev); + g_free(oc); +} + +int port_open(const char *dev, open_notify_t notify, + void *udata, udata_free_t ufree) +{ + int fd; + + fd = open(dev, O_RDONLY | O_NOCTTY); + if (fd < 0) { + struct open_context *oc; + oc = g_new0(struct open_context, 1); + oc->dev = g_strdup(dev); + oc->notify = notify; + oc->ufree = ufree; + oc->udata = udata; + g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, OPEN_WAIT, + (GSourceFunc) open_continue, oc, open_context_free); + return -EINPROGRESS; + } + + return fd; +} + static uint16_t str2class(const char *pattern) { int i; |