diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/afb-wsj1.c | 1 | ||||
-rw-r--r-- | src/afb-wsj1.hpp | 125 |
3 files changed, 127 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8bee1068..61f1c3da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,7 +86,7 @@ IF(HAVE_MAGIC_H) ENDIF(HAVE_MAGIC_H) PKG_CHECK_MODULES(libsystemd libsystemd>=222) -PKG_CHECK_MODULES(libmicrohttpd libmicrohttpd>=0.9.55) +PKG_CHECK_MODULES(libmicrohttpd libmicrohttpd>=0.9.60) PKG_CHECK_MODULES(openssl openssl) PKG_CHECK_MODULES(uuid uuid) PKG_CHECK_MODULES(cynara cynara-client) diff --git a/src/afb-wsj1.c b/src/afb-wsj1.c index 7fb85169..6816617d 100644 --- a/src/afb-wsj1.c +++ b/src/afb-wsj1.c @@ -588,3 +588,4 @@ int afb_wsj1_reply_s(struct afb_wsj1_msg *msg, const char *object, const char *t return wsj1_send_isot(msg->wsj1, iserror ? RETERR : RETOK, msg->id, object, token); } +z
\ No newline at end of file diff --git a/src/afb-wsj1.hpp b/src/afb-wsj1.hpp new file mode 100644 index 00000000..17f74d37 --- /dev/null +++ b/src/afb-wsj1.hpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2015-2018 "IoT.bzh" + * Author Gabin Fodop + * Author José Bollo <jose.bollo@iot.bzh> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#define _GNU_SOURCE + +#include <stdlib.h> +#include <unistd.h> +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <pthread.h> + +extern "C" { +#include <json-c/json.h> +#include <afb-wsj1.h> +#include <afb-ws-client.h> +} + +#define WEBSOCKET_CODE_INTERNAL_ERROR 1011 + +#include <string> +#include <functional> +#include <thread> + +#include <systemd/sd-event.h> + +namespace afb { + +class wsj1 { +public: + wsj1() noexcept = default; + wsj1(const wsj1 &other) = delete; + wsj1(wsj1 &&other) noexcept { wsj1_ = other.wsj1_; other.wsj1_ = nullptr; } + wsj1(const std::string &uri) { connect(uri); } + wsj1(const char *uri) { connect(uri); } + ~wsj1() { if (wsj1_) disconnect(); } + void connect(const std::string &uri) { connect(uri.c_str()); } + void connect(const char *uri); + void disconnect(); + void call(const char *api, const char *verb, json_object *request, std::function<void(json_object*)> &onreply) + { + call(api,verb,json_object_to_json_string_ext(request,JSON_C_TO_STRING_PLAIN),[](const char *x){onreply(std::string(x));}); + }; + void call(const char *api, const char *verb, char *request, std::function<void(const char*)> &onreply); + void call(const std::string &api, const std::string &verb, const std::string &request, std::function<void(std::string&)> &onreply) + { + call(api.c_str(), verb.c_str(), request.c_str(), [=](const char *x){onreply(std::string(x));}); + } +public: + class msg { + friend class wsj1; + msg(afb_wsj1_msg *msg) : msg_{msg} {} + afb_wsj1_msg *msg_; + public: + }; +private: + afb_wsj1 *wsj1_ = nullptr; +private: + static struct afb_wsj1_itf wsj1_itf; + static void itf_hangup_(void *closure, struct afb_wsj1 *wsj1); + static void itf_on_call_(void *closure, const char *api, const char *verb, struct afb_wsj1_msg *msg); + static void itf_on_event_(void *closure, const char *event, struct afb_wsj1_msg *msg); +private: + void on_hangup_(struct afb_wsj1 *wsj1) {} + void on_call_(const char *api, const char *verb, struct afb_wsj1_msg *msg) {} + void on_event_(const char *event, struct afb_wsj1_msg *msg); + static void on_reply_(void *closure, struct afb_wsj1_msg *msg); +private: + static sd_event *eloop(); +}; + +struct afb_wsj1_itf wsj1::wsj1_itf = { + wsj1::itf_hangup_, + wsj1::itf_on_call_, + wsj1::itf_on_event_ +}; + +void wsj1::connect(const char *uri) { + if (wsj1_) + throw std::runtime_error("already-connected"); + wsj1_ = afb_ws_client_connect_wsj1(eloop(), uri, &wsj1_itf, reinterpret_cast<void*>(this)); + if (!wsj1_) + throw std::runtime_error("connection-failed"); +} + +void wsj1::disconnect() { + if (!wsj1_) + throw std::runtime_error("not-connected"); + afb_wsj1_unref(wsj1_); + wsj1_ = nullptr; +} + +void wsj1::itf_on_event_(void *closure, const char *event, struct afb_wsj1_msg *msg) { + reinterpret_cast<wsj1*>(closure)->on_event_(event, msg); +} + +void wsj1::on_event_(const char *event, struct afb_wsj1_msg *msg) { + +} + +void wsj1::call(const char *api, const char *verb, char *request, std::function<void(const char*)> &onreply) { + if (!wsj1_) + throw std::runtime_error("not-connected"); + afb_wsj1_call_s(wsj1_,api,verb,request,onreply,reinterpret_cast<void*>(this)); +} + +} |