telephony: plugin arguments for resource set configuration
authorKrisztian Litkey <kli@iki.fi>
Sat, 14 Sep 2013 11:11:32 +0000 (14:11 +0300)
committerKrisztian Litkey <krisztian.litkey@intel.com>
Thu, 8 Jan 2015 16:37:10 +0000 (18:37 +0200)
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
src/plugins/telephony/resctl.c
src/plugins/telephony/resctl.h

index 83cd82d..691c3fb 100644 (file)
 
 #include <murphy/common.h>
 #include <murphy/core.h>
-#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 */ );
index d00e7c6..327f78d 100644 (file)
@@ -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);
 }
 
 
index a29b577..bdf0da9 100644 (file)
@@ -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);