- uint32_t descid;
- struct client_describe *desc;
- struct json_object *object;
-
- if (!readbuf_uint32(rb, &descid))
- ERROR("unreadable description");
- else {
- desc = stubws->describes;
- while (desc && desc->descid != descid)
- desc = desc->next;
- if (desc == NULL)
- ERROR("unexpected description");
- else {
- if (readbuf_object(rb, &object))
- desc->result = object;
- else
- ERROR("bad description");
- jobs_leave(desc->jobloop);
- }
- }
-}
-
-/* callback when receiving binary data */
-static void client_on_binary(void *closure, char *data, size_t size)
-{
- if (size > 0) {
- struct afb_stub_ws *stubws = closure;
- struct readbuf rb = { .head = data, .end = data + size };
-
- pthread_mutex_lock(&stubws->mutex);
- switch (*rb.head++) {
- case CHAR_FOR_ANSWER_SUCCESS: /* success */
- client_reply_success(stubws, &rb);
- break;
- case CHAR_FOR_ANSWER_FAIL: /* fail */
- client_reply_fail(stubws, &rb);
- break;
- case CHAR_FOR_EVT_BROADCAST: /* broadcast */
- client_event_broadcast(stubws, &rb);
- break;
- case CHAR_FOR_EVT_ADD: /* creates the event */
- client_event_create(stubws, &rb);
- break;
- case CHAR_FOR_EVT_DEL: /* drops the event */
- client_event_drop(stubws, &rb);
- break;
- case CHAR_FOR_EVT_PUSH: /* pushs the event */
- client_event_push(stubws, &rb);
- break;
- case CHAR_FOR_EVT_SUBSCRIBE: /* subscribe event for a request */
- client_event_subscribe(stubws, &rb);
- break;
- case CHAR_FOR_EVT_UNSUBSCRIBE: /* unsubscribe event for a request */
- client_event_unsubscribe(stubws, &rb);
- break;
- case CHAR_FOR_SUBCALL_CALL: /* subcall */
- client_subcall(stubws, &rb);
- break;
- case CHAR_FOR_DESCRIPTION: /* description */
- client_on_description(stubws, &rb);
- break;
- default: /* unexpected message */
- /* TODO: close the connection */
- break;
- }
- pthread_mutex_unlock(&stubws->mutex);
- }
- free(data);
-}
-
-/* on call, propagate it to the ws service */
-static void client_call_cb(void * closure, struct afb_xreq *xreq)
-{
- int rc;
- struct client_call *call;
- struct writebuf wb = { .count = 0 };
- const char *raw;
- size_t szraw;
- struct afb_stub_ws *stubws = closure;
-
- pthread_mutex_lock(&stubws->mutex);
-
- /* create the recording data */
- call = client_call_make(stubws, xreq);
- if (call == NULL) {
- afb_xreq_fail_f(xreq, "error", "out of memory");
- goto end;
- }
-
- /* creates the call message */
- raw = afb_xreq_raw(xreq, &szraw);
- if (raw == NULL)
- goto internal_error;
- if (!writebuf_char(&wb, CHAR_FOR_CALL)
- || !writebuf_uint32(&wb, call->msgid)
- || !writebuf_uint32(&wb, (uint32_t)xreq->context.flags)
- || !writebuf_string(&wb, xreq->verb)
- || !writebuf_string(&wb, afb_session_uuid(xreq->context.session))
- || !writebuf_string_length(&wb, raw, szraw))
- goto overflow;
-
- /* send */
- rc = afb_ws_binary_v(stubws->ws, wb.iovec, wb.count);
- if (rc >= 0)
- goto end;
-
- afb_xreq_fail(xreq, "error", "websocket sending error");
- goto clean_call;