X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-api-ws.c;h=6e4a890fe33ed58a0e01d94f955c53d45b87d1cd;hb=6e5acd75aee411a530c1f86fe4653e017ba0125a;hp=5c3dcd4764a5a9ee23b4e45d3b6a5537f2f15c71;hpb=0b838a6101edc810098ee0645d3bfd966096ae07;p=src%2Fapp-framework-binder.git diff --git a/src/afb-api-ws.c b/src/afb-api-ws.c index 5c3dcd47..6e4a890f 100644 --- a/src/afb-api-ws.c +++ b/src/afb-api-ws.c @@ -38,6 +38,7 @@ #include "afb-common.h" #include "afb-session.h" +#include "afb-cred.h" #include "afb-ws.h" #include "afb-msg-json.h" #include "afb-apis.h" @@ -52,7 +53,14 @@ struct api_ws_memo; struct api_ws_event; struct api_ws_client; - +#define CHAR_FOR_ANSWER_SUCCESS 'T' +#define CHAR_FOR_ANSWER_FAIL 'F' +#define CHAR_FOR_EVT_BROADCAST '*' +#define CHAR_FOR_EVT_ADD '+' +#define CHAR_FOR_EVT_DEL '-' +#define CHAR_FOR_EVT_PUSH '!' +#define CHAR_FOR_EVT_SUBSCRIBE 'S' +#define CHAR_FOR_EVT_UNSUBSCRIBE 'U' /* */ @@ -125,6 +133,9 @@ struct api_ws_client /* websocket */ struct afb_ws *ws; + + /* credentials */ + struct afb_cred *cred; }; /******************* websocket interface for client part **********************************/ @@ -155,11 +166,11 @@ struct api_ws_server_req { uint32_t msgid; /* the incoming request msgid */ }; -static void api_ws_server_req_success_cb(void *closure, struct json_object *obj, const char *info); -static void api_ws_server_req_fail_cb(void *closure, const char *status, const char *info); -static void api_ws_server_req_destroy_cb(void *closure); -static int api_ws_server_req_subscribe_cb(void *closure, struct afb_event event); -static int api_ws_server_req_unsubscribe_cb(void *closure, struct afb_event event); +static void api_ws_server_req_success_cb(struct afb_xreq *xreq, struct json_object *obj, const char *info); +static void api_ws_server_req_fail_cb(struct afb_xreq *xreq, const char *status, const char *info); +static void api_ws_server_req_destroy_cb(struct afb_xreq *xreq); +static int api_ws_server_req_subscribe_cb(struct afb_xreq *xreq, struct afb_event event); +static int api_ws_server_req_unsubscribe_cb(struct afb_xreq *xreq, struct afb_event event); const struct afb_xreq_query_itf afb_api_ws_xreq_itf = { .success = api_ws_server_req_success_cb, @@ -733,28 +744,28 @@ static void api_ws_client_on_binary(void *closure, char *data, size_t size) if (size > 0) { struct readbuf rb = { .head = data, .end = data + size }; switch (*rb.head++) { - case 'T': /* success */ + case CHAR_FOR_ANSWER_SUCCESS: /* success */ api_ws_client_reply_success(closure, &rb); break; - case 'F': /* fail */ + case CHAR_FOR_ANSWER_FAIL: /* fail */ api_ws_client_reply_fail(closure, &rb); break; - case '*': /* broadcast */ + case CHAR_FOR_EVT_BROADCAST: /* broadcast */ api_ws_client_event_broadcast(closure, &rb); break; - case '+': /* creates the event */ + case CHAR_FOR_EVT_ADD: /* creates the event */ api_ws_client_event_create(closure, &rb); break; - case '-': /* drops the event */ + case CHAR_FOR_EVT_DEL: /* drops the event */ api_ws_client_event_drop(closure, &rb); break; - case '!': /* pushs the event */ + case CHAR_FOR_EVT_PUSH: /* pushs the event */ api_ws_client_event_push(closure, &rb); break; - case 'S': /* subscribe event for a request */ + case CHAR_FOR_EVT_SUBSCRIBE: /* subscribe event for a request */ api_ws_client_event_subscribe(closure, &rb); break; - case 'U': /* unsubscribe event for a request */ + case CHAR_FOR_EVT_UNSUBSCRIBE: /* unsubscribe event for a request */ api_ws_client_event_unsubscribe(closure, &rb); break; default: /* unexpected message */ @@ -856,6 +867,11 @@ static int api_ws_client_connect(struct api_ws *api) return -1; } +static struct afb_api_itf ws_api_itf = { + .call = api_ws_client_call_cb, + .service_start = api_ws_service_start_cb +}; + /* adds a afb-ws-service client api */ int afb_api_ws_add_client(const char *path) { @@ -877,8 +893,7 @@ int afb_api_ws_add_client(const char *path) /* record it as an API */ afb_api.closure = api; - afb_api.call = api_ws_client_call_cb; - afb_api.service_start = api_ws_service_start_cb; + afb_api.itf = &ws_api_itf; if (afb_apis_add(api->api, afb_api) < 0) goto error3; @@ -899,6 +914,7 @@ static void api_ws_server_client_unref(struct api_ws_client *client) if (!--client->refcount) { afb_evt_listener_unref(client->listener); afb_ws_destroy(client->ws); + afb_cred_unref(client->cred); free(client); } } @@ -928,6 +944,7 @@ static void api_ws_server_called(struct api_ws_client *client, struct readbuf *r || !api_ws_read_string(rb, &wreq->request, &wreq->lenreq)) goto overflow; + afb_xreq_init(&wreq->xreq, &afb_api_ws_xreq_itf); wreq->xreq.json = json_tokener_parse(wreq->request); if (wreq->xreq.json == NULL && strcmp(wreq->request, "null")) { wreq->xreq.json = json_object_new_string(wreq->request); @@ -939,11 +956,9 @@ static void api_ws_server_called(struct api_ws_client *client, struct readbuf *r wreq->xreq.context.flags = flags; /* makes the call */ - wreq->xreq.refcount = 1; + wreq->xreq.cred = afb_cred_addref(client->cred); wreq->xreq.api = client->api; wreq->xreq.verb = verb; - wreq->xreq.query = wreq; - wreq->xreq.queryitf = &afb_api_ws_xreq_itf; afb_apis_call(&wreq->xreq); afb_xreq_unref(&wreq->xreq); return; @@ -990,6 +1005,7 @@ static void api_ws_server_accept(struct api_ws *api) lenaddr = (socklen_t)sizeof addr; client->fd = accept(api->fd, &addr, &lenaddr); if (client->fd >= 0) { + client->cred = afb_cred_create_for_socket(client->fd); fcntl(client->fd, F_SETFD, FD_CLOEXEC); fcntl(client->fd, F_SETFL, O_NONBLOCK); client->ws = afb_ws_create(afb_common_get_event_loop(), client->fd, &api_ws_server_ws_itf, client); @@ -998,6 +1014,7 @@ static void api_ws_server_accept(struct api_ws *api) client->refcount = 1; return; } + afb_cred_unref(client->cred); close(client->fd); } afb_evt_listener_unref(client->listener); @@ -1026,18 +1043,18 @@ static void api_ws_server_event_send(struct api_ws_client *client, char order, c static void api_ws_server_event_add(void *closure, const char *event, int eventid) { - api_ws_server_event_send(closure, '+', event, eventid, NULL); + api_ws_server_event_send(closure, CHAR_FOR_EVT_ADD, event, eventid, NULL); } static void api_ws_server_event_remove(void *closure, const char *event, int eventid) { - api_ws_server_event_send(closure, '-', event, eventid, NULL); + api_ws_server_event_send(closure, CHAR_FOR_EVT_DEL, event, eventid, NULL); } static void api_ws_server_event_push(void *closure, const char *event, int eventid, struct json_object *object) { const char *data = json_object_to_json_string_ext(object, JSON_C_TO_STRING_PLAIN); - api_ws_server_event_send(closure, '!', event, eventid, data ? : "null"); + api_ws_server_event_send(closure, CHAR_FOR_EVT_PUSH, event, eventid, data ? : "null"); json_object_put(object); } @@ -1048,7 +1065,7 @@ static void api_ws_server_event_broadcast(void *closure, const char *event, int struct writebuf wb = { .count = 0 }; - if (api_ws_write_char(&wb, '*') && api_ws_write_string(&wb, event) && api_ws_write_object(&wb, object)) { + if (api_ws_write_char(&wb, CHAR_FOR_EVT_BROADCAST) && api_ws_write_string(&wb, event) && api_ws_write_object(&wb, object)) { rc = afb_ws_binary_v(client->ws, wb.iovec, wb.count); if (rc < 0) ERROR("error while broadcasting event %s", event); @@ -1060,24 +1077,25 @@ static void api_ws_server_event_broadcast(void *closure, const char *event, int /******************* ws request part for server *****************/ /* decrement the reference count of the request and free/release it on falling to null */ -static void api_ws_server_req_destroy_cb(void *closure) +static void api_ws_server_req_destroy_cb(struct afb_xreq *xreq) { - struct api_ws_server_req *wreq = closure; + struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq); afb_context_disconnect(&wreq->xreq.context); + afb_cred_unref(wreq->xreq.cred); json_object_put(wreq->xreq.json); free(wreq->rcvdata); api_ws_server_client_unref(wreq->client); free(wreq); } -static void api_ws_server_req_success_cb(void *closure, struct json_object *obj, const char *info) +static void api_ws_server_req_success_cb(struct afb_xreq *xreq, struct json_object *obj, const char *info) { int rc; struct writebuf wb = { .count = 0 }; - struct api_ws_server_req *wreq = closure; + struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq); - if (api_ws_write_char(&wb, 'T') + if (api_ws_write_char(&wb, CHAR_FOR_ANSWER_SUCCESS) && api_ws_write_uint32(&wb, wreq->msgid) && api_ws_write_uint32(&wb, (uint32_t)wreq->xreq.context.flags) && api_ws_write_string(&wb, info ? : "") @@ -1091,13 +1109,13 @@ success: json_object_put(obj); } -static void api_ws_server_req_fail_cb(void *closure, const char *status, const char *info) +static void api_ws_server_req_fail_cb(struct afb_xreq *xreq, const char *status, const char *info) { int rc; struct writebuf wb = { .count = 0 }; - struct api_ws_server_req *wreq = closure; + struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq); - if (api_ws_write_char(&wb, 'F') + if (api_ws_write_char(&wb, CHAR_FOR_ANSWER_FAIL) && api_ws_write_uint32(&wb, wreq->msgid) && api_ws_write_uint32(&wb, (uint32_t)wreq->xreq.context.flags) && api_ws_write_string(&wb, status) @@ -1109,17 +1127,17 @@ static void api_ws_server_req_fail_cb(void *closure, const char *status, const c ERROR("error while sending fail"); } -static int api_ws_server_req_subscribe_cb(void *closure, struct afb_event event) +static int api_ws_server_req_subscribe_cb(struct afb_xreq *xreq, struct afb_event event) { int rc, rc2; struct writebuf wb = { .count = 0 }; - struct api_ws_server_req *wreq = closure; + struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq); rc = afb_evt_add_watch(wreq->client->listener, event); if (rc < 0) return rc; - if (api_ws_write_char(&wb, 'S') + if (api_ws_write_char(&wb, CHAR_FOR_EVT_SUBSCRIBE) && api_ws_write_uint32(&wb, wreq->msgid) && api_ws_write_uint32(&wb, (uint32_t)afb_evt_event_id(event)) && api_ws_write_string(&wb, afb_evt_event_name(event))) { @@ -1132,13 +1150,13 @@ success: return rc; } -static int api_ws_server_req_unsubscribe_cb(void *closure, struct afb_event event) +static int api_ws_server_req_unsubscribe_cb(struct afb_xreq *xreq, struct afb_event event) { int rc, rc2; struct writebuf wb = { .count = 0 }; - struct api_ws_server_req *wreq = closure; + struct api_ws_server_req *wreq = CONTAINER_OF_XREQ(struct api_ws_server_req, xreq); - if (api_ws_write_char(&wb, 'U') + if (api_ws_write_char(&wb, CHAR_FOR_EVT_UNSUBSCRIBE) && api_ws_write_uint32(&wb, wreq->msgid) && api_ws_write_uint32(&wb, (uint32_t)afb_evt_event_id(event)) && api_ws_write_string(&wb, afb_evt_event_name(event))) {