18 #include <sys/socket.h> 25 #define ELOG(args,...) _ELOG(__FUNCTION__,__LINE__,args,##__VA_ARGS__) 27 #define DLOG(args,...) _DLOG(__FUNCTION__,__LINE__,args,##__VA_ARGS__) 29 #define DLOG(args,...) 31 static void _DLOG(
const char* func,
const int line,
const char* log, ...);
32 static void _ELOG(
const char* func,
const int line,
const char* log, ...);
36 static bool has_verb(
const std::string& verb);
37 static const char API[] =
"soundmanager";
38 static int eventIndent(
const string&
event);
40 static const std::vector<std::string> api_list{
41 std::string(
"connect"),
42 std::string(
"disconnect"),
43 std::string(
"setVolume"),
44 std::string(
"volumeStep"),
45 std::string(
"setSinkMuteState"),
46 std::string(
"getListMainConnections"),
47 std::string(
"ackConnect"),
48 std::string(
"ackDisconnect"),
49 std::string(
"ackSetSourceState"),
50 std::string(
"registerSource"),
51 std::string(
"deregisterSource"),
52 std::string(
"subscribe"),
53 std::string(
"unsubscribe")
56 static const std::vector<std::string> event_list{
57 std::string(
"asyncSetSourceState"),
58 std::string(
"newMainConnection"),
59 std::string(
"volumeChanged"),
60 std::string(
"removedMainConnection"),
61 std::string(
"sinkMuteStateChanged"),
62 std::string(
"mainConnectionStateChanged"),
63 std::string(
"setRoutingReady"),
64 std::string(
"setRoutingRundown"),
65 std::string(
"asyncConnect")
68 static void _on_hangup_static(
void *closure,
struct afb_wsj1 *wsj)
73 static void _on_call_static(
void *closure,
const char *api,
const char *verb,
struct afb_wsj1_msg *msg)
78 static void _on_event_static(
void* closure,
const char*
event,
struct afb_wsj1_msg *msg)
83 static void _on_reply_static(
void *closure,
struct afb_wsj1_msg *msg)
88 static void *event_loop_run(
void *args)
90 struct sd_event* loop = (
struct sd_event*)(args);
91 DLOG(
"start eventloop");
93 sd_event_run(loop, 30000000);
104 sd_event_unref(mploop);
106 if(sp_websock != NULL)
108 afb_wsj1_unref(sp_websock);
129 if(port > 0 && token.size() > 0)
136 ELOG(
"port and token should be > 0, Initial port and token uses.");
140 ret = initialize_websocket();
143 ELOG(
"Failed to initialize websocket");
149 ELOG(
"Failed to initialize websocket");
153 ELOG(
"Failed to create thread");
159 int LibSoundmanager::initialize_websocket()
164 int ret = sd_event_default(&mploop);
167 ELOG(
"Failed to create event loop");
172 minterface.on_hangup = _on_hangup_static;
173 minterface.on_call = _on_call_static;
174 minterface.on_event = _on_event_static;
175 string muri =
"ws://localhost:" + to_string(mport) +
"/api?token=" + mtoken;
176 sp_websock = afb_ws_client_connect_wsj1(mploop, muri.c_str(), &minterface,
this);
178 if(sp_websock == NULL)
180 ELOG(
"Failed to create websocket connection");
188 sd_event_unref(mploop);
193 int LibSoundmanager::init_event(){
195 return subscribe(
string(
"asyncSetSourceState"));
213 void (*event_cb)(
const string& event,
struct json_object* event_contents),
214 void (*reply_cb)(
struct json_object* reply_contents),
215 void (*hangup_cb)(
void))
219 onHangup = hangup_cb;
237 void (*reply_cb)(
struct json_object* reply_contents),
238 void (*hangup_cb)(
void))
241 onHangup = hangup_cb;
265 struct json_object* j_obj = json_object_new_object();
266 struct json_object* jsn = json_object_new_string(sourceName.c_str());
267 json_object_object_add(j_obj,
"appname", jsn);
268 return this->call(__FUNCTION__, j_obj);
293 struct json_object* j_obj = json_object_new_object();
294 struct json_object* jsource = json_object_new_int(sourceID);
295 struct json_object* jsink = json_object_new_int(sinkID);
296 json_object_object_add(j_obj,
"sourceID", jsource);
297 json_object_object_add(j_obj,
"sinkID", jsink);
298 return this->call(__FUNCTION__, j_obj);
325 struct json_object* j_obj = json_object_new_object();
326 struct json_object* jsource = json_object_new_int(sourceID);
328 struct json_object* jsink = json_object_new_string(sinkName.c_str());
329 json_object_object_add(j_obj,
"sourceID", jsource);
330 json_object_object_add(j_obj,
"sinkID", jsink);
331 return this->call(__FUNCTION__, j_obj);
353 struct json_object* j_obj = json_object_new_object();
354 struct json_object* jconnection = json_object_new_int(connectionID);
355 json_object_object_add(j_obj,
"mainConnectionID", jconnection);
356 return this->call(__FUNCTION__, j_obj);
380 struct json_object* j_obj = json_object_new_object();
381 struct json_object* jhandle = json_object_new_int(handle);
382 struct json_object* jerrno = json_object_new_int(error);
383 json_object_object_add(j_obj,
"handle", jhandle);
384 json_object_object_add(j_obj,
"error", jerrno);
385 return this->call(__FUNCTION__, j_obj);
411 ELOG(
"verb doesn't exit");
414 ret = afb_wsj1_call_j(sp_websock, API, verb.c_str(), arg, _on_reply_static,
this);
416 ELOG(
"Failed to call verb:%s",verb.c_str());
443 if (!has_verb(
string(verb)))
445 ELOG(
"verb doesn't exit");
448 ret = afb_wsj1_call_j(sp_websock, API, verb, arg, _on_reply_static,
this);
450 ELOG(
"Failed to call verb:%s",verb);
475 struct json_object* j_obj = json_object_new_object();
476 json_object_object_add(j_obj,
"event", json_object_new_string(event_name.c_str()));
478 int ret = afb_wsj1_call_j(sp_websock, API,
"subscribe", j_obj, _on_reply_static,
this);
480 ELOG(
"Failed to call verb:%s",__FUNCTION__);
504 struct json_object* j_obj = json_object_new_object();
505 json_object_object_add(j_obj,
"event", json_object_new_string(event_name.c_str()));
507 int ret = afb_wsj1_call_j(sp_websock, API,
"unsubscribe", j_obj, _on_reply_static,
this);
509 ELOG(
"Failed to call verb:%s",__FUNCTION__);
530 if (et > 1 && et < NumItems) {
531 this->handlers[et] = std::move(f);
540 DLOG(
"%s called", __FUNCTION__);
541 if(onHangup !=
nullptr)
561 string ev = string(event);
562 if (ev.find(API) == string::npos) {
566 struct json_object* ev_contents = afb_wsj1_msg_object_j(msg);
567 if(onEvent !=
nullptr)
569 onEvent(ev, ev_contents);
573 dispatch_event(ev, ev_contents);
575 json_object_put(ev_contents);
580 struct json_object* reply = afb_wsj1_msg_object_j(msg);
594 if(onReply !=
nullptr)
598 json_object_put(reply);
601 int LibSoundmanager::dispatch_event(
const string &event , json_object* event_contents){
605 if(event.find(event_list[0].c_str())){
606 x = Event_AsyncSetSourceState;
611 auto i = this->handlers.find(x);
612 if(i != handlers.end()){
613 i->second(event_contents);
621 static void _ELOG(
const char* func,
const int line,
const char* log, ...)
626 if (log == NULL || vasprintf(&message, log, args) < 0)
628 cout <<
"[ERROR: soundmanager]" << func <<
"(" << line <<
"):" << message << endl;
633 static void _DLOG(
const char* func,
const int line,
const char* log, ...)
638 if (log == NULL || vasprintf(&message, log, args) < 0)
640 cout <<
"[DEBUG: soundmanager]" << func <<
"(" << line <<
"):" << message << endl;
645 static bool has_verb(
const string& verb)
647 if(find(api_list.begin(), api_list.end(), verb) != api_list.end())
void register_callback(void(*event_cb)(const std::string &event, struct json_object *event_contents), void(*reply_cb)(struct json_object *reply_contents), void(*hangup_cb)(void)=nullptr)
void set_event_handler(enum EventType_SM et, handler_fun f)
int init(int port, const std::string &token)
int unsubscribe(const std::string &event_name)
int disconnect(int connectionID)
int call(const std::string &verb, struct json_object *arg)
int connect(int sourceID, int sinkID)
std::function< void(struct json_object *)> handler_fun
void on_hangup(void *closure, struct afb_wsj1 *wsj)
int subscribe(const std::string &event_name)
int ackSetSourceState(int handle, int error)
void on_reply(void *closure, struct afb_wsj1_msg *msg)
void on_call(void *closure, const char *api, const char *verb, struct afb_wsj1_msg *msg)
void on_event(void *closure, const char *event, struct afb_wsj1_msg *msg)
int registerSource(const std::string &sourceName)