uint32_t descid;
};
-/******************* client description part for server *****************************/
+/******************* stub description for client or servers ******************/
struct afb_stub_ws
{
/* apiset */
struct afb_apiset *apiset;
+ /* on hangup callback */
+ void (*on_hangup)(struct afb_stub_ws *);
+
/* the api name */
char apiname[1];
};
}
/* send a subcall reply */
-static void client_send_subcall_reply(struct client_subcall *subcall, int iserror, json_object *object)
+static void client_send_subcall_reply(struct client_subcall *subcall, int status, json_object *object)
{
int rc;
struct writebuf wb = { .count = 0 };
- char ie = (char)!!iserror;
+ char ie = status < 0;
if (!writebuf_char(&wb, CHAR_FOR_SUBCALL_REPLY)
|| !writebuf_uint32(&wb, subcall->subcallid)
}
/* callback for subcall reply */
-static void client_subcall_reply_cb(void *closure, int iserror, json_object *object)
+static void client_subcall_reply_cb(void *closure, int status, json_object *object)
{
- client_send_subcall_reply(closure, iserror, object);
+ client_send_subcall_reply(closure, status, object);
free(closure);
}
/* on subcall reply */
static void server_on_subcall_reply(struct afb_stub_ws *stubws, struct readbuf *rb)
{
- char iserror;
+ char ie;
uint32_t subcallid;
struct json_object *object;
struct server_subcall *sc, **psc;
/* reads the call message data */
if (!readbuf_uint32(rb, &subcallid)
- || !readbuf_char(rb, &iserror)
+ || !readbuf_char(rb, &ie)
|| !readbuf_object(rb, &object)) {
/* TODO bad protocol */
return;
} else {
*psc = sc->next;
pthread_mutex_unlock(&stubws->mutex);
- sc->callback(sc->closure, (int)iserror, object);
+ sc->callback(sc->closure, -(int)ie, object);
free(sc);
}
json_object_put(object);
static void server_describe_job(int signum, void *closure)
{
- struct afb_api api;
struct json_object *obj;
struct server_describe *desc = closure;
/* get the description if possible */
- obj = NULL;
- if (!signum
- && !afb_apiset_get(desc->stubws->apiset, desc->stubws->apiname, &api)
- && api.itf->describe) {
- obj = api.itf->describe(api.closure);
- }
+ obj = !signum ? afb_apiset_describe(desc->stubws->apiset, desc->stubws->apiname) : NULL;
/* send it */
server_send_description(desc->stubws, desc->descid, obj);
if (stubws->fd >= 0) {
close(stubws->fd);
stubws->fd = -1;
+ if (stubws->on_hangup)
+ stubws->on_hangup(stubws);
}
/* release the client */
struct afb_stub_ws *afb_stub_ws_create_client(int fd, const char *apiname, struct afb_apiset *apiset)
{
- struct afb_api afb_api;
- struct afb_stub_ws *stubws;
-
- stubws = afb_stub_ws_create(fd, apiname, apiset, &stub_ws_client_ws_itf);
- if (stubws) {
- afb_api.closure = stubws;
- afb_api.itf = &ws_api_itf;
- if (afb_apiset_add(apiset, stubws->apiname, afb_api) >= 0)
- return stubws;
- afb_stub_ws_unref(stubws);
- }
- return NULL;
-
+ return afb_stub_ws_create(fd, apiname, apiset, &stub_ws_client_ws_itf);
}
struct afb_stub_ws *afb_stub_ws_create_server(int fd, const char *apiname, struct afb_apiset *apiset)
__atomic_add_fetch(&stubws->refcount, 1, __ATOMIC_RELAXED);
}
+void afb_stub_ws_on_hangup(struct afb_stub_ws *stubws, void (*on_hangup)(struct afb_stub_ws*))
+{
+ stubws->on_hangup = on_hangup;
+}
+
+const char *afb_stub_ws_name(struct afb_stub_ws *stubws)
+{
+ return stubws->apiname;
+}
+
+struct afb_api afb_stub_ws_client_api(struct afb_stub_ws *stubws)
+{
+ struct afb_api api;
+
+ assert(!stubws->listener); /* check client */
+ api.closure = stubws;
+ api.itf = &ws_api_itf;
+ return api;
+}
+
+int afb_stub_ws_client_add(struct afb_stub_ws *stubws, struct afb_apiset *apiset)
+{
+ return afb_apiset_add(apiset, stubws->apiname, afb_stub_ws_client_api(stubws));
+}
+