diff options
author | Loïc Collignon <loic.collignon@iot.bzh> | 2018-06-12 11:00:25 +0200 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2018-06-12 14:40:08 +0000 |
commit | 22c2633ac833ae78ff84beafce19cec0f05758a2 (patch) | |
tree | dca31bcfc6bf27aaca93e6f9f676361c6f6ed1e1 /ahl-binding/role.cpp | |
parent | 9a631c30c9c8792865ce2aa0ec06a1bb5fd16751 (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.cpp | 200 |
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) +{ +} |