From bde7b86bd6632ccf17abae508a85928ea46d7ba7 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Sat, 14 Sep 2013 14:11:32 +0300 Subject: [PATCH] telephony: plugin arguments for resource set configuration The resource set the plugin controls on behalf of the telephony stack is now configurable using plugin arguments. Currently the resource set zone, class and priority as well as the playback and recording resource names, role, optionality and shareability are configurable. The policies are currently always set to relaxed. Adding configurability for this using a plugin argument is now trivial if needed. Change-Id: Ia80245c458014231fed1bb62cf3c660d091cd075 --- src/plugins/plugin-telephony.c | 66 +++++++++++---- src/plugins/telephony/resctl.c | 183 +++++++++++++++++++++++++++++++++++++++-- src/plugins/telephony/resctl.h | 4 + 3 files changed, 229 insertions(+), 24 deletions(-) diff --git a/src/plugins/plugin-telephony.c b/src/plugins/plugin-telephony.c index 83cd82d..691c3fb 100644 --- a/src/plugins/plugin-telephony.c +++ b/src/plugins/plugin-telephony.c @@ -36,18 +36,40 @@ #include #include -#include "murphy/plugins/telephony/ofono.h" -#include "murphy/plugins/telephony/telephony.h" +#include "telephony/resctl.h" +#include "telephony/ofono.h" +#include "telephony/telephony.h" + +enum { + ARG_ZONE, /* resource set zone */ + ARG_CLASS, /* application class */ + ARG_PRIORITY, /* priority within class */ + ARG_PLAYBACK, /* playback resource config */ + ARG_RECORDING, /* recording resource config */ + ARG_ROLE, /* (media) role attribute */ +}; mrp_plugin_t *telephony_plugin; + static int telephony_init(mrp_plugin_t *plugin) { - mrp_context_t *ctx = plugin->ctx; - - mrp_log_info("%s() called...", __FUNCTION__); + mrp_context_t *ctx = plugin->ctx; + mrp_plugin_arg_t *args = plugin->args; + const char *zone = args[ARG_ZONE].str; + const char *cls = args[ARG_CLASS].str; + uint32_t prio = args[ARG_PRIORITY].u32; + const char *play = args[ARG_PLAYBACK].str; + const char *rec = args[ARG_RECORDING].str; + const char *role = args[ARG_ROLE].str; + + if (!resctl_config(zone, cls, prio, play, rec, role)) { + mrp_log_error("Failed to configure telephony resource-set."); + + return FALSE; + } if (ctx != NULL) { /* use the mainloop from the plugin context */ @@ -61,8 +83,6 @@ static void telephony_exit(mrp_plugin_t *plugin) { MRP_UNUSED(plugin); - mrp_log_info("%s() called...", __FUNCTION__); - tel_exit_listeners(); } @@ -77,11 +97,27 @@ static void telephony_exit(mrp_plugin_t *plugin) "The telephony plugin follows ofono DBUS activity" \ "and updates Murphy database with telephony calls information" -MRP_REGISTER_CORE_PLUGIN("telephony", \ - TELEPHONY_VERSION, TELEPHONY_DESCRIPTION, \ - TELEPHONY_AUTHORS, TELEPHONY_HELP, MRP_SINGLETON, \ - telephony_init, telephony_exit, - NULL, 0, /* args */ - NULL, 0, /* exports */ - NULL, 0, /* imports */ - NULL /* commands */ ); +#define DEFAULT_ZONE "driver" +#define DEFAULT_CLASS "phone" +#define DEFAULT_PRIORITY 1 +#define DEFAULT_PLAYBACK "audio_playback,mandatory,shared" +#define DEFAULT_RECORDING "audio_recording,mandatory,exclusive" +#define DEFAULT_ROLE "phone" + +static mrp_plugin_arg_t telephony_args[] = { + MRP_PLUGIN_ARGIDX(ARG_ZONE , STRING, "zone" , DEFAULT_ZONE), + MRP_PLUGIN_ARGIDX(ARG_CLASS , STRING, "class" , DEFAULT_CLASS), + MRP_PLUGIN_ARGIDX(ARG_PRIORITY , UINT32, "priority" , DEFAULT_PRIORITY), + MRP_PLUGIN_ARGIDX(ARG_PLAYBACK , STRING, "playback" , DEFAULT_PLAYBACK), + MRP_PLUGIN_ARGIDX(ARG_RECORDING, STRING, "recording", DEFAULT_RECORDING), + MRP_PLUGIN_ARGIDX(ARG_ROLE , STRING, "role" , DEFAULT_ROLE), +}; + +MRP_REGISTER_CORE_PLUGIN("telephony", + TELEPHONY_VERSION, TELEPHONY_DESCRIPTION, + TELEPHONY_AUTHORS, TELEPHONY_HELP, MRP_SINGLETON, + telephony_init, telephony_exit, + telephony_args, MRP_ARRAY_SIZE(telephony_args), + NULL, 0, /* exports */ + NULL, 0, /* imports */ + NULL /* commands */ ); diff --git a/src/plugins/telephony/resctl.c b/src/plugins/telephony/resctl.c index d00e7c6..327f78d 100644 --- a/src/plugins/telephony/resctl.c +++ b/src/plugins/telephony/resctl.c @@ -17,18 +17,161 @@ struct resctl_s { static void event_cb(uint32_t reqid, mrp_resource_set_t *rset, void *user_data); + +typedef struct { + char *zone; + char *cls; + uint32_t prio; + char *play; + int pmnd; + int pshr; + char *rec; + int rmnd; + int rshr; + char *role; +} config_t; + + +static config_t cfg; + +#define EXCLUSIVE "exclusive" +#define SHARED "shared" +#define MANDATORY "mandatory" +#define OPTIONAL "optional" +#define EXCLEN (sizeof(EXCLUSIVE) - 1) +#define SHRLEN (sizeof(SHARED) - 1) +#define MNDLEN (sizeof(MANDATORY) - 1) +#define OPTLEN (sizeof(OPTIONAL) - 1) + +#define PLAYBACK "playback" +#define RECORDING "recording" + +static int parse_resource(const char *key, const char *value) +{ + const char *p, *e; + char **resp; + int *mndp, *shrp, l; + + if (!strcmp(key, PLAYBACK)) { + resp = &cfg.play; + mndp = &cfg.pmnd; + shrp = &cfg.pshr; + } + else if (!strcmp(key, RECORDING)) { + resp = &cfg.rec; + mndp = &cfg.rmnd; + shrp = &cfg.rshr; + } + else + return FALSE; + + mrp_free(*resp); + *resp = NULL; + *mndp = 1; + *shrp = 0; + + p = value; + while (p) { + while (*p && (*p == ' ' || *p == '\t' || *p == ',')) + p++; + + e = strchr(p, ','); + + if (e != NULL) + l = e - p; + else + l = strlen(p); + + if (l == SHRLEN && !strncmp(p, SHARED , l)) *shrp = 1; + else if (l == EXCLEN && !strncmp(p, EXCLUSIVE, l)) *shrp = 0; + else if (l == OPTLEN && !strncmp(p, OPTIONAL , l)) *mndp = 0; + else if (l == MNDLEN && !strncmp(p, MANDATORY, l)) *mndp = 1; + else { + if (*resp != NULL || (*resp = mrp_datadup((void *)p, l+1)) == NULL) + return FALSE; + + (*resp)[l] = '\0'; + } + + p = e && *e ? e + 1 : NULL; + } + + if (*resp != NULL) + return TRUE; + else + return FALSE; +} + + +int resctl_config(const char *zone, const char *cls, uint32_t priority, + const char *playback, const char *recording, const char *role) +{ + mrp_free(cfg.zone); + mrp_free(cfg.cls); + mrp_free(cfg.play); + mrp_free(cfg.rec); + mrp_free(cfg.role); + mrp_clear(&cfg); + + if (!(cfg.zone = mrp_strdup(zone)) || + !(cfg.cls = mrp_strdup(cls)) || + !(cfg.role = mrp_strdup(role))) + goto fail; + + if (!parse_resource(PLAYBACK , playback) || + !parse_resource(RECORDING, recording)) + goto fail; + + cfg.prio = priority; + + mrp_log_info("Telephony resource-set configuration:"); + mrp_log_info(" zone: %s, class: %s, priority: %u", cfg.zone, cfg.cls, + cfg.prio); + mrp_log_info(" playback: %s %s %s%s%s", + cfg.pmnd ? "mandatory" : "optional", + cfg.pshr ? "shared" : "exclusive", + cfg.play, + cfg.role && *cfg.role ? " role:s:" : "", + cfg.role && *cfg.role ? cfg.role : ""); + mrp_log_info(" recording: %s %s %s%s%s", + cfg.rmnd ? "mandatory" : "optional", + cfg.rshr ? "shared" : "exclusive", + cfg.rec, + cfg.role && *cfg.role ? " role:s:" : "", + cfg.role && *cfg.role ? cfg.role : ""); + + return TRUE; + + fail: + mrp_free(cfg.zone); + mrp_free(cfg.cls); + mrp_free(cfg.play); + mrp_free(cfg.rec); + mrp_free(cfg.role); + mrp_clear(&cfg); + + return FALSE; +} + + resctl_t *resctl_init(void) { + const char *zone = cfg.zone; + const char *cls = cfg.cls; + uint32_t prio = cfg.prio; + const char *play = cfg.play; + bool pshr = !!cfg.pshr; + bool pmnd = !!cfg.pmnd; + const char *rec = cfg.rec; + bool rshr = !!cfg.rshr; + bool rmnd = !!cfg.rmnd; + const char *role = cfg.role && *cfg.role ? cfg.role : NULL; + bool ar = false; + bool nowait = false; resctl_t *ctl; mrp_resource_client_t *client; mrp_resource_set_t *set; - const char *zone = "driver"; - const char *play = "audio_playback"; - const char *rec = "audio_recording"; - const char *cls = "phone"; - bool ar = false; - bool nowait = false; - uint32_t prio = 1; /* what is this ? */ + mrp_attr_t attrs[3], *attrp; ctl = NULL; client = NULL; @@ -55,8 +198,23 @@ resctl_t *resctl_init(void) goto fail; } - if (mrp_resource_set_add_resource(set, play, false, NULL, true) < 0 || - mrp_resource_set_add_resource(set, rec , false, NULL, true) < 0) { + attrs[0].name = "policy"; + attrs[0].type = mqi_string; + attrs[0].value.string = "relaxed"; + + if (role != NULL) { + attrs[1].type = mqi_string; + attrs[1].name = "role"; + attrs[1].value.string = role; + attrs[2].name = NULL; + } + else + attrs[1].name = NULL; + + attrp = &attrs[0]; + + if (mrp_resource_set_add_resource(set, play, pshr, attrp, pmnd) < 0 || + mrp_resource_set_add_resource(set, rec , rshr, attrp, rmnd) < 0) { mrp_log_error("Failed to initialize telephony resource set."); goto fail; } @@ -96,6 +254,13 @@ void resctl_exit(resctl_t *ctl) mrp_free(ctl); } + + mrp_free(cfg.zone); + mrp_free(cfg.cls); + mrp_free(cfg.play); + mrp_free(cfg.rec); + mrp_free(cfg.role); + mrp_clear(&cfg); } diff --git a/src/plugins/telephony/resctl.h b/src/plugins/telephony/resctl.h index a29b577..bdf0da9 100644 --- a/src/plugins/telephony/resctl.h +++ b/src/plugins/telephony/resctl.h @@ -4,6 +4,10 @@ struct resctl_s; typedef struct resctl_s resctl_t; +int resctl_config(const char *zone, const char *cls, uint32_t priority, + const char *playback, const char *recording, + const char *role); + resctl_t *resctl_init(void); void resctl_exit(resctl_t *ctl); -- 2.7.4