summaryrefslogtreecommitdiffstats
path: root/serial/manager.c
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2007-05-18 15:16:21 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2007-05-18 15:16:21 +0000
commitf7544168a7628f67f98da7a7d6db63678a3d9be3 (patch)
tree8d4db6fdd22d6649252bd4c6e58baae01bbc2f1a /serial/manager.c
parentd0b45fbc214a16bcc0b13f4e37c37a8bfa96b904 (diff)
serial: keep port_open static since Connect will not be implemented
Diffstat (limited to 'serial/manager.c')
-rw-r--r--serial/manager.c66
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;