summaryrefslogtreecommitdiffstats
path: root/ahl-binding/role.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ahl-binding/role.cpp')
-rw-r--r--ahl-binding/role.cpp125
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;