diff options
Diffstat (limited to 'ahl-binding/role.cpp')
-rw-r--r-- | ahl-binding/role.cpp | 114 |
1 files changed, 44 insertions, 70 deletions
diff --git a/ahl-binding/role.cpp b/ahl-binding/role.cpp index a122fc2..a073b33 100644 --- a/ahl-binding/role.cpp +++ b/ahl-binding/role.cpp @@ -15,10 +15,13 @@ * limitations under the License. */ +#include <algorithm> #include "role.hpp" #include "jsonc_utils.hpp" #include "ahl-binding.hpp" +using session_t = std::vector<role_t*>; + role_t::role_t(json_object* j) { jcast(uid_, j, "uid"); @@ -111,52 +114,7 @@ const std::vector<interrupt_t>& role_t::interrupts() const 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_DEBUG(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_DEBUG(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; + return interrupts_.size() ? interrupts_[0].apply(req, *this) : 0; } void role_t::invoke(afb_request* req) @@ -202,33 +160,42 @@ void role_t::open(afb_request* r, json_object* o) if (!apply_policy(r)) { - afb_request_context_set( - r, - this, - [](void* arg) - { - role_t * role = (role_t*) arg; + afb_req_context(r, + 0, // Do not replace previous context if any + [](void* arg) -> void* { return new session_t(); }, + [](void* arg) { afb_dynapi * api = ahl_binding_t::instance().handle(); - - AFB_DYNAPI_DEBUG(api, "Released role %s\n", role->uid_.c_str()); - role->opened_ = false; - - // send a mute command to the HAL. We cannot reuse the do_mute function, - // because in the context here, the afb_request is no longer valid. - json_object* a = json_object_new_object(); - json_object_object_add(a, "mute", json_object_new_boolean(true)); - - afb_dynapi_call( - api, - role->hal_.c_str(), - role->stream_.c_str(), - a, - NULL, - NULL); - } + session_t* opened_roles = reinterpret_cast<session_t*>(arg); + for(role_t* role : *opened_roles) + { + AFB_DYNAPI_DEBUG(api, "Released role %s\n", role->uid_.c_str()); + role->opened_ = false; + if(role->interrupts_.size()) role->interrupts_[0].clear(); + + // send a mute command to the HAL. We cannot reuse the do_mute function, + // because in the context here, the afb_request is no longer valid. + json_object* a = json_object_new_object(); + json_object_object_add(a, "mute", json_object_new_boolean(true)); + + afb_dynapi_call( + api, + role->hal_.c_str(), + role->stream_.c_str(), + a, + NULL, + NULL); + } + delete opened_roles; + }, + this ); + opened_ = true; + // Add the current role to the session + session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r)); + context->push_back(this); + json_object* result = json_object_new_object(); json_object_object_add(result, "device_uri", json_object_new_string(device_uri_.c_str())); @@ -244,13 +211,20 @@ void role_t::close(afb_request* r, json_object* o) return; } - if(!afb_request_context_get(r)) + session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r)); + if(!context) { afb_request_fail(r, "Stream is opened by another client!", nullptr); return; } + // Remove the current role from the session. + std::string uid = uid_; + std::remove_if(context->begin(), context->end(), [uid](role_t* r) { return r->uid_ == uid; }); + context->push_back(this); + opened_ = false; + if(interrupts_.size()) interrupts_[0].clear(); afb_request_success(r, nullptr, "Stream closed!"); } |