add auto (re)connect logic to libubus
authorJohn Crispin <blogic@openwrt.org>
Wed, 22 Jan 2014 13:53:11 +0000 (13:53 +0000)
committerJohn Crispin <blogic@openwrt.org>
Wed, 22 Jan 2014 13:53:11 +0000 (13:53 +0000)
Signed-off-by: John Crispin <blogic@openwrt.org>
libubus.c
libubus.h

index c6e956aa8b1ca5fd0d08a88d2e4fc5131cb7e9e2..e435200150ef02c48be73c25fd693b366cd7a515 100644 (file)
--- a/libubus.c
+++ b/libubus.c
@@ -267,14 +267,8 @@ static void ubus_default_connection_lost(struct ubus_context *ctx)
                uloop_end();
 }
 
-struct ubus_context *ubus_connect(const char *path)
+static int _ubus_connect(struct ubus_context *ctx, const char *path)
 {
-       struct ubus_context *ctx;
-
-       ctx = calloc(1, sizeof(*ctx));
-       if (!ctx)
-               return NULL;
-
        ctx->sock.fd = -1;
        ctx->sock.cb = ubus_handle_data;
        ctx->connection_lost = ubus_default_connection_lost;
@@ -282,7 +276,60 @@ struct ubus_context *ubus_connect(const char *path)
        INIT_LIST_HEAD(&ctx->requests);
        INIT_LIST_HEAD(&ctx->pending);
        avl_init(&ctx->objects, ubus_cmp_id, false, NULL);
-       if (ubus_reconnect(ctx, path)) {
+       if (ubus_reconnect(ctx, path))
+               return -1;
+
+       return 0;
+}
+
+static void ubus_auto_reconnect_cb(struct uloop_timeout *timeout)
+{
+       struct ubus_auto_conn *conn = container_of(timeout, struct ubus_auto_conn, timer);
+
+       if (!ubus_reconnect(&conn->ctx, conn->path))
+               ubus_add_uloop(&conn->ctx);
+       else
+               uloop_timeout_set(timeout, 1000);
+}
+
+static void ubus_auto_disconnect_cb(struct ubus_context *ctx)
+{
+       struct ubus_auto_conn *conn = container_of(ctx, struct ubus_auto_conn, ctx);
+
+       conn->timer.cb = ubus_auto_reconnect_cb;
+       uloop_timeout_set(&conn->timer, 1000);
+}
+
+static void ubus_auto_connect_cb(struct uloop_timeout *timeout)
+{
+       struct ubus_auto_conn *conn = container_of(timeout, struct ubus_auto_conn, timer);
+
+       if (_ubus_connect(&conn->ctx, conn->path)) {
+               uloop_timeout_set(timeout, 1000);
+               fprintf(stderr, "failed to connect to ubus\n");
+               return;
+       }
+       conn->ctx.connection_lost = ubus_auto_disconnect_cb;
+       if (conn->cb)
+               conn->cb(&conn->ctx);
+       ubus_add_uloop(&conn->ctx);
+}
+
+void ubus_auto_connect(struct ubus_auto_conn *conn)
+{
+       conn->timer.cb = ubus_auto_connect_cb;
+       ubus_auto_connect_cb(&conn->timer);
+}
+
+struct ubus_context *ubus_connect(const char *path)
+{
+       struct ubus_context *ctx;
+
+       ctx = calloc(1, sizeof(*ctx));
+       if (!ctx)
+               return NULL;
+
+       if (_ubus_connect(ctx, path)) {
                free(ctx);
                ctx = NULL;
        }
index f899ded49658aed9176931742ddcc8a7618fb3d9..0c97436df6e9a3c514a0200d6aa85c63b208d9e8 100644 (file)
--- a/libubus.h
+++ b/libubus.h
@@ -56,6 +56,7 @@ typedef void (*ubus_data_handler_t)(struct ubus_request *req,
 typedef void (*ubus_complete_handler_t)(struct ubus_request *req, int ret);
 typedef void (*ubus_notify_complete_handler_t)(struct ubus_notify_request *req,
                                               int idx, int ret);
+typedef void (*ubus_connect_handler_t)(struct ubus_context *ctx);
 
 #define UBUS_OBJECT_TYPE(_name, _methods)              \
        {                                               \
@@ -188,7 +189,15 @@ struct ubus_notify_request {
        uint32_t id[UBUS_MAX_NOTIFY_PEERS + 1];
 };
 
+struct ubus_auto_conn {
+       struct ubus_context ctx;
+       struct uloop_timeout timer;
+       const char *path;
+       ubus_connect_handler_t cb;
+};
+
 struct ubus_context *ubus_connect(const char *path);
+void ubus_auto_connect(struct ubus_auto_conn *conn);
 int ubus_reconnect(struct ubus_context *ctx, const char *path);
 void ubus_free(struct ubus_context *ctx);