2 * Copyright (C) 2015-2018 "IoT.bzh"
4 * Author José Bollo <jose.bollo@iot.bzh>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
32 #include <json-c/json.h>
34 #include <afb-ws-client.h>
37 #define WEBSOCKET_CODE_INTERNAL_ERROR 1011
43 #include <systemd/sd-event.h>
49 wsj1() noexcept = default;
50 wsj1(const wsj1 &other) = delete;
51 wsj1(wsj1 &&other) noexcept { wsj1_ = other.wsj1_; other.wsj1_ = nullptr; }
52 wsj1(const std::string &uri) { connect(uri); }
53 wsj1(const char *uri) { connect(uri); }
54 ~wsj1() { if (wsj1_) disconnect(); }
55 void connect(const std::string &uri) { connect(uri.c_str()); }
56 void connect(const char *uri);
58 void call(const char *api, const char *verb, json_object *request, std::function<void(json_object*)> &onreply)
60 call(api,verb,json_object_to_json_string_ext(request,JSON_C_TO_STRING_PLAIN),[](const char *x){onreply(std::string(x));});
62 void call(const char *api, const char *verb, char *request, std::function<void(const char*)> &onreply);
63 void call(const std::string &api, const std::string &verb, const std::string &request, std::function<void(std::string&)> &onreply)
65 call(api.c_str(), verb.c_str(), request.c_str(), [=](const char *x){onreply(std::string(x));});
70 msg(afb_wsj1_msg *msg) : msg_{msg} {}
75 afb_wsj1 *wsj1_ = nullptr;
77 static struct afb_wsj1_itf wsj1_itf;
78 static void itf_hangup_(void *closure, struct afb_wsj1 *wsj1);
79 static void itf_on_call_(void *closure, const char *api, const char *verb, struct afb_wsj1_msg *msg);
80 static void itf_on_event_(void *closure, const char *event, struct afb_wsj1_msg *msg);
82 void on_hangup_(struct afb_wsj1 *wsj1) {}
83 void on_call_(const char *api, const char *verb, struct afb_wsj1_msg *msg) {}
84 void on_event_(const char *event, struct afb_wsj1_msg *msg);
85 static void on_reply_(void *closure, struct afb_wsj1_msg *msg);
87 static sd_event *eloop();
90 struct afb_wsj1_itf wsj1::wsj1_itf = {
96 void wsj1::connect(const char *uri) {
98 throw std::runtime_error("already-connected");
99 wsj1_ = afb_ws_client_connect_wsj1(eloop(), uri, &wsj1_itf, reinterpret_cast<void*>(this));
101 throw std::runtime_error("connection-failed");
104 void wsj1::disconnect() {
106 throw std::runtime_error("not-connected");
107 afb_wsj1_unref(wsj1_);
111 void wsj1::itf_on_event_(void *closure, const char *event, struct afb_wsj1_msg *msg) {
112 reinterpret_cast<wsj1*>(closure)->on_event_(event, msg);
115 void wsj1::on_event_(const char *event, struct afb_wsj1_msg *msg) {
119 void wsj1::call(const char *api, const char *verb, char *request, std::function<void(const char*)> &onreply) {
121 throw std::runtime_error("not-connected");
122 afb_wsj1_call_s(wsj1_,api,verb,request,onreply,reinterpret_cast<void*>(this));