diff options
Diffstat (limited to 'ahl-binding/role.cpp')
-rw-r--r-- | ahl-binding/role.cpp | 125 |
1 files changed, 99 insertions, 26 deletions
diff --git a/ahl-binding/role.cpp b/ahl-binding/role.cpp index 3a4dd0e..1a5d7ba 100644 --- a/ahl-binding/role.cpp +++ b/ahl-binding/role.cpp @@ -22,23 +22,55 @@ using session_t = std::vector<role_t*>; +inline restype_t fromstring(const std::string& str) +{ + if (str == "" || str == "stream") return restype_t::stream; + if (str == "playback") return restype_t::playback; + if (str == "control") return restype_t::control; + + std::stringstream ss; + ss << "Unknown resource type: " << str; + throw std::runtime_error(ss.str()); +} + role_t::role_t(json_object* j) { + rtype_ = restype_t::stream; + jcast(uid_, j, "uid"); jcast(description_, j, "description"); jcast(priority_, j, "priority"); - jcast(stream_, j, "stream"); + jcast(resource_, j, "resource"); jcast_array(interrupts_, j, "interrupts"); + + std::string type; + jcast(type, j, "type"); + rtype_ = fromstring(type); + + // device_uri_ = (rtype_ == restype_t::stream) ? "" : resource_; + if (rtype_ == restype_t::control) + { + device_uri_ = resource_; + hal_ = "4a-hal-csl-cm106-8ch-usb"; + } opened_ = false; } role_t& role_t::operator<<(json_object* j) { + rtype_ = restype_t::stream; + jcast(uid_, j, "uid"); jcast(description_, j, "description"); jcast(priority_, j, "priority"); - jcast(stream_, j, "stream"); + jcast(resource_, j, "resource"); jcast_array(interrupts_, j, "interrupts"); + + std::string type; + jcast(type, j, "type"); + rtype_ = fromstring(type); + + // device_uri_ = (rtype_ == restype_t::stream) ? "" : resource_; return *this; } @@ -57,9 +89,14 @@ std::string role_t::hal() const return hal_; } -std::string role_t::stream() const +std::string role_t::resource() const { - return stream_; + return resource_; +} + +restype_t role_t::rtype() const +{ + return rtype_; } int role_t::priority() const @@ -67,6 +104,11 @@ int role_t::priority() const return priority_; } +const std::vector<interrupt_t>& role_t::interrupts() const +{ + return interrupts_; +} + std::string role_t::device_uri() const { return device_uri_; @@ -92,9 +134,14 @@ void role_t::hal(std::string v) hal_ = v; } -void role_t::stream(std::string v) +void role_t::resource(std::string v) +{ + resource_ = v; +} + +void role_t::rtype(restype_t v) { - stream_ = v; + rtype_ = v; } void role_t::priority(int v) @@ -107,11 +154,6 @@ void role_t::device_uri(std::string v) device_uri_ = v; } -const std::vector<interrupt_t>& role_t::interrupts() const -{ - return interrupts_; -} - int role_t::apply_policy(afb_req_t req) { return interrupts_.size() ? interrupts_[0].apply(req, *this) : 0; @@ -158,7 +200,11 @@ void role_t::open(afb_req_t r, json_object* o) return; } - if (!apply_policy(r)) + if (rtype_ != restype_t::stream) + { + afb_req_fail(r, "Only stream resources can be opened!", nullptr); + } + else if (!apply_policy(r)) { afb_req_context(r, 0, // Do not replace previous context if any @@ -180,7 +226,7 @@ void role_t::open(afb_req_t r, json_object* o) afb_api_call( api, role->hal_.c_str(), - role->stream_.c_str(), + role->resource_.c_str(), a, NULL, NULL); @@ -229,11 +275,13 @@ void role_t::close(afb_req_t r, json_object* o) } void role_t::mute(afb_req_t r, json_object* o) { - do_mute(r, true); + if (rtype_ != restype_t::stream) afb_req_fail(r, "Only stream resource can be muted!", nullptr); + else do_mute(r, true); } void role_t::unmute(afb_req_t r, json_object *o) { - do_mute(r, false); + if (rtype_ != restype_t::stream) afb_req_fail(r, "Only stream resource can be unmuted!", nullptr); + else do_mute(r, false); } void role_t::do_mute(afb_req_t r, bool v) { @@ -245,7 +293,7 @@ void role_t::do_mute(afb_req_t r, bool v) { afb_api_call( api, hal_.c_str(), - stream_.c_str(), + resource_.c_str(), a, [](void* closure, json_object* result, const char* error, const char* info, afb_api_t handle) { @@ -262,7 +310,7 @@ void role_t::do_mute(afb_req_t r, bool v) { struct volumeclosure { - std::string role; + role_t* role; afb_req_t req; }; @@ -300,32 +348,57 @@ void role_t::volume(afb_req_t r, json_object* o) json_object_get(value); json_object* a = json_object_new_object(); - json_object_object_add(a, "volume", value); + json_object_object_add(a, (rtype_ == restype_t::control ? "value" : "volume"), value); + + AFB_API_DEBUG(api, "VOLUME QUERY: %s", json_object_to_json_string(a)); volumeclosure* userdata = new volumeclosure(); - userdata->role = uid_; + userdata->role = this; userdata->req = afb_req_addref(r); afb_api_call( api, hal_.c_str(), - stream_.c_str(), + resource_.c_str(), a, [](void* closure, json_object* result, const char* error, const char* info, afb_api_t handle) { AFB_API_DEBUG(handle, "Got the following answer: %s", json_object_to_json_string(result)); volumeclosure* r = reinterpret_cast<volumeclosure*>(closure); - json_object_get(result); - if (error) afb_req_fail(r->req, json_object_to_json_string(result), nullptr); + if (error) + { + json_object_get(result); + afb_req_fail(r->req, json_object_to_json_string(result), nullptr); + } else { - json_object* volnew; - if (json_object_object_get_ex(result, "volnew", &volnew)) + if (r->role->rtype() == restype_t::control) + { + int average = 0; + size_t arraylen = json_object_array_length(result); + for (size_t i = 0; i < arraylen; ++i) + { + average += json_object_get_int(json_object_array_get_idx(result, i)); + } + average = average / (int)arraylen; + + json_object* response = json_object_new_object(); + json_object* newvol = json_object_new_int(average); + json_object_object_add(response, "newvol", newvol); + ahl_binding_t::instance().emit_volume_changed(r->role->uid(), average); + afb_req_success(r->req, response, nullptr); + } + else { - ahl_binding_t::instance().emit_volume_changed(r->role, json_object_get_int(volnew)); + json_object* volnew; + if (json_object_object_get_ex(result, "volnew", &volnew)) + { + ahl_binding_t::instance().emit_volume_changed(r->role->uid(), json_object_get_int(volnew)); + } + json_object_get(result); + afb_req_success(r->req, result, nullptr); } - afb_req_success(r->req, result, nullptr); } afb_req_unref(r->req); delete r; |