X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-api-ws.c;h=c1ccd3297162fe270b93bfc657b341bbe9445dcf;hb=4f7f5ae8e1907b23cb74178dea68790a6fa963fe;hp=1a46358764166a9d2dabde8a5f6ceb761a576d7a;hpb=adb89e71f1c366b0cabdf9e04aaed60b84a96f0e;p=src%2Fapp-framework-binder.git diff --git a/src/afb-api-ws.c b/src/afb-api-ws.c index 1a463587..c1ccd329 100644 --- a/src/afb-api-ws.c +++ b/src/afb-api-ws.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" + * Copyright (C) 2015-2018 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,20 +30,20 @@ #include #include -#include +#include "afb-fdev.h" +#include "afb-systemd.h" #include "afb-api.h" #include "afb-apiset.h" -#include "afb-common.h" +#include "afb-api-ws.h" #include "afb-stub-ws.h" #include "verbose.h" -#include "sd-fds.h" +#include "fdev.h" struct api_ws { char *path; /* path of the object for the API */ char *api; /* api name of the interface */ - int fd; /* file descriptor */ - sd_event_source *listensrc; /**< systemd source for server socket */ + struct fdev *fdev; /* fdev handler */ struct afb_apiset *apiset; }; @@ -78,7 +78,6 @@ static struct api_ws *api_ws_make(const char *path) goto error2; } - api->fd = -1; return api; error2: @@ -177,7 +176,7 @@ static int api_ws_socket(const char *path, int server) /* check for systemd socket */ if (0 == strncmp(path, "sd:", 3)) - fd = sd_fds_for(path + 3); + fd = afb_systemd_fds_for(path + 3); else { /* check for unix socket */ if (0 == strncmp(path, "unix:", 5)) @@ -201,9 +200,27 @@ static int api_ws_socket(const char *path, int server) return fd; } +static struct fdev *api_ws_socket_fdev(const char *path, int server) +{ + int fd; + struct fdev *fdev; + + fd = api_ws_socket(path, server); + if (fd < 0) + fdev = 0; + else { + fdev = afb_fdev_create(fd); + if (!fdev) + close(fd); + } + if (!fdev) + ERROR("can't make %s socket for %s", server ? "server" : "client", path); + return fdev; +} + /**********************************************************************************/ -int afb_api_ws_add_client(const char *path, struct afb_apiset *apiset, int strong) +int afb_api_ws_add_client(const char *path, struct afb_apiset *declare_set, struct afb_apiset *call_set, int strong) { struct api_ws *apiws; struct afb_stub_ws *stubws; @@ -214,46 +231,42 @@ int afb_api_ws_add_client(const char *path, struct afb_apiset *apiset, int stron goto error; /* connect to the service */ - apiws->fd = api_ws_socket(apiws->path, 0); - if (apiws->fd < 0) { - ERROR("can't connect to ws service %s", apiws->path); + apiws->fdev = api_ws_socket_fdev(apiws->path, 0); + if (!apiws->fdev) goto error2; - } - stubws = afb_stub_ws_create_client(apiws->fd, apiws->api, apiset); + stubws = afb_stub_ws_create_client(apiws->fdev, apiws->api, call_set); if (!stubws) { ERROR("can't setup client ws service to %s", apiws->path); goto error3; } - if (afb_stub_ws_client_add(stubws, apiset) < 0) { + if (afb_stub_ws_client_add(stubws, declare_set) < 0) { ERROR("can't add the client to the apiset for service %s", apiws->path); - goto error4; + goto error3; } free(apiws); return 0; -error4: - afb_stub_ws_unref(stubws); error3: - close(apiws->fd); + afb_stub_ws_unref(stubws); error2: free(apiws); error: return -!!strong; } -int afb_api_ws_add_client_strong(const char *path, struct afb_apiset *apiset) +int afb_api_ws_add_client_strong(const char *path, struct afb_apiset *declare_set, struct afb_apiset *call_set) { - return afb_api_ws_add_client(path, apiset, 1); + return afb_api_ws_add_client(path, declare_set, call_set, 1); } -int afb_api_ws_add_client_weak(const char *path, struct afb_apiset *apiset) +int afb_api_ws_add_client_weak(const char *path, struct afb_apiset *declare_set, struct afb_apiset *call_set) { - return afb_api_ws_add_client(path, apiset, 0); + return afb_api_ws_add_client(path, declare_set, call_set, 0); } -static int api_ws_server_accept_client(struct api_ws *apiws, int fd) +static int api_ws_server_accept_client(struct api_ws *apiws, struct fdev *fdev) { - return -!afb_stub_ws_create_server(fd, apiws->api, apiws->apiset); + return -!afb_stub_ws_create_server(fdev, apiws->api, apiws->apiset); } static void api_ws_server_accept(struct api_ws *apiws) @@ -261,20 +274,28 @@ static void api_ws_server_accept(struct api_ws *apiws) int rc, fd; struct sockaddr addr; socklen_t lenaddr; + struct fdev *fdev; lenaddr = (socklen_t)sizeof addr; - fd = accept(apiws->fd, &addr, &lenaddr); - if (fd >= 0) { - rc = api_ws_server_accept_client(apiws, fd); - if (rc >= 0) - return; - close(fd); + fd = accept(fdev_fd(apiws->fdev), &addr, &lenaddr); + if (fd < 0) { + ERROR("can't accept connection to %s: %m", apiws->path); + } else { + fdev = afb_fdev_create(fd); + if (!fdev) { + ERROR("can't hold accepted connection to %s: %m", apiws->path); + close(fd); + } else { + rc = api_ws_server_accept_client(apiws, fdev); + if (rc < 0) + ERROR("can't serve accepted connection to %s: %m", apiws->path); + } } } static int api_ws_server_connect(struct api_ws *apiws); -static int api_ws_server_listen_callback(sd_event_source *src, int fd, uint32_t revents, void *closure) +static void api_ws_server_listen_callback(void *closure, uint32_t revents, struct fdev *fdev) { struct api_ws *apiws = closure; @@ -282,48 +303,34 @@ static int api_ws_server_listen_callback(sd_event_source *src, int fd, uint32_t api_ws_server_accept(apiws); if ((revents & EPOLLHUP) != 0) api_ws_server_connect(apiws); - return 0; } static void api_ws_server_disconnect(struct api_ws *apiws) { - if (apiws->listensrc != NULL) { - sd_event_source_unref(apiws->listensrc); - apiws->listensrc = NULL; - } - if (apiws->fd >= 0) { - close(apiws->fd); - apiws->fd = -1; - } + fdev_unref(apiws->fdev); + apiws->fdev = 0; } static int api_ws_server_connect(struct api_ws *apiws) { - int rc; - /* ensure disconnected */ api_ws_server_disconnect(apiws); /* request the service object name */ - apiws->fd = api_ws_socket(apiws->path, 1); - if (apiws->fd < 0) + apiws->fdev = api_ws_socket_fdev(apiws->path, 1); + if (!apiws->fdev) ERROR("can't create socket %s", apiws->path); else { /* listen for service */ - rc = sd_event_add_io(afb_common_get_event_loop(), - &apiws->listensrc, apiws->fd, EPOLLIN, - api_ws_server_listen_callback, apiws); - if (rc >= 0) - return 0; - close(apiws->fd); - errno = -rc; - ERROR("can't add ws object %s", apiws->path); + fdev_set_events(apiws->fdev, EPOLLIN); + fdev_set_callback(apiws->fdev, api_ws_server_listen_callback, apiws); + return 0; } return -1; } /* create the service */ -int afb_api_ws_add_server(const char *path, struct afb_apiset *apiset) +int afb_api_ws_add_server(const char *path, struct afb_apiset *declare_set, struct afb_apiset *call_set) { int rc; struct api_ws *apiws; @@ -334,7 +341,7 @@ int afb_api_ws_add_server(const char *path, struct afb_apiset *apiset) goto error; /* check api name */ - if (!afb_apiset_lookup(apiset, apiws->api, 1)) { + if (!afb_apiset_lookup(call_set, apiws->api, 1)) { ERROR("Can't provide ws-server for %s: API %s doesn't exist", path, apiws->api); goto error2; } @@ -344,7 +351,7 @@ int afb_api_ws_add_server(const char *path, struct afb_apiset *apiset) if (rc < 0) goto error2; - apiws->apiset = afb_apiset_addref(apiset); + apiws->apiset = afb_apiset_addref(call_set); return 0; error2: