summaryrefslogtreecommitdiffstats
path: root/ahl-binding/role.cpp
diff options
context:
space:
mode:
authorLoïc Collignon <loic.collignon@iot.bzh>2018-06-12 11:00:25 +0200
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2018-06-12 14:40:08 +0000
commit22c2633ac833ae78ff84beafce19cec0f05758a2 (patch)
treedca31bcfc6bf27aaca93e6f9f676361c6f6ed1e1 /ahl-binding/role.cpp
parent9a631c30c9c8792865ce2aa0ec06a1bb5fd16751 (diff)
Update to last softmixer and hal, plus some fixes
Use the last 4a-softmixer and 4a-hal-generic versions. Fix some potential crash and performance bottleneck. Now support sessions to disallow multiple opening or closing by not owner. Change-Id: I95b020a3fab03b1e1058812adae1d8d5986f282b Signed-off-by: Loïc Collignon <loic.collignon@iot.bzh>
Diffstat (limited to 'ahl-binding/role.cpp')
-rw-r--r--ahl-binding/role.cpp200
1 files changed, 181 insertions, 19 deletions
diff --git a/ahl-binding/role.cpp b/ahl-binding/role.cpp
index 9338436..b6a9c1f 100644
--- a/ahl-binding/role.cpp
+++ b/ahl-binding/role.cpp
@@ -17,30 +17,21 @@
#include "role.hpp"
#include "jsonc_utils.hpp"
-
-role_t::role_t(std::string uid, std::string name, std::string description, std::string stream, int priority)
- : uid_{uid}
- , name_{name}
- , description_{description}
- , stream_{stream}
- , priority_{priority}
-{
-}
+#include "ahl-binding.hpp"
role_t::role_t(json_object* j)
{
jcast(uid_, j, "uid");
- jcast(name_, j, "name");
jcast(description_, j, "description");
jcast(priority_, j, "priority");
jcast(stream_, j, "stream");
jcast_array(interrupts_, j, "interrupts");
+ opened_ = false;
}
role_t& role_t::operator<<(json_object* j)
{
jcast(uid_, j, "uid");
- jcast(name_, j, "name");
jcast(description_, j, "description");
jcast(priority_, j, "priority");
jcast(stream_, j, "stream");
@@ -53,14 +44,14 @@ std::string role_t::uid() const
return uid_;
}
-std::string role_t::name() const
+std::string role_t::description() const
{
- return name_;
+ return description_;
}
-std::string role_t::description() const
+std::string role_t::hal() const
{
- return description_;
+ return hal_;
}
std::string role_t::stream() const
@@ -78,14 +69,14 @@ std::string role_t::device_uri() const
return device_uri_;
}
-void role_t::uid(std::string v)
+bool role_t::opened() const
{
- uid_ = v;
+ return opened_;
}
-void role_t::name(std::string v)
+void role_t::uid(std::string v)
{
- name_ = v;
+ uid_ = v;
}
void role_t::description(std::string v)
@@ -93,6 +84,11 @@ void role_t::description(std::string v)
description_ = v;
}
+void role_t::hal(std::string v)
+{
+ hal_ = v;
+}
+
void role_t::stream(std::string v)
{
stream_ = v;
@@ -112,3 +108,169 @@ const std::vector<interrupt_t>& role_t::interrupts() const
{
return interrupts_;
}
+
+int role_t::apply_policy(afb_request* req)
+{
+ if(interrupts_.size())
+ {
+ const interrupt_t& i = interrupts_[0];
+ /*if (i.type() == "mute")
+ {
+ }
+ else if (i.type() == "continue")
+ {
+ }
+ else if (i.type() == "cancel")
+ {
+ }
+ else */if (i.type() == "ramp")
+ {
+ for(const auto& r: ahl_binding_t::instance().roles())
+ {
+ if (r.opened() && priority_ > r.priority())
+ {
+ // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } }
+ json_object* arg = json_object_new_object();
+ json_object_object_add(arg, "ramp", i.args());
+ json_object_get(i.args());
+ json_object* result = nullptr;
+
+ AFB_DYNAPI_NOTICE(ahl_binding_t::instance().handle(),
+ "Call '%s'/'%s' '%s",
+ r.hal().c_str(), r.stream().c_str(), json_object_to_json_string(arg));
+
+ if(afb_dynapi_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result))
+ {
+ afb_request_fail(req, "Failed to call 'ramp' action on stream", nullptr);
+ return -1;
+ }
+ AFB_DYNAPI_NOTICE(ahl_binding_t::instance().handle(),
+ "POLICY: Applying a ramp to '%s' stream because '%s' is opened and have higher priority!",
+ r.stream().c_str(), stream_.c_str());
+ }
+ }
+ }
+ else
+ {
+ afb_request_fail(req, "Unkown interrupt uid!", nullptr);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void role_t::invoke(afb_request* req)
+{
+ json_object* arg = afb_request_json(req);
+ if (arg == nullptr)
+ {
+ afb_request_fail(req, "No valid argument!", nullptr);
+ return;
+ }
+
+ json_object* jaction = json_object_object_get(arg, "action");
+ if (jaction == nullptr)
+ {
+ afb_request_fail(req, "No valid action!", nullptr);
+ return;
+ }
+
+ std::string action = json_object_get_string(jaction);
+ if (action.size() == 0)
+ {
+ afb_request_fail(req, "No valid action!", nullptr);
+ return;
+ }
+
+ if (action == "open") open(req, arg);
+ else if (action == "close") close(req, arg);
+ else if (action == "volume") volume(req, arg);
+ else if (action == "interrupt") interrupt(req, arg);
+ else afb_request_fail(req, "Unknown action!", nullptr);
+}
+
+void role_t::open(afb_request* r, json_object* o)
+{
+ if (opened_)
+ {
+ afb_request_fail(r, "Already opened!", nullptr);
+ return;
+ }
+
+ if (!apply_policy(r))
+ {
+ afb_request_context_set(r, this, nullptr);
+ opened_ = true;
+
+ json_object* result = json_object_new_object();
+ json_object_object_add(result, "device_uri", json_object_new_string(device_uri_.c_str()));
+
+ afb_request_success(r, result, nullptr);
+ }
+}
+
+void role_t::close(afb_request* r, json_object* o)
+{
+ if (!opened_)
+ {
+ afb_request_success(r, nullptr, "Already closed!");
+ return;
+ }
+
+ if(!afb_request_context_get(r))
+ {
+ afb_request_fail(r, "Stream is opened by another client!", nullptr);
+ return;
+ }
+
+ opened_ = false;
+ afb_request_success(r, nullptr, "Stream closed!");
+}
+
+void role_t::volume(afb_request* r, json_object* o)
+{
+ if (!opened_)
+ {
+ afb_request_fail(r, "You have to open the stream first!", nullptr);
+ return;
+ }
+
+ if(!afb_request_context_get(r))
+ {
+ afb_request_fail(r, "Stream is opened by another client!", nullptr);
+ return;
+ }
+
+ json_object* value = json_object_object_get(o, "value");
+ if(!value)
+ {
+ afb_request_fail(r, "No value given!", nullptr);
+ return;
+ }
+
+ json_object_get(value);
+
+ json_object* a = json_object_new_object();
+ json_object_object_add(a, "volume", value);
+
+ afb_dynapi_call(
+ r->dynapi,
+ hal_.c_str(),
+ stream_.c_str(),
+ a,
+ [](void* closure, int status, json_object* result, afb_dynapi* handle)
+ {
+ AFB_DYNAPI_DEBUG(handle, "Got the following answer: %s", json_object_to_json_string(result));
+ afb_request* r = (afb_request*)closure;
+
+ json_object_get(result);
+ if (status) afb_request_fail(r, json_object_to_json_string(result), nullptr);
+ else afb_request_success(r, result, nullptr);
+ afb_request_unref(r);
+ },
+ afb_request_addref(r));
+}
+
+void role_t::interrupt(afb_request* r, json_object* o)
+{
+}