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")) {
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 *);
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);
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;
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);
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);
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;
}
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 {
}
-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;
}
}
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 {
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;
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,