#include "afb-cred.h"
#include "afb-ws.h"
#include "afb-msg-json.h"
-#include "afb-apis.h"
+#include "afb-api.h"
+#include "afb-apiset.h"
#include "afb-api-so.h"
#include "afb-context.h"
#include "afb-evt.h"
pthread_mutex_t mutex; /**< resource control */
union {
struct {
- uint32_t id;
struct afb_ws *ws;
struct api_ws_event *events;
struct api_ws_memo *memos;
} client;
struct {
sd_event_source *listensrc; /**< systemd source for server socket */
+ struct afb_apiset *apiset;
} server;
};
};
#define RETERR 2
#define RETRAW 3
+/******************* common usefull tools **********************************/
+
+/**
+ * translate a pointer to some integer
+ * @param ptr the pointer to translate
+ * @return an integer
+ */
+static inline uint32_t ptr2id(void *ptr)
+{
+ return (uint32_t)(((intptr_t)ptr) >> 6);
+}
+
/******************* websocket interface for client part **********************************/
static void api_ws_client_on_binary(void *closure, char *data, size_t size);
/* pending subcalls */
struct api_ws_subcall *subcalls;
+
+ /* apiset */
+ struct afb_apiset *apiset;
};
/******************* websocket interface for client part **********************************/
while (length && path[length - 1] != '/' && path[length - 1] != ':')
length = length - 1;
api->api = &api->path[length];
- if (api->api == NULL || !afb_apis_is_valid_api_name(api->api)) {
+ if (api->api == NULL || !afb_api_is_valid_name(api->api)) {
errno = EINVAL;
goto error2;
}
return -1;
}
- if (server)
+ if (server && path[0] != '@')
unlink(path);
fd = socket(AF_UNIX, SOCK_STREAM, 0);
memset(&addr, 0, sizeof addr);
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, path);
+ if (addr.sun_path[0] == '@')
+ addr.sun_path[0] = 0; /* implement abstract sockets */
if (server) {
rc = bind(fd, (struct sockaddr *) &addr, (socklen_t)(sizeof addr));
} else {
if (memo != NULL) {
afb_xreq_addref(xreq);
memo->xreq = xreq;
- do { memo->msgid = ++api->client.id; } while(api_ws_client_memo_search(api, memo->msgid) != NULL);
+ memo->msgid = ptr2id(memo);
+ while(api_ws_client_memo_search(api, memo->msgid) != NULL)
+ memo->msgid++;
memo->api = api;
memo->next = api->client.memos;
api->client.memos = memo;
pthread_mutex_unlock(&apiws->mutex);
}
-static int api_ws_service_start_cb(void *closure, int share_session, int onneed)
-{
- struct api_ws *api = closure;
-
- /* not an error when onneed */
- if (onneed != 0)
- return 0;
-
- /* already started: it is an error */
- ERROR("The WS binding %s is not a startable service", api->path);
- return -1;
-}
-
/* */
static void api_ws_client_disconnect(struct api_ws *api)
{
}
static struct afb_api_itf ws_api_itf = {
- .call = api_ws_client_call_cb,
- .service_start = api_ws_service_start_cb
+ .call = api_ws_client_call_cb
};
/* adds a afb-ws-service client api */
-int afb_api_ws_add_client(const char *path)
+int afb_api_ws_add_client(const char *path, struct afb_apiset *apiset)
{
int rc;
struct api_ws *api;
/* record it as an API */
afb_api.closure = api;
afb_api.itf = &ws_api_itf;
- if (afb_apis_add(api->api, afb_api) < 0)
+ if (afb_apiset_add(apiset, api->api, afb_api) < 0)
goto error3;
return 0;
free(sc);
}
afb_cred_unref(client->cred);
+ afb_apiset_unref(client->apiset);
free(client);
}
}
wreq->xreq.api = client->api;
wreq->xreq.verb = cverb;
wreq->xreq.json = object;
- afb_apis_call(&wreq->xreq);
- afb_xreq_unref(&wreq->xreq);
+ afb_xreq_process(&wreq->xreq, client->apiset);
return;
unconnected:
client->ws = afb_ws_create(afb_common_get_event_loop(), client->fd, &api_ws_server_ws_itf, client);
if (client->ws != NULL) {
client->api = api->api;
+ client->apiset = afb_apiset_addref(api->server.apiset);
client->refcount = 1;
client->subcalls = NULL;
return;
sc->closure = cb_closure;
pthread_mutex_unlock(&client->mutex);
- sc->subcallid = (uint32_t)(((intptr_t)sc) >> 6);
+ sc->subcallid = ptr2id(sc);
do {
sc->subcallid++;
osc = client->subcalls;
}
/* create the service */
-int afb_api_ws_add_server(const char *path)
+int afb_api_ws_add_server(const char *path, struct afb_apiset *apiset)
{
int rc;
struct api_ws *api;
if (rc < 0)
goto error2;
+ api->server.apiset = afb_apiset_addref(apiset);
return 0;
error2: