diff options
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; | 
