changes for bt port and profile discovery 29/8329/1
authorJaska Uimonen <jaska.uimonen@helsinki.fi>
Tue, 13 Aug 2013 10:38:05 +0000 (13:38 +0300)
committerJaska Uimonen <jaska.uimonen@helsinki.fi>
Fri, 16 Aug 2013 06:19:02 +0000 (09:19 +0300)
murphy/classify.c
murphy/discover.c
murphy/utils.c
murphy/utils.h

index 877f7ba..8cca9c5 100644 (file)
@@ -109,6 +109,23 @@ void pa_classify_node_by_card(mir_node        *node,
                 node->type = mir_microphone;
             }
         }
+        else if (!strcasecmp(form, "phone")) {
+            if (bus && !strcasecmp(bus,"bluetooth") && prof) {
+                if (!strcmp(prof->name, "a2dp"))
+                    node->type = mir_bluetooth_a2dp;
+                else if (!strcmp(prof->name, "hsp"))
+                    node->type = mir_bluetooth_sco;
+                else if (!strcmp(prof->name, "hfgw"))
+                    node->type = mir_bluetooth_carkit;
+                else if (!strcmp(prof->name, "a2dp_source"))
+                    node->type = mir_bluetooth_source;
+                else if (!strcmp(prof->name, "a2dp_sink"))
+                    node->type = mir_bluetooth_sink;
+
+                if (node->type != mir_node_type_unknown)
+                    node->location = mir_external;
+            }
+        }
     }
     else {
         if (port && !strcasecmp(bus, "pci")) {
index 6d210b9..e38d351 100644 (file)
@@ -119,7 +119,7 @@ static pa_source *make_input_prerouting(struct userdata *, mir_node *,
 
 static mir_node_type get_stream_routing_class(pa_proplist *);
 
-static void set_bluetooth_profile(struct userdata *, mir_node *);
+static void set_bluetooth_profile(struct userdata *, pa_card *, pa_direction_t);
 
 
 static void schedule_deferred_routing(struct userdata *);
@@ -355,14 +355,17 @@ void pa_discover_profile_changed(struct userdata *u, pa_card *card)
 void pa_discover_port_available_changed(struct userdata *u,
                                         pa_device_port  *port)
 {
-    pa_core    *core;
-    pa_sink    *sink;
-    pa_source  *source;
-    mir_node   *node;
-    uint32_t    idx;
-    pa_bool_t   available;
-    const char *state;
-    pa_bool_t   route;
+    pa_core       *core;
+    pa_sink       *sink;
+    pa_source     *source;
+    mir_node      *node;
+    uint32_t       idx;
+    pa_bool_t      available;
+    const char    *state;
+    pa_bool_t      btport;
+    pa_bool_t      route;
+    pa_direction_t direction;
+    void          *iter;
 
     pa_assert(u);
     pa_assert(port);
@@ -377,13 +380,20 @@ void pa_discover_port_available_changed(struct userdata *u,
     pa_log_debug("port '%s' availabilty changed to %s. Updating",
                  port->name, state);
 
+    btport = FALSE;
     route = FALSE;
+    direction = 0;
+    iter = NULL;
 
-    if ((node = pa_utils_get_node_from_port(u, port))) {
+    while ((node = pa_utils_get_node_from_port(u, port, &iter))) {
+        btport = TRUE;
         available = get_bluetooth_port_availability(node, port);
         route |= update_node_availability(u, node, available);
-        set_bluetooth_profile(u, node);
+        direction |= (node->direction == mir_input) ? PA_DIRECTION_INPUT : PA_DIRECTION_OUTPUT;
     }
+
+    if (btport)
+        set_bluetooth_profile(u, port->card, direction);
     else {
         switch (port->available) {
         case PA_PORT_AVAILABLE_NO:    available = FALSE;    break;
@@ -1671,7 +1681,7 @@ static void handle_bluetooth_card(struct userdata *u, pa_card *card)
                     data.amname = amname;
                     amname[0] = '\0';
                     snprintf(paname, sizeof(paname), "bluez_sink.%s", cid);
-                    snprintf(key, sizeof(key), "%s@%s", paname, port->name);
+                    snprintf(key, sizeof(key), "%s@%s.%s", paname, port->name, prof->name);
                     pa_classify_node_by_card(&data, card, prof, NULL);
                     node = create_node(u, &data, NULL);
                     mir_constrain_add_node(u, cd, node);
@@ -1684,7 +1694,7 @@ static void handle_bluetooth_card(struct userdata *u, pa_card *card)
                     data.amname = amname;
                     amname[0] = '\0';
                     snprintf(paname, sizeof(paname), "bluez_source.%s", cid);
-                    snprintf(key, sizeof(key), "%s@%s", paname, port->name);
+                    snprintf(key, sizeof(key), "%s@%s.%s", paname, port->name, prof->name);
                     pa_classify_node_by_card(&data, card, prof, NULL);
                     node = create_node(u, &data, NULL);
                     mir_constrain_add_node(u, cd, node);
@@ -1717,7 +1727,7 @@ static pa_bool_t get_bluetooth_port_availability(mir_node *node,
         if (!strcmp(prof, "hfgw")        ||
             !strcmp(prof, "a2dp_source") ||
             !strcmp(prof, "a2dp_sink"))
-            available = (port->available == PA_PORT_AVAILABLE_YES);
+            available = (port->available != PA_PORT_AVAILABLE_NO);
         else
             available = TRUE;
     }
@@ -2137,7 +2147,7 @@ static char *node_key(struct userdata *u, mir_direction direction,
             key = NULL;
         else {
             key = buf;
-            snprintf(buf, len, "%s@%s", name, port->name);
+            snprintf(buf, len, "%s@%s.%s", name, port->name, profile_name);
         }
     }
     else {
@@ -2243,22 +2253,21 @@ static mir_node_type get_stream_routing_class(pa_proplist *pl)
 }
 
 
-static void set_bluetooth_profile(struct userdata *u, mir_node *node)
+static void set_bluetooth_profile(struct userdata *u,
+                                  pa_card *card,
+                                  pa_direction_t direction)
 {
     pa_core *core;
-    pa_card *card;
     pa_device_port *port;
     pa_card_profile *prof, *make_active;
     void *state0, *state1;
-    pa_bool_t available;
+    pa_bool_t port_available;
     pa_bool_t switch_off;
     int nport;
 
     pa_assert(u);
-    pa_assert(node);
+    pa_assert(card);
     pa_assert_se((core = u->core));
-    pa_assert_se((card = pa_idxset_get_by_index(core->cards,
-                                                node->pacard.index)));
 
     make_active = NULL;
     switch_off = FALSE;
@@ -2275,23 +2284,26 @@ static void set_bluetooth_profile(struct userdata *u, mir_node *node)
             }
         }
         else {
-            available = FALSE;
+            port_available = FALSE;
 
             PA_HASHMAP_FOREACH(port, card->ports, state1) {
-                if (prof == pa_hashmap_first(port->profiles)) {
-                    available = (port->available == PA_PORT_AVAILABLE_YES);
+                if ((direction & port->direction) &&
+                    pa_hashmap_get(port->profiles, prof->name))
+                {
+                    port_available = (port->available != PA_PORT_AVAILABLE_NO);
                     break;
                 }
             }
 
-            if (!available) {
-                pa_log_debug("   ruling out %s (not available)", prof->name);
-            }
+            if (!port_available)
+                pa_log_debug("   ruling out %s (port not available)", prof->name);
+            else if (prof->available != PA_AVAILABLE_YES)
+                pa_log_debug("   ruling out %s (profile not available)", prof->name);
             else {
                 nport++;
 
-                if ((node->direction == mir_input  && prof->n_sources > 0) ||
-                    (node->direction == mir_output && prof->n_sinks   > 0)   ) {
+                if (((direction & PA_DIRECTION_INPUT)  && prof->n_sources > 0) ||
+                    ((direction & PA_DIRECTION_OUTPUT) && prof->n_sinks   > 0)   ) {
                     if (make_active && prof->priority < make_active->priority)
                         pa_log_debug("   ruling out %s (low priority)", prof->name);
                     else {
index 4a57588..e1c6751 100644 (file)
@@ -403,20 +403,26 @@ static pa_bool_t get_unsigned_property(pa_proplist *pl,
 
 void pa_utils_set_port_properties(pa_device_port *port, mir_node *node)
 {
+    const char *profile;
+    char propnam[512];
     char nodeidx[256];
 
     pa_assert(port);
     pa_assert(port->proplist);
     pa_assert(node);
+    pa_assert_se((profile = node->pacard.profile));
 
+    snprintf(propnam, sizeof(propnam), "%s.%s", PA_PROP_NODE_INDEX, profile);
     snprintf(nodeidx, sizeof(nodeidx), "%u", node->index);
 
-    pa_proplist_sets(port->proplist, PA_PROP_NODE_INDEX, nodeidx);
+    pa_proplist_sets(port->proplist, propnam, nodeidx);
 }
 
 mir_node *pa_utils_get_node_from_port(struct userdata *u,
-                                      pa_device_port *port)
+                                      pa_device_port *port,
+                                      void **state)
 {
+    const char *name;
     const char *value;
     char *e;
     uint32_t index = PA_IDXSET_INVALID;
@@ -426,14 +432,24 @@ mir_node *pa_utils_get_node_from_port(struct userdata *u,
     pa_assert(port);
     pa_assert(port->proplist);
 
-    if ((value = pa_proplist_gets(port->proplist, PA_PROP_NODE_INDEX))) {
-        index = strtoul(value, &e, 10);
+    while ((name = pa_proplist_iterate(port->proplist, state))) {
+        if (!strncmp(name, PA_PROP_NODE_INDEX, sizeof(PA_PROP_NODE_INDEX)-1)) {
+            if ((value = pa_proplist_gets(port->proplist, name))) {
+                index = strtoul(value, &e, 10);
+                node = NULL;
 
-        if (value[0] && !e[0])
-            node = mir_node_find_by_index(u, index);
+                if (value[0] && !e[0])
+                    node = mir_node_find_by_index(u, index);
+                
+                if (node)
+                    return node;
+
+                pa_log("Can't find node %u for port %s", index, port->name);
+            }
+        }
     }
 
-    return node;
+    return NULL;
 }
 
 mir_node *pa_utils_get_node_from_stream(struct userdata *u,
index 87b076a..f64fe06 100644 (file)
@@ -55,7 +55,7 @@ pa_nodeset_resdef *pa_utils_get_resource_properties(pa_proplist *,
                                                     pa_nodeset_resdef *);
 
 void      pa_utils_set_port_properties(pa_device_port *, mir_node *);
-mir_node *pa_utils_get_node_from_port(struct userdata *, pa_device_port *);
+mir_node *pa_utils_get_node_from_port(struct userdata *, pa_device_port *, void **);
 mir_node *pa_utils_get_node_from_stream(struct userdata *,mir_direction,void*);
 mir_node *pa_utils_get_node_from_data(struct userdata *, mir_direction,void *);
 #endif