diff options
author | Marcus Fritzsch <marcus_fritzsch@mentor.com> | 2017-09-12 12:02:38 +0200 |
---|---|---|
committer | Marcus Fritzsch <marcus_fritzsch@mentor.com> | 2017-09-12 12:21:18 +0200 |
commit | 41215ddc3ab972d2d3b31a54576103be75a20f44 (patch) | |
tree | 2805e36b6b8cd244b5802052d8f6db03f9a79f04 | |
parent | f73d072d63607cdfb6657f828c2e55b8f100669a (diff) |
add AFBClient
Signed-off-by: Marcus Fritzsch <marcus_fritzsch@mentor.com>
-rw-r--r-- | AFBClient.cpp | 133 | ||||
-rw-r--r-- | AFBClient.h | 34 |
2 files changed, 167 insertions, 0 deletions
diff --git a/AFBClient.cpp b/AFBClient.cpp new file mode 100644 index 0000000..2c200bc --- /dev/null +++ b/AFBClient.cpp @@ -0,0 +1,133 @@ +#include "AFBClient.h" + +/* the callback interface for wsj1 */ +static struct afb_wsj1_itf itf = +{ + .on_hangup = AFBClient::onHangup, + .on_call = AFBClient::onCall, + .on_event = AFBClient::onEvent +}; + +AFBClient::AFBClient() +{ + /* get the default event loop */ + int rc = sd_event_default(&loop); + if (rc < 0) { + fprintf(stderr, "Connection to default event loop failed: %s\n", strerror(-rc)); + return 1; + } + + /* connect the websocket wsj1 to the uri given by the first argument */ + wsj1 = afb_ws_client_connect_wsj1(loop, wmURI, &itf, NULL); + if (wsj1 == NULL) { + fprintf(stderr, "Connection to %s failed: %m\n", wmURI); + return 1; + } +} + +void AFBClient::requestSurface(const char *label) +{ + const char functionParamName[] = "{\"drawing_name\":\""; + char *parameter = (char *)malloc(strlen(functionParamName) + strlen(label) + 3); + strcpy(parameter, functionParamName); + strcat(parameter, label); + strcat(parameter, "\"}"); + printf("requestSurface(%s): %s\n", label, parameter); + call(wmAPI, "request_surface", parameter); +} + +void AFBClient::activateSurface(const char *label) +{ + const char functionParamName[] = "{\"drawing_name\":\""; + char *parameter = (char *)malloc(strlen(functionParamName) + strlen(label) + 3); + strcpy(parameter, functionParamName); + strcat(parameter, label); + strcat(parameter, "\"}"); + printf("activateSurface(%s): %s\n", label, parameter); + call(wmAPI, "activate_surface", parameter); +} + +void AFBClient::deactivateSurface(const char *label) +{ +} + +void AFBClient::endDraw(const char *label) +{ +} + +/* called when wsj1 receives a method invocation */ +void AFBClient::onCall(void *closure, afb_wsj1 *wsj1) +{ + int rc; + printf("ON-CALL %s/%s:\n%s\n", api, verb, + json_object_to_json_string_ext(afb_wsj1_msg_object_j(msg), + JSON_C_TO_STRING_PRETTY)); + fflush(stdout); + rc = afb_wsj1_reply_error_s(msg, "\"unimplemented\"", NULL); + if (rc < 0) + fprintf(stderr, "replying failed: %m\n"); +} + +/* called when wsj1 receives an event */ +void AFBClient::onEvent(void *closure, const char *event, afb_wsj1_msg *msg) +{ + printf("ON-EVENT %s:\n%s\n", event, + json_object_to_json_string_ext(afb_wsj1_msg_object_j(msg), + JSON_C_TO_STRING_PRETTY)); + fflush(stdout); +} + +/* called when wsj1 hangsup */ +void AFBClient::onHangup(void *closure, afb_wsj1 *wsj1) +{ + printf("ON-HANGUP\n"); + fflush(stdout); + exit(0); +} + +/* called when wsj1 receives a reply */ +void AFBClient::onReply(void *closure, afb_wsj1_msg *msg) +{ + printf("ON-REPLY %s: %s\n%s\n", (char*)closure, + afb_wsj1_msg_is_reply_ok(msg) ? "OK" : "ERROR", + json_object_to_json_string_ext(afb_wsj1_msg_object_j(msg), + JSON_C_TO_STRING_PRETTY)); + fflush(stdout); + free(closure); +} + +/* makes a call */ +void AFBClient::call(const char *api, const char *verb, const char *object) +{ + static int num = 0; + char *key; + int rc; + + /* allocates an id for the request */ + rc = asprintf(&key, "%d:%s/%s", ++num, api, verb); + + /* send the request */ + rc = afb_wsj1_call_s(wsj1, api, verb, object, AFBClient::onReply, key); + if (rc < 0) + fprintf(stderr, "calling %s/%s(%s) failed: %m\n", api, verb, object); +} + +/* sends an event */ +void AFBClient::event(const char *event, const char *object) +{ + int rc; + + rc = afb_wsj1_send_event_s(wsj1, event, object); + if (rc < 0) + fprintf(stderr, "sending !%s(%s) failed: %m\n", event, object); +} + +void AFBClient::emitSignalOrCall(const char *api, const char *verb, const char *object) +{ + if (object == NULL || object[0] == 0) + object = "null"; + if (api[0] == '!' && api[1] == 0) + event(verb, object); + else + call(api, verb, object); +} diff --git a/AFBClient.h b/AFBClient.h new file mode 100644 index 0000000..d93817b --- /dev/null +++ b/AFBClient.h @@ -0,0 +1,34 @@ +#ifndef AFBCLIENT_H +#define AFBCLIENT_H + +#include <systemd/sd-event.h> +#include <json-c/json.h> + +#include "afb-wsj1.h" +#include "afb-ws-client.h" + +class AFBClient +{ +public: + AFBClient(); + void requestSurface(const char *label); + void activateSurface(const char *label); + void deactivateSurface(const char *label); + void endDraw(const char *label); + +private: + void call(const char *api, const char *verb, const char *object); + void emitSignalOrCall(const char *api, const char *verb, const char *object); + void event(const char *event, const char *object); + void onCall(void *closure, struct afb_wsj1 *wsj1); + void onEvent(void *closure, const char *event, struct afb_wsj1_msg *msg); + void onHangup(void *closure, struct afb_wsj1 *wsj1); + void onReply(void *closure, struct afb_wsj1_msg *msg); + + struct afb_wsj1 *wsj1; + sd_event *loop; + const char *wmURI = "ws://localhost:1700/api?wm"; + const char *wmAPI = "winman"; +}; + +#endif // AFBCLIENT_H |