diff options
-rw-r--r-- | ahl-binding/CMakeLists.txt | 58 | ||||
-rw-r--r-- | ahl-binding/ahl-binding.cpp | 528 | ||||
-rw-r--r-- | ahl-binding/ahl-binding.hpp | 52 | ||||
-rw-r--r-- | ahl-binding/config_entry.cpp | 24 | ||||
-rw-r--r-- | ahl-binding/config_entry.hpp | 17 | ||||
-rw-r--r-- | ahl-binding/interrupt.cpp | 220 | ||||
-rw-r--r-- | ahl-binding/interrupt.hpp | 34 | ||||
-rw-r--r-- | ahl-binding/jsonc_utils.hpp | 48 | ||||
-rw-r--r-- | ahl-binding/role.cpp | 410 | ||||
-rw-r--r-- | ahl-binding/role.hpp | 82 |
10 files changed, 736 insertions, 737 deletions
diff --git a/ahl-binding/CMakeLists.txt b/ahl-binding/CMakeLists.txt index bd2be0c..042903c 100644 --- a/ahl-binding/CMakeLists.txt +++ b/ahl-binding/CMakeLists.txt @@ -19,38 +19,38 @@ # Add target to project dependency list PROJECT_TARGET_ADD(audiohighlevel) - # Define project Targets - ADD_LIBRARY(${TARGET_NAME} MODULE - config_entry.cpp - role.cpp - interrupt.cpp - ahl-binding.cpp - ) + # Define project Targets + ADD_LIBRARY(${TARGET_NAME} MODULE + config_entry.cpp + role.cpp + interrupt.cpp + ahl-binding.cpp + ) - # Binder exposes a unique public entry point - SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES - PREFIX "afb-" - LABELS "BINDING" - LINK_FLAGS ${BINDINGS_LINK_FLAG} - OUTPUT_NAME ${TARGET_NAME} - ) + # Binder exposes a unique public entry point + SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + PREFIX "afb-" + LABELS "BINDING" + LINK_FLAGS ${BINDINGS_LINK_FLAG} + OUTPUT_NAME ${TARGET_NAME} + ) - # Define target includes - TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME} - PUBLIC ${GLIB_PKG_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../controller/ctl-lib - ${CMAKE_CURRENT_SOURCE_DIR}/../afb-utilities - ) + # Define target includes + TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME} + PUBLIC ${GLIB_PKG_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../controller/ctl-lib + ${CMAKE_CURRENT_SOURCE_DIR}/../afb-utilities + ) - # Library dependencies (include updates automatically) - # Find package for GLIB does not seem to export - TARGET_LINK_LIBRARIES(${TARGET_NAME} - #ahl-policy + # Library dependencies (include updates automatically) + # Find package for GLIB does not seem to export + TARGET_LINK_LIBRARIES(${TARGET_NAME} + #ahl-policy afb-helpers - ctl-utilities - ${GLIB_PKG_LIBRARIES} - ${link_libraries} - ) + ctl-utilities + ${GLIB_PKG_LIBRARIES} + ${link_libraries} + ) diff --git a/ahl-binding/ahl-binding.cpp b/ahl-binding/ahl-binding.cpp index 98d36b6..3a16197 100644 --- a/ahl-binding/ahl-binding.cpp +++ b/ahl-binding/ahl-binding.cpp @@ -25,7 +25,7 @@ */ int ahl_api_create(void*, afb_api_t handle) { - return ahl_binding_t::instance().preinit(handle); + return ahl_binding_t::instance().preinit(handle); } /** @@ -35,19 +35,19 @@ int ahl_api_create(void*, afb_api_t handle) */ int afbBindingEntry(afb_api_t handle) { - using namespace std::placeholders; - assert(handle != nullptr); - - afb_api_new_api( - handle, - HL_API_NAME, - HL_API_INFO, - 1, - ahl_api_create, - nullptr - ); - - return 0; + using namespace std::placeholders; + assert(handle != nullptr); + + afb_api_new_api( + handle, + HL_API_NAME, + HL_API_INFO, + 1, + ahl_api_create, + nullptr + ); + + return 0; } /** @@ -56,7 +56,7 @@ int afbBindingEntry(afb_api_t handle) */ int ahl_api_init(afb_api_t) { - return ahl_binding_t::instance().init(); + return ahl_binding_t::instance().init(); } /** @@ -66,7 +66,7 @@ int ahl_api_init(afb_api_t) */ void ahl_api_on_event(afb_api_t, const char* e, struct json_object* o) { - ahl_binding_t::instance().event(e, o); + ahl_binding_t::instance().event(e, o); } /** @@ -76,7 +76,7 @@ void ahl_api_on_event(afb_api_t, const char* e, struct json_object* o) */ int ahl_api_config_roles(afb_api_t, CtlSectionT*, json_object* o) { - return ahl_binding_t::instance().parse_roles_config(o); + return ahl_binding_t::instance().parse_roles_config(o); } /** @@ -85,7 +85,7 @@ int ahl_api_config_roles(afb_api_t, CtlSectionT*, json_object* o) */ void ahl_api_get_roles(afb_req_t req) { - ahl_binding_t::instance().get_roles(req); + ahl_binding_t::instance().get_roles(req); } /** @@ -94,7 +94,7 @@ void ahl_api_get_roles(afb_req_t req) */ void ahl_api_subscribe(afb_req_t req) { - ahl_binding_t::instance().subscribe(req); + ahl_binding_t::instance().subscribe(req); } /** @@ -103,7 +103,7 @@ void ahl_api_subscribe(afb_req_t req) */ void ahl_api_unsubscribe(afb_req_t req) { - ahl_binding_t::instance().unsubscribe(req); + ahl_binding_t::instance().unsubscribe(req); } /** @@ -114,17 +114,17 @@ void ahl_api_unsubscribe(afb_req_t req) */ void ahl_api_role(afb_req_t req) { - role_t* role = (role_t*)req->vcbdata; - assert(role != nullptr); + role_t* role = (role_t*)req->vcbdata; + assert(role != nullptr); - role->invoke(req); + role->invoke(req); } /** * @brief Default constructor. */ ahl_binding_t::ahl_binding_t() - : handle_{nullptr} + : handle_{nullptr} { } @@ -134,8 +134,8 @@ ahl_binding_t::ahl_binding_t() */ ahl_binding_t& ahl_binding_t::instance() { - static ahl_binding_t s; - return s; + static ahl_binding_t s; + return s; } /** @@ -145,26 +145,26 @@ ahl_binding_t& ahl_binding_t::instance() */ int ahl_binding_t::preinit(afb_api_t handle) { - handle_ = handle; - - try - { - load_static_verbs(); - load_controller_configs(); - - if (afb_api_on_event(handle_, ahl_api_on_event)) - throw std::runtime_error("Failed to register event handler callback."); - - if (afb_api_on_init(handle_, ahl_api_init)) - throw std::runtime_error("Failed to register init handler callback."); - } - catch(std::exception& e) - { - AFB_API_ERROR(handle, "%s", e.what()); - return -1; - } - - return 0; + handle_ = handle; + + try + { + load_static_verbs(); + load_controller_configs(); + + if (afb_api_on_event(handle_, ahl_api_on_event)) + throw std::runtime_error("Failed to register event handler callback."); + + if (afb_api_on_init(handle_, ahl_api_init)) + throw std::runtime_error("Failed to register init handler callback."); + } + catch(std::exception& e) + { + AFB_API_ERROR(handle, "%s", e.what()); + return -1; + } + + return 0; } /** @@ -172,17 +172,17 @@ int ahl_binding_t::preinit(afb_api_t handle) */ int ahl_binding_t::init() { - using namespace std::placeholders; + using namespace std::placeholders; - if (afb_api_require_api(handle_, HAL_MGR_API, 1)) - { - AFB_API_ERROR(handle_, "Failed to require '%s' API!", HAL_MGR_API); - return -1; - } - AFB_API_NOTICE(handle_, "Required '%s' API found!", HAL_MGR_API); + if (afb_api_require_api(handle_, HAL_MGR_API, 1)) + { + AFB_API_ERROR(handle_, "Failed to require '%s' API!", HAL_MGR_API); + return -1; + } + AFB_API_NOTICE(handle_, "Required '%s' API found!", HAL_MGR_API); - afb_api_seal(handle_); - AFB_API_NOTICE(handle_, "API is now sealed!"); + afb_api_seal(handle_); + AFB_API_NOTICE(handle_, "API is now sealed!"); volume_changed_ = afb_api_make_event(handle_, "volume_changed"); if(!afb_event_is_valid(volume_changed_)) @@ -191,8 +191,8 @@ int ahl_binding_t::init() return -2; } - if (update_streams()) return -1; - return 0; + if (update_streams()) return -1; + return 0; } /** @@ -201,70 +201,70 @@ int ahl_binding_t::init() */ int ahl_binding_t::update_streams() { - json_object* loaded = nullptr; - size_t hals_count = 0, streams_count = 0; - - if (afb_api_call_sync(handle_, "4a-hal-manager", "loaded", json_object_new_object(), &loaded, nullptr, nullptr)) - { - AFB_API_ERROR(handle_, "Failed to call 'loaded' verb on '4a-hal-manager' API!"); - if (loaded) - { - AFB_API_ERROR(handle_, "%s", json_object_to_json_string(loaded)); - json_object_put(loaded); - } - return -1; - } - - if (!json_object_is_type(loaded, json_type_array)) - { - AFB_API_ERROR(handle_, "Expected an array from '4a-hal-manager/loaded', but got something else!"); - json_object_put(loaded); - return -1; - } - hals_count = json_object_array_length(loaded); - - for(int i = 0; i < hals_count; ++i) - { - json_object* info = nullptr; - - const char* halname = json_object_get_string(json_object_array_get_idx(loaded, i)); - AFB_API_DEBUG(handle_, "Found an active HAL: %s", halname); - - if (afb_api_call_sync(handle_, halname, "info", json_object_new_object(), &info, nullptr, nullptr)) - { - AFB_API_ERROR(handle_, "Failed to call 'info' verb on '%s' API!", halname); - if (info) - { - AFB_API_ERROR(handle_, "%s", json_object_to_json_string(info)); - json_object_put(info); - } - json_object_put(loaded); - return -1; - } - - json_object* streamsJ = nullptr; - json_object_object_get_ex(info, "streams", &streamsJ); - streams_count = json_object_array_length(streamsJ); - for(int j = 0; j < streams_count; ++j) - { - json_object * nameJ = nullptr, * cardIdJ = nullptr; - json_object * streamJ = json_object_array_get_idx(streamsJ, j); - - json_object_object_get_ex(streamJ, "name", &nameJ); - json_object_object_get_ex(streamJ, "cardId", &cardIdJ); - - update_stream( - halname, - json_object_get_string(nameJ), - json_object_get_string(cardIdJ) - ); - } - - json_object_put(info); - } - json_object_put(loaded); - - return 0; + json_object* loaded = nullptr; + size_t hals_count = 0, streams_count = 0; + + if (afb_api_call_sync(handle_, "4a-hal-manager", "loaded", json_object_new_object(), &loaded, nullptr, nullptr)) + { + AFB_API_ERROR(handle_, "Failed to call 'loaded' verb on '4a-hal-manager' API!"); + if (loaded) + { + AFB_API_ERROR(handle_, "%s", json_object_to_json_string(loaded)); + json_object_put(loaded); + } + return -1; + } + + if (!json_object_is_type(loaded, json_type_array)) + { + AFB_API_ERROR(handle_, "Expected an array from '4a-hal-manager/loaded', but got something else!"); + json_object_put(loaded); + return -1; + } + hals_count = json_object_array_length(loaded); + + for(int i = 0; i < hals_count; ++i) + { + json_object* info = nullptr; + + const char* halname = json_object_get_string(json_object_array_get_idx(loaded, i)); + AFB_API_DEBUG(handle_, "Found an active HAL: %s", halname); + + if (afb_api_call_sync(handle_, halname, "info", json_object_new_object(), &info, nullptr, nullptr)) + { + AFB_API_ERROR(handle_, "Failed to call 'info' verb on '%s' API!", halname); + if (info) + { + AFB_API_ERROR(handle_, "%s", json_object_to_json_string(info)); + json_object_put(info); + } + json_object_put(loaded); + return -1; + } + + json_object* streamsJ = nullptr; + json_object_object_get_ex(info, "streams", &streamsJ); + streams_count = json_object_array_length(streamsJ); + for(int j = 0; j < streams_count; ++j) + { + json_object * nameJ = nullptr, * cardIdJ = nullptr; + json_object * streamJ = json_object_array_get_idx(streamsJ, j); + + json_object_object_get_ex(streamJ, "name", &nameJ); + json_object_object_get_ex(streamJ, "cardId", &cardIdJ); + + update_stream( + halname, + json_object_get_string(nameJ), + json_object_get_string(cardIdJ) + ); + } + + json_object_put(info); + } + json_object_put(loaded); + + return 0; } /** @@ -275,179 +275,179 @@ int ahl_binding_t::update_streams() */ void ahl_binding_t::update_stream(std::string halname, std::string stream, std::string deviceid) { - for(auto& r : roles_) - { - if(r.stream() == stream) - { - if (r.device_uri().size()) - AFB_API_WARNING(handle_, "Multiple stream with same name: '%s'.", stream.c_str()); - else - { - r.device_uri(deviceid); - r.hal(halname); - } - } - } + for(auto& r : roles_) + { + if(r.stream() == stream) + { + if (r.device_uri().size()) + AFB_API_WARNING(handle_, "Multiple stream with same name: '%s'.", stream.c_str()); + else + { + r.device_uri(deviceid); + r.hal(halname); + } + } + } } void ahl_binding_t::event(std::string name, json_object* arg) { - AFB_API_DEBUG(handle_, "Event '%s' received with the following arg: %s", name.c_str(), json_object_to_json_string(arg)); + AFB_API_DEBUG(handle_, "Event '%s' received with the following arg: %s", name.c_str(), json_object_to_json_string(arg)); } void ahl_binding_t::load_static_verbs() { - if (afb_api_add_verb( - handle_, - "get_roles", - "Retrieve array of available audio roles", - ahl_api_get_roles, - nullptr, - nullptr, - AFB_SESSION_NONE_X2, 0)) - { - throw std::runtime_error("Failed to add 'get_role' verb to the API."); - } - - if (afb_api_add_verb( - handle_, - "subscribe", - "Subscribe to \"volume_changed\" event", - ahl_api_subscribe, - nullptr, - nullptr, - AFB_SESSION_NONE_X2, 0)) - { - throw std::runtime_error("Failed to add 'subscribe' verb to the API."); - } - - if (afb_api_add_verb( - handle_, - "unsubscribe", - "Unsubscribe to \"volume_changed\" event", - ahl_api_unsubscribe, - nullptr, - nullptr, - AFB_SESSION_NONE_X2, 0)) - { - throw std::runtime_error("Failed to add 'unsubscribe' verb to the API."); - } + if (afb_api_add_verb( + handle_, + "get_roles", + "Retrieve array of available audio roles", + ahl_api_get_roles, + nullptr, + nullptr, + AFB_SESSION_NONE_X2, 0)) + { + throw std::runtime_error("Failed to add 'get_role' verb to the API."); + } + + if (afb_api_add_verb( + handle_, + "subscribe", + "Subscribe to \"volume_changed\" event", + ahl_api_subscribe, + nullptr, + nullptr, + AFB_SESSION_NONE_X2, 0)) + { + throw std::runtime_error("Failed to add 'subscribe' verb to the API."); + } + + if (afb_api_add_verb( + handle_, + "unsubscribe", + "Unsubscribe to \"volume_changed\" event", + ahl_api_unsubscribe, + nullptr, + nullptr, + AFB_SESSION_NONE_X2, 0)) + { + throw std::runtime_error("Failed to add 'unsubscribe' verb to the API."); + } } void ahl_binding_t::load_controller_configs() { - char* dir_list = getenv("CONTROL_CONFIG_PATH"); - if (!dir_list) dir_list = strdup(CONTROL_CONFIG_PATH); - struct json_object* config_files = CtlConfigScan(dir_list, "policy"); - if (!config_files) throw std::runtime_error("No config files found!"); - - // Only one file should be found this way, but read all just in case - size_t config_files_count = json_object_array_length(config_files); - for(int i = 0; i < config_files_count; ++i) - { - config_entry_t file {json_object_array_get_idx(config_files, i)}; - - if(load_controller_config(file.filepath()) < 0) - { - std::stringstream ss; - ss << "Failed to load config file '" - << file.filename() - << "' from '" - << file.fullpath() - << "'!"; - throw std::runtime_error(ss.str()); - } - } + char* dir_list = getenv("CONTROL_CONFIG_PATH"); + if (!dir_list) dir_list = strdup(CONTROL_CONFIG_PATH); + struct json_object* config_files = CtlConfigScan(dir_list, "policy"); + if (!config_files) throw std::runtime_error("No config files found!"); + + // Only one file should be found this way, but read all just in case + size_t config_files_count = json_object_array_length(config_files); + for(int i = 0; i < config_files_count; ++i) + { + config_entry_t file {json_object_array_get_idx(config_files, i)}; + + if(load_controller_config(file.filepath()) < 0) + { + std::stringstream ss; + ss << "Failed to load config file '" + << file.filename() + << "' from '" + << file.fullpath() + << "'!"; + throw std::runtime_error(ss.str()); + } + } } int ahl_binding_t::load_controller_config(const std::string& path) { - CtlConfigT* controller_config; - - controller_config = CtlLoadMetaData(handle_, path.c_str()); - if (!controller_config) - { - AFB_API_ERROR(handle_, "Failed to load controller from config file!"); - return -1; - } - - static CtlSectionT controller_sections[] = - { - {.key = "plugins", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = PluginConfig, .handle = nullptr, .actions = nullptr}, - {.key = "onload", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = OnloadConfig, .handle = nullptr, .actions = nullptr}, - {.key = "controls", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = ControlConfig, .handle = nullptr, .actions = nullptr}, - {.key = "events", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = EventConfig, .handle = nullptr, .actions = nullptr}, - {.key = "roles", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = ahl_api_config_roles, .handle = nullptr, .actions = nullptr }, - {.key = nullptr, .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = nullptr, .handle = nullptr, .actions = nullptr} - }; - - CtlLoadSections(handle_, controller_config, controller_sections); - - return 0; + CtlConfigT* controller_config; + + controller_config = CtlLoadMetaData(handle_, path.c_str()); + if (!controller_config) + { + AFB_API_ERROR(handle_, "Failed to load controller from config file!"); + return -1; + } + + static CtlSectionT controller_sections[] = + { + {.key = "plugins", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = PluginConfig, .handle = nullptr, .actions = nullptr}, + {.key = "onload", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = OnloadConfig, .handle = nullptr, .actions = nullptr}, + {.key = "controls", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = ControlConfig, .handle = nullptr, .actions = nullptr}, + {.key = "events", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = EventConfig, .handle = nullptr, .actions = nullptr}, + {.key = "roles", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = ahl_api_config_roles, .handle = nullptr, .actions = nullptr }, + {.key = nullptr, .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = nullptr, .handle = nullptr, .actions = nullptr} + }; + + CtlLoadSections(handle_, controller_config, controller_sections); + + return 0; } int ahl_binding_t::parse_roles_config(json_object* o) { - assert(o != nullptr); - assert(json_object_is_type(o, json_type_array)); + assert(o != nullptr); + assert(json_object_is_type(o, json_type_array)); - if (roles_.size()) return 0; // Roles already added, ignore. + if (roles_.size()) return 0; // Roles already added, ignore. - size_t count = json_object_array_length(o); - roles_.reserve(count); - for(int i = 0; i < count; ++i) - { - json_object* jr = json_object_array_get_idx(o, i); - assert(jr != nullptr); + size_t count = json_object_array_length(o); + roles_.reserve(count); + for(int i = 0; i < count; ++i) + { + json_object* jr = json_object_array_get_idx(o, i); + assert(jr != nullptr); - roles_.push_back(role_t(jr)); - role_t& r = roles_[roles_.size() - 1]; - if(create_api_verb(&r)) - return -1; - } + roles_.push_back(role_t(jr)); + role_t& r = roles_[roles_.size() - 1]; + if(create_api_verb(&r)) + return -1; + } - return 0; + return 0; } int ahl_binding_t::create_api_verb(role_t* r) { - AFB_API_NOTICE(handle_, "New audio role: %s", r->uid().c_str()); - - if (afb_api_add_verb( - handle_, - r->uid().c_str(), - r->description().c_str(), - ahl_api_role, - r, - nullptr, - AFB_SESSION_NONE_X2, 0)) - { - AFB_API_ERROR(handle_, "Failed to add '%s' verb to the API.", - r->uid().c_str()); - return -1; - } - - return 0; + AFB_API_NOTICE(handle_, "New audio role: %s", r->uid().c_str()); + + if (afb_api_add_verb( + handle_, + r->uid().c_str(), + r->description().c_str(), + ahl_api_role, + r, + nullptr, + AFB_SESSION_NONE_X2, 0)) + { + AFB_API_ERROR(handle_, "Failed to add '%s' verb to the API.", + r->uid().c_str()); + return -1; + } + + return 0; } void ahl_binding_t::get_roles(afb_req_t req) const { - json_bool verbose = FALSE; - json_object* arg = afb_req_json(req); - json_object* jverbose; - if (arg != nullptr) - { - json_bool ret = json_object_object_get_ex(arg, "verbose", &jverbose); - if (ret) verbose = json_object_get_boolean(jverbose); - } - - json_object* result = json_object_new_array(); - for(const auto& r : roles_) - { - if (verbose == TRUE || r.device_uri().size()) - json_object_array_add(result, json_object_new_string(r.uid().c_str())); - } - afb_req_success(req, result, nullptr); + json_bool verbose = FALSE; + json_object* arg = afb_req_json(req); + json_object* jverbose; + if (arg != nullptr) + { + json_bool ret = json_object_object_get_ex(arg, "verbose", &jverbose); + if (ret) verbose = json_object_get_boolean(jverbose); + } + + json_object* result = json_object_new_array(); + for(const auto& r : roles_) + { + if (verbose == TRUE || r.device_uri().size()) + json_object_array_add(result, json_object_new_string(r.uid().c_str())); + } + afb_req_success(req, result, nullptr); } void ahl_binding_t::subscribe(afb_req_t req) const @@ -477,10 +477,10 @@ int ahl_binding_t::emit_volume_changed(const std::string& role, int volume) cons const std::vector<role_t> ahl_binding_t::roles() const { - return roles_; + return roles_; } afb_api_t ahl_binding_t::handle() const { - return handle_; + return handle_; } diff --git a/ahl-binding/ahl-binding.hpp b/ahl-binding/ahl-binding.hpp index 24f4acb..9e670bb 100644 --- a/ahl-binding/ahl-binding.hpp +++ b/ahl-binding/ahl-binding.hpp @@ -36,41 +36,41 @@ class ahl_binding_t { - using role_action = std::function<void(afb_req_t, std::string, std::string, json_object*)>; + using role_action = std::function<void(afb_req_t, std::string, std::string, json_object*)>; private: - afb_api_t handle_; - afb_event_t volume_changed_; - std::vector<role_t> roles_; + afb_api_t handle_; + afb_event_t volume_changed_; + std::vector<role_t> roles_; - explicit ahl_binding_t(); + explicit ahl_binding_t(); - void load_static_verbs(); + void load_static_verbs(); - void load_controller_configs(); - int load_controller_config(const std::string& path); - int update_streams(); - void update_stream(std::string hal, std::string stream, std::string deviceuri); - int create_api_verb(role_t* r); + void load_controller_configs(); + int load_controller_config(const std::string& path); + int update_streams(); + void update_stream(std::string hal, std::string stream, std::string deviceuri); + int create_api_verb(role_t* r); - void policy_open(afb_req_t req, const role_t& role); + void policy_open(afb_req_t req, const role_t& role); public: - static ahl_binding_t& instance(); - int preinit(afb_api_t handle); - int init(); - void event(std::string name, json_object* arg); - void get_roles(afb_req_t req) const; - void subscribe(afb_req_t req) const; - void unsubscribe(afb_req_t req) const; - int emit_volume_changed(const std::string& role, int volume) const; - - const std::vector<role_t> roles() const; - afb_api_t handle() const; - - void audiorole(afb_req_t req); - int parse_roles_config(json_object* o); + static ahl_binding_t& instance(); + int preinit(afb_api_t handle); + int init(); + void event(std::string name, json_object* arg); + void get_roles(afb_req_t req) const; + void subscribe(afb_req_t req) const; + void unsubscribe(afb_req_t req) const; + int emit_volume_changed(const std::string& role, int volume) const; + + const std::vector<role_t> roles() const; + afb_api_t handle() const; + + void audiorole(afb_req_t req); + int parse_roles_config(json_object* o); }; diff --git a/ahl-binding/config_entry.cpp b/ahl-binding/config_entry.cpp index 65d7a40..8685d34 100644 --- a/ahl-binding/config_entry.cpp +++ b/ahl-binding/config_entry.cpp @@ -18,45 +18,45 @@ #include "config_entry.hpp" config_entry_t::config_entry_t(std::string fp, std::string fn) - : fullpath_{fp} - , filename_{fn} + : fullpath_{fp} + , filename_{fn} { } config_entry_t::config_entry_t(struct json_object* j) { - jcast(fullpath_, j, "fullpath"); - jcast(filename_, j, "filename"); + jcast(fullpath_, j, "fullpath"); + jcast(filename_, j, "filename"); } config_entry_t& config_entry_t::operator<<(struct json_object* j) { - jcast(fullpath_, j, "fullpath"); - jcast(filename_, j, "filename"); - return *this; + jcast(fullpath_, j, "fullpath"); + jcast(filename_, j, "filename"); + return *this; } std::string config_entry_t::fullpath() const { - return fullpath_; + return fullpath_; } std::string config_entry_t::filename() const { - return filename_; + return filename_; } std::string config_entry_t::filepath() const { - return fullpath_ + '/' + filename_; + return fullpath_ + '/' + filename_; } void config_entry_t::fullpath(std::string fp) { - fullpath_ = fp; + fullpath_ = fp; } void config_entry_t::finename(std::string fn) { - filename_ = fn; + filename_ = fn; } diff --git a/ahl-binding/config_entry.hpp b/ahl-binding/config_entry.hpp index 492eed2..58b0b06 100644 --- a/ahl-binding/config_entry.hpp +++ b/ahl-binding/config_entry.hpp @@ -24,26 +24,25 @@ class config_entry_t private: std::string fullpath_; std::string filename_; - + public: explicit config_entry_t() = default; explicit config_entry_t(const config_entry_t&) = default; - explicit config_entry_t(config_entry_t&&) = default; - + explicit config_entry_t(config_entry_t&&) = default; + ~config_entry_t() = default; - + config_entry_t& operator=(const config_entry_t&) = default; - config_entry_t& operator=(config_entry_t&&) = default; - + config_entry_t& operator=(config_entry_t&&) = default; + explicit config_entry_t(std::string fp, std::string fn); explicit config_entry_t(struct json_object* j); config_entry_t& operator<<(struct json_object* j); - + std::string fullpath() const; std::string filename() const; std::string filepath() const; - + void fullpath(std::string fp); void finename(std::string fn); - }; diff --git a/ahl-binding/interrupt.cpp b/ahl-binding/interrupt.cpp index 5bf0b79..a0fa563 100644 --- a/ahl-binding/interrupt.cpp +++ b/ahl-binding/interrupt.cpp @@ -5,147 +5,147 @@ interrupt_t::interrupt_t(json_object* o) { - jcast(type_, o, "type"); - json_object * value = NULL; - json_object_object_get_ex(o, "args", &value); - args_ = value; + jcast(type_, o, "type"); + json_object * value = NULL; + json_object_object_get_ex(o, "args", &value); + args_ = value; } interrupt_t& interrupt_t::operator<<(json_object* o) { - jcast(type_, o, "type"); - json_object * value = NULL; - json_object_object_get_ex(o, "args", &value); - args_ = value; - return *this; + jcast(type_, o, "type"); + json_object * value = NULL; + json_object_object_get_ex(o, "args", &value); + args_ = value; + return *this; } std::string interrupt_t::type() const { - return type_; + return type_; } json_object* interrupt_t::args() const { - return args_; + return args_; } void interrupt_t::type(std::string v) { - type_ = v; + type_ = v; } void interrupt_t::args(json_object* v) { - args_ = v; + args_ = v; } int interrupt_t::apply(afb_req_t req, const role_t& role) { - /*if (type_ == "mute") - { - } - else if (type_ == "continue") - { - } - else if (type_ == "cancel") - { - } - else */if (type_ == "ramp") - { - for(const auto& r: ahl_binding_t::instance().roles()) - { - if (r.opened() && role.priority() > r.priority()) - { - // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } } - json_object* arg = json_object_new_object(); - json_object_object_add(arg, "ramp", args_); - json_object_get(args_); - json_object* result = nullptr; + /*if (type_ == "mute") + { + } + else if (type_ == "continue") + { + } + else if (type_ == "cancel") + { + } + else */if (type_ == "ramp") + { + for(const auto& r: ahl_binding_t::instance().roles()) + { + if (r.opened() && role.priority() > r.priority()) + { + // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } } + json_object* arg = json_object_new_object(); + json_object_object_add(arg, "ramp", args_); + json_object_get(args_); + json_object* result = nullptr; - AFB_API_DEBUG(ahl_binding_t::instance().handle(), - "Call '%s'/'%s' '%s'", - r.hal().c_str(), r.stream().c_str(), json_object_to_json_string(arg)); + AFB_API_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_api_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result, nullptr, nullptr)) - { - afb_req_fail(req, "Failed to call 'ramp' action on stream", nullptr); - return -1; - } - json_object* jvolold = nullptr; - if (json_object_object_get_ex(result, "volold", &jvolold)) - { - applied_on_.push_back(std::make_tuple<std::string, int>(r.uid(), json_object_get_int(jvolold))); - AFB_API_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(), role.stream().c_str()); - } - } - } - return 0; - } - else - { - afb_req_fail(req, "Unkown interrupt uid!", nullptr); - return -1; - } + if(afb_api_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result, nullptr, nullptr)) + { + afb_req_fail(req, "Failed to call 'ramp' action on stream", nullptr); + return -1; + } + json_object* jvolold = nullptr; + if (json_object_object_get_ex(result, "volold", &jvolold)) + { + applied_on_.push_back(std::make_tuple<std::string, int>(r.uid(), json_object_get_int(jvolold))); + AFB_API_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(), role.stream().c_str()); + } + } + } + return 0; + } + else + { + afb_req_fail(req, "Unkown interrupt uid!", nullptr); + return -1; + } } void interrupt_t::clear() { - for (const std::tuple<std::string, int>& state : applied_on_) - { - std::string role; - int vol; - std::tie(role, vol) = state; - /*if (type_ == "mute") - { - } - else if (type_ == "continue") - { - } - else if (type_ == "cancel") - { - } - else */if (type_ == "ramp") - { - for(const auto& r: ahl_binding_t::instance().roles()) - { - if (r.uid() == role) - { - // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } } - // Create an fake-interrupt, with the old volume - json_object* interrupt = json_tokener_parse(json_object_to_json_string(args_)); - json_object_object_add(interrupt, "volume", json_object_new_int(vol)); // Replace the volume - /* - json_object* volume = nullptr; - if (json_object_object_get_ex(interrupt, "volume", &volume)) - { - json_object_set_int(volume, vol); - } - */ + for (const std::tuple<std::string, int>& state : applied_on_) + { + std::string role; + int vol; + std::tie(role, vol) = state; + /*if (type_ == "mute") + { + } + else if (type_ == "continue") + { + } + else if (type_ == "cancel") + { + } + else */if (type_ == "ramp") + { + for(const auto& r: ahl_binding_t::instance().roles()) + { + if (r.uid() == role) + { + // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } } + // Create an fake-interrupt, with the old volume + json_object* interrupt = json_tokener_parse(json_object_to_json_string(args_)); + json_object_object_add(interrupt, "volume", json_object_new_int(vol)); // Replace the volume + /* + json_object* volume = nullptr; + if (json_object_object_get_ex(interrupt, "volume", &volume)) + { + json_object_set_int(volume, vol); + } + */ - json_object* arg = json_object_new_object(); - json_object_object_add(arg, "ramp", interrupt); - json_object* result = nullptr; + json_object* arg = json_object_new_object(); + json_object_object_add(arg, "ramp", interrupt); + json_object* result = nullptr; - AFB_API_DEBUG(ahl_binding_t::instance().handle(), - "Call '%s'/'%s' '%s", - r.hal().c_str(), r.stream().c_str(), json_object_to_json_string(arg)); + AFB_API_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_api_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result, nullptr, nullptr)) - { - AFB_API_ERROR(ahl_binding_t::instance().handle(), - "Failed to call 'ramp' action on '%s'", role.c_str()); - } - else - { - AFB_API_DEBUG(ahl_binding_t::instance().handle(), - "Called 'ramp' action on '%s'", role.c_str()); - } - } - } - } - } - applied_on_.clear(); + if(afb_api_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result, nullptr, nullptr)) + { + AFB_API_ERROR(ahl_binding_t::instance().handle(), + "Failed to call 'ramp' action on '%s'", role.c_str()); + } + else + { + AFB_API_DEBUG(ahl_binding_t::instance().handle(), + "Called 'ramp' action on '%s'", role.c_str()); + } + } + } + } + } + applied_on_.clear(); } diff --git a/ahl-binding/interrupt.hpp b/ahl-binding/interrupt.hpp index c123699..d0caf79 100644 --- a/ahl-binding/interrupt.hpp +++ b/ahl-binding/interrupt.hpp @@ -11,27 +11,27 @@ class role_t; class interrupt_t { private: - std::string type_; - json_object* args_; - std::vector<std::tuple<std::string, uint32_t>> applied_on_; + std::string type_; + json_object* args_; + std::vector<std::tuple<std::string, uint32_t>> applied_on_; public: - explicit interrupt_t() = default; - explicit interrupt_t(const interrupt_t&) = default; - explicit interrupt_t(interrupt_t&&) = default; - ~interrupt_t() = default; + explicit interrupt_t() = default; + explicit interrupt_t(const interrupt_t&) = default; + explicit interrupt_t(interrupt_t&&) = default; + ~interrupt_t() = default; - interrupt_t& operator=(const interrupt_t&) = default; - interrupt_t& operator=(interrupt_t&&) = default; + interrupt_t& operator=(const interrupt_t&) = default; + interrupt_t& operator=(interrupt_t&&) = default; - explicit interrupt_t(json_object* o); - interrupt_t& operator<<(json_object* o); + explicit interrupt_t(json_object* o); + interrupt_t& operator<<(json_object* o); - std::string type() const; - json_object* args() const; + std::string type() const; + json_object* args() const; - void type(std::string v); - void args(json_object* v); - int apply(afb_req_t req, const role_t& role); - void clear(); + void type(std::string v); + void args(json_object* v); + int apply(afb_req_t req, const role_t& role); + void clear(); }; diff --git a/ahl-binding/jsonc_utils.hpp b/ahl-binding/jsonc_utils.hpp index 097eda4..4657611 100644 --- a/ahl-binding/jsonc_utils.hpp +++ b/ahl-binding/jsonc_utils.hpp @@ -24,58 +24,58 @@ template<class T> inline T& jcast(T& v, json_object* o) { - v << o; - return v; + v << o; + return v; } template<class T> inline T& jcast_array(T& v, json_object* o) { - if (o == nullptr) return v; - auto sz = json_object_array_length(o); - for(auto i = 0; i < sz ; ++i) - { - typename T::value_type item; - jcast(item, json_object_array_get_idx(o, i)); - v.push_back(item); - } - return v; + if (o == nullptr) return v; + auto sz = json_object_array_length(o); + for(auto i = 0; i < sz ; ++i) + { + typename T::value_type item; + jcast(item, json_object_array_get_idx(o, i)); + v.push_back(item); + } + return v; } template<> inline bool& jcast<bool>(bool& v, json_object* o) { - v = (json_object_get_boolean(o) == TRUE); - return v; + v = (json_object_get_boolean(o) == TRUE); + return v; } template<> inline double& jcast<double>(double& v, json_object* o) { - v = json_object_get_double(o); - return v; + v = json_object_get_double(o); + return v; } template<> inline int32_t& jcast<int32_t>(int32_t& v, json_object* o) { - v = json_object_get_int(o); - return v; + v = json_object_get_int(o); + return v; } template<> inline int64_t& jcast<int64_t>(int64_t& v, json_object* o) { - v = json_object_get_int(o); - return v; + v = json_object_get_int(o); + return v; } template<> inline std::string& jcast<std::string>(std::string& v, json_object* o) { - const char* tmp = json_object_get_string(o); - v = tmp ? tmp : ""; - return v; + const char* tmp = json_object_get_string(o); + v = tmp ? tmp : ""; + return v; } template<class T> @@ -83,7 +83,7 @@ inline T& jcast(T& v, json_object* o, std::string field) { json_object * value; json_object_object_get_ex(o, field.c_str(), &value); - return jcast<T>(v, value); + return jcast<T>(v, value); } template<class T> @@ -91,5 +91,5 @@ inline T& jcast_array(T& v, json_object* o, std::string field) { json_object * value; json_object_object_get_ex(o, field.c_str(), &value); - return jcast_array<T>(v, value); + return jcast_array<T>(v, value); } diff --git a/ahl-binding/role.cpp b/ahl-binding/role.cpp index 3a4dd0e..635e585 100644 --- a/ahl-binding/role.cpp +++ b/ahl-binding/role.cpp @@ -24,208 +24,208 @@ using session_t = std::vector<role_t*>; role_t::role_t(json_object* j) { - jcast(uid_, j, "uid"); - jcast(description_, j, "description"); - jcast(priority_, j, "priority"); - jcast(stream_, j, "stream"); - jcast_array(interrupts_, j, "interrupts"); - opened_ = false; + jcast(uid_, j, "uid"); + 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(description_, j, "description"); - jcast(priority_, j, "priority"); - jcast(stream_, j, "stream"); - jcast_array(interrupts_, j, "interrupts"); - return *this; + jcast(uid_, j, "uid"); + jcast(description_, j, "description"); + jcast(priority_, j, "priority"); + jcast(stream_, j, "stream"); + jcast_array(interrupts_, j, "interrupts"); + return *this; } std::string role_t::uid() const { - return uid_; + return uid_; } std::string role_t::description() const { - return description_; + return description_; } std::string role_t::hal() const { - return hal_; + return hal_; } std::string role_t::stream() const { - return stream_; + return stream_; } int role_t::priority() const { - return priority_; + return priority_; } std::string role_t::device_uri() const { - return device_uri_; + return device_uri_; } bool role_t::opened() const { - return opened_; + return opened_; } void role_t::uid(std::string v) { - uid_ = v; + uid_ = v; } void role_t::description(std::string v) { - description_ = v; + description_ = v; } void role_t::hal(std::string v) { - hal_ = v; + hal_ = v; } void role_t::stream(std::string v) { - stream_ = v; + stream_ = v; } void role_t::priority(int v) { - priority_ = v; + priority_ = v; } void role_t::device_uri(std::string v) { - device_uri_ = v; + device_uri_ = v; } const std::vector<interrupt_t>& role_t::interrupts() const { - return interrupts_; + return interrupts_; } int role_t::apply_policy(afb_req_t req) { - return interrupts_.size() ? interrupts_[0].apply(req, *this) : 0; + return interrupts_.size() ? interrupts_[0].apply(req, *this) : 0; } void role_t::invoke(afb_req_t req) { - json_object* arg = afb_req_json(req); - if (arg == nullptr) - { - afb_req_fail(req, "No valid argument!", nullptr); - return; - } - - json_object* jaction; - json_bool ret = json_object_object_get_ex(arg, "action", &jaction); - if (!ret) - { - afb_req_fail(req, "No valid action!", nullptr); - return; - } - - std::string action = json_object_get_string(jaction); - if (action.size() == 0) - { - afb_req_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 if (action == "mute") mute(req, arg); - else if (action == "unmute") unmute(req, arg); - else afb_req_fail(req, "Unknown action!", nullptr); + json_object* arg = afb_req_json(req); + if (arg == nullptr) + { + afb_req_fail(req, "No valid argument!", nullptr); + return; + } + + json_object* jaction; + json_bool ret = json_object_object_get_ex(arg, "action", &jaction); + if (!ret) + { + afb_req_fail(req, "No valid action!", nullptr); + return; + } + + std::string action = json_object_get_string(jaction); + if (action.size() == 0) + { + afb_req_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 if (action == "mute") mute(req, arg); + else if (action == "unmute") unmute(req, arg); + else afb_req_fail(req, "Unknown action!", nullptr); } void role_t::open(afb_req_t r, json_object* o) { - if (opened_) - { - afb_req_fail(r, "Already opened!", nullptr); - return; - } - - if (!apply_policy(r)) - { - afb_req_context(r, - 0, // Do not replace previous context if any - [](void* arg) -> void* { return new session_t(); }, - [](void* arg) { - afb_api_t api = ahl_binding_t::instance().handle(); - session_t* opened_roles = reinterpret_cast<session_t*>(arg); - for(role_t* role : *opened_roles) - { - AFB_API_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_api_call( - api, - role->hal_.c_str(), - role->stream_.c_str(), - a, - NULL, - NULL); - } - delete opened_roles; - }, - nullptr - ); - - opened_ = true; - - // Add the current role to the session - session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r)); - if(context) 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())); - - afb_req_success(r, result, nullptr); - } + if (opened_) + { + afb_req_fail(r, "Already opened!", nullptr); + return; + } + + if (!apply_policy(r)) + { + afb_req_context(r, + 0, // Do not replace previous context if any + [](void* arg) -> void* { return new session_t(); }, + [](void* arg) { + afb_api_t api = ahl_binding_t::instance().handle(); + session_t* opened_roles = reinterpret_cast<session_t*>(arg); + for(role_t* role : *opened_roles) + { + AFB_API_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_api_call( + api, + role->hal_.c_str(), + role->stream_.c_str(), + a, + NULL, + NULL); + } + delete opened_roles; + }, + nullptr + ); + + opened_ = true; + + // Add the current role to the session + session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r)); + if(context) 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())); + + afb_req_success(r, result, nullptr); + } } void role_t::close(afb_req_t r, json_object* o) { - if (!opened_) - { - afb_req_success(r, nullptr, "Already closed!"); - return; - } - - session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r)); - if(!context) - { - afb_req_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_req_success(r, nullptr, "Stream closed!"); + if (!opened_) + { + afb_req_success(r, nullptr, "Already closed!"); + return; + } + + session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r)); + if(!context) + { + afb_req_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_req_success(r, nullptr, "Stream closed!"); } void role_t::mute(afb_req_t r, json_object* o) { @@ -238,100 +238,100 @@ void role_t::unmute(afb_req_t r, json_object *o) { void role_t::do_mute(afb_req_t r, bool v) { - json_object* a = json_object_new_object(); - json_object_object_add(a, "mute", json_object_new_boolean(v)); - afb_api_t api = ahl_binding_t::instance().handle(); - - afb_api_call( - api, - hal_.c_str(), - stream_.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)); - afb_req_t r = (afb_req_t)closure; - - json_object_get(result); - if (error) afb_req_fail(r, json_object_to_json_string(result), nullptr); - else afb_req_success(r, result, nullptr); - afb_req_unref(r); - }, - afb_req_addref(r)); + json_object* a = json_object_new_object(); + json_object_object_add(a, "mute", json_object_new_boolean(v)); + afb_api_t api = ahl_binding_t::instance().handle(); + + afb_api_call( + api, + hal_.c_str(), + stream_.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)); + afb_req_t r = (afb_req_t)closure; + + json_object_get(result); + if (error) afb_req_fail(r, json_object_to_json_string(result), nullptr); + else afb_req_success(r, result, nullptr); + afb_req_unref(r); + }, + afb_req_addref(r)); } struct volumeclosure { - std::string role; - afb_req_t req; + std::string role; + afb_req_t req; }; void role_t::volume(afb_req_t r, json_object* o) { afb_api_t api = ahl_binding_t::instance().handle(); - if(!afb_req_has_permission(r, "urn:AGL:permission::public:4a-audio-mixer")) - { - if (!opened_) - { - afb_req_fail(r, "You have to open the stream first!", nullptr); - return; - } - - if(!afb_req_context_get(r)) - { - afb_req_fail(r, "Stream is opened by another client!", nullptr); - return; - } - } - else - { - AFB_API_DEBUG(api, "Granted special audio-mixer permission to change volume"); - } - - json_object* value; - json_bool ret = json_object_object_get_ex(o, "value", &value); - if (!ret) - { - afb_req_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); + if(!afb_req_has_permission(r, "urn:AGL:permission::public:4a-audio-mixer")) + { + if (!opened_) + { + afb_req_fail(r, "You have to open the stream first!", nullptr); + return; + } + + if(!afb_req_context_get(r)) + { + afb_req_fail(r, "Stream is opened by another client!", nullptr); + return; + } + } + else + { + AFB_API_DEBUG(api, "Granted special audio-mixer permission to change volume"); + } + + json_object* value; + json_bool ret = json_object_object_get_ex(o, "value", &value); + if (!ret) + { + afb_req_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); volumeclosure* userdata = new volumeclosure(); userdata->role = uid_; userdata->req = afb_req_addref(r); - afb_api_call( - api, - hal_.c_str(), - stream_.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); - else - { - json_object* volnew; - if (json_object_object_get_ex(result, "volnew", &volnew)) - { - ahl_binding_t::instance().emit_volume_changed(r->role, json_object_get_int(volnew)); - } - afb_req_success(r->req, result, nullptr); - } - afb_req_unref(r->req); - delete r; - }, - userdata - ); + afb_api_call( + api, + hal_.c_str(), + stream_.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); + else + { + json_object* volnew; + if (json_object_object_get_ex(result, "volnew", &volnew)) + { + ahl_binding_t::instance().emit_volume_changed(r->role, json_object_get_int(volnew)); + } + afb_req_success(r->req, result, nullptr); + } + afb_req_unref(r->req); + delete r; + }, + userdata + ); } void role_t::interrupt(afb_req_t r, json_object* o) diff --git a/ahl-binding/role.hpp b/ahl-binding/role.hpp index 055a405..e0c979a 100644 --- a/ahl-binding/role.hpp +++ b/ahl-binding/role.hpp @@ -24,59 +24,59 @@ class role_t { private: - // Members filled by config - std::string uid_; - std::string description_; - std::string hal_; - std::string stream_; - int priority_; - std::vector<interrupt_t> interrupts_; + // Members filled by config + std::string uid_; + std::string description_; + std::string hal_; + std::string stream_; + int priority_; + std::vector<interrupt_t> interrupts_; - std::string device_uri_; - bool opened_ = false; + std::string device_uri_; + bool opened_ = false; - int apply_policy(afb_req_t req); + int apply_policy(afb_req_t req); - void do_mute(afb_req_t, bool); + void do_mute(afb_req_t, bool); public: - explicit role_t() = default; - explicit role_t(const role_t&) = default; - explicit role_t(role_t&&) = default; + explicit role_t() = default; + explicit role_t(const role_t&) = default; + explicit role_t(role_t&&) = default; - ~role_t() = default; + ~role_t() = default; - role_t& operator=(const role_t&) = default; - role_t& operator=(role_t&&) = default; + role_t& operator=(const role_t&) = default; + role_t& operator=(role_t&&) = default; - static role_t from_json(json_object* o); + static role_t from_json(json_object* o); - explicit role_t(json_object* j); + explicit role_t(json_object* j); - role_t& operator<<(json_object* j); + role_t& operator<<(json_object* j); - std::string uid() const; - std::string description() const; - std::string hal() const; - std::string stream() const; - int priority() const; - const std::vector<interrupt_t>& interrupts() const; - std::string device_uri() const; - bool opened() const; + std::string uid() const; + std::string description() const; + std::string hal() const; + std::string stream() const; + int priority() const; + const std::vector<interrupt_t>& interrupts() const; + std::string device_uri() const; + bool opened() const; - void uid(std::string v); - void description(std::string v); - void hal(std::string v); - void stream(std::string v); - void device_uri(std::string v); - void priority(int v); + void uid(std::string v); + void description(std::string v); + void hal(std::string v); + void stream(std::string v); + void device_uri(std::string v); + void priority(int v); - void invoke(afb_req_t r); + void invoke(afb_req_t r); - void open(afb_req_t r, json_object* o); - void close(afb_req_t r, json_object* o); - void volume(afb_req_t r, json_object* o); - void interrupt(afb_req_t r, json_object* o); - void mute(afb_req_t r, json_object* o); - void unmute(afb_req_t r, json_object* o); + void open(afb_req_t r, json_object* o); + void close(afb_req_t r, json_object* o); + void volume(afb_req_t r, json_object* o); + void interrupt(afb_req_t r, json_object* o); + void mute(afb_req_t r, json_object* o); + void unmute(afb_req_t r, json_object* o); }; |