diff --git a/spa/plugins/bluez5/backend-native.c b/spa/plugins/bluez5/backend-native.c
index 24794cf82..57d048a07 100644
--- a/spa/plugins/bluez5/backend-native.c
+++ b/spa/plugins/bluez5/backend-native.c
@@ -212,14 +212,25 @@ static void transport_destroy(void *data)
rfcomm->transport = NULL;
}
+static void transport_state_changed (void *data, enum spa_bt_transport_state old,
+ enum spa_bt_transport_state state)
+{
+ struct rfcomm *rfcomm = data;
+ if (rfcomm->telephony_ag) {
+ rfcomm->telephony_ag->transport.state = state;
+ telephony_ag_transport_notify_updated_props(rfcomm->telephony_ag);
+ }
+}
+
static const struct spa_bt_transport_events transport_events = {
SPA_VERSION_BT_TRANSPORT_EVENTS,
.destroy = transport_destroy,
+ .state_changed = transport_state_changed,
};
static const struct spa_bt_transport_implementation sco_transport_impl;
-static int rfcomm_new_transport(struct rfcomm *rfcomm)
+static int rfcomm_new_transport(struct rfcomm *rfcomm, int codec)
{
struct impl *backend = rfcomm->backend;
struct spa_bt_transport *t = NULL;
@@ -248,7 +259,7 @@ static int rfcomm_new_transport(struct rfcomm *rfcomm)
t->backend = &backend->this;
t->n_channels = 1;
t->channels[0] = SPA_AUDIO_CHANNEL_MONO;
- t->codec = HFP_AUDIO_CODEC_CVSD;
+ t->codec = codec;
td = t->user_data;
td->rfcomm = rfcomm;
@@ -271,6 +282,12 @@ static int rfcomm_new_transport(struct rfcomm *rfcomm)
spa_bt_transport_add_listener(t, &rfcomm->transport_listener, &transport_events, rfcomm);
+ if (rfcomm->telephony_ag) {
+ rfcomm->telephony_ag->transport.codec = codec;
+ rfcomm->telephony_ag->transport.state = SPA_BT_TRANSPORT_STATE_IDLE;
+ telephony_ag_transport_notify_updated_props(rfcomm->telephony_ag);
+ }
+
rfcomm->transport = t;
return 0;
@@ -939,10 +956,9 @@ static bool rfcomm_hfp_ag(struct rfcomm *rfcomm, char* buf)
rfcomm_send_reply(rfcomm, "+BCS: 2");
codec_switch_start_timer(rfcomm, HFP_CODEC_SWITCH_INITIAL_TIMEOUT_MSEC);
} else {
- if (rfcomm_new_transport(rfcomm) < 0) {
+ if (rfcomm_new_transport(rfcomm, HFP_AUDIO_CODEC_CVSD) < 0) {
// TODO: We should manage the missing transport
} else {
- rfcomm->transport->codec = HFP_AUDIO_CODEC_CVSD;
spa_bt_device_connect_profile(rfcomm->device, rfcomm->profile);
rfcomm_emit_volume_changed(rfcomm, -1, SPA_BT_VOLUME_INVALID);
}
@@ -981,14 +997,13 @@ static bool rfcomm_hfp_ag(struct rfcomm *rfcomm, char* buf)
spa_log_debug(backend->log, "RFCOMM selected_codec = %i", selected_codec);
/* Recreate transport, since previous connection may now be invalid */
- if (rfcomm_new_transport(rfcomm) < 0) {
+ if (rfcomm_new_transport(rfcomm, selected_codec) < 0) {
// TODO: We should manage the missing transport
rfcomm_send_error(rfcomm, CMEE_AG_FAILURE);
if (was_switching_codec)
spa_bt_device_emit_codec_switched(rfcomm->device, -ENOMEM);
return true;
}
- rfcomm->transport->codec = selected_codec;
spa_bt_device_connect_profile(rfcomm->device, rfcomm->profile);
rfcomm_emit_volume_changed(rfcomm, -1, SPA_BT_VOLUME_INVALID);
@@ -1745,10 +1760,9 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
rfcomm->hf_state = hfp_hf_bcs;
if (!rfcomm->transport || (rfcomm->transport->codec != selected_codec) ) {
- if (rfcomm_new_transport(rfcomm) < 0) {
+ if (rfcomm_new_transport(rfcomm, selected_codec) < 0) {
// TODO: We should manage the missing transport
} else {
- rfcomm->transport->codec = selected_codec;
spa_bt_device_connect_profile(rfcomm->device, rfcomm->profile);
}
}
@@ -2116,10 +2130,9 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
rfcomm->slc_configured = true;
if (!rfcomm->codec_negotiation_supported) {
- if (rfcomm_new_transport(rfcomm) < 0) {
+ if (rfcomm_new_transport(rfcomm, HFP_AUDIO_CODEC_CVSD) < 0) {
// TODO: We should manage the missing transport
} else {
- rfcomm->transport->codec = HFP_AUDIO_CODEC_CVSD;
spa_bt_device_connect_profile(rfcomm->device, rfcomm->profile);
}
}
@@ -2127,6 +2140,10 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
rfcomm->telephony_ag = telephony_ag_new(backend->telephony, sizeof(struct spa_hook));
telephony_ag_add_listener(rfcomm->telephony_ag, telephony_ag_get_user_data(rfcomm->telephony_ag),
&telephony_ag_events, rfcomm);
+ if (rfcomm->transport) {
+ rfcomm->telephony_ag->transport.codec = rfcomm->transport->codec;
+ rfcomm->telephony_ag->transport.state = rfcomm->transport->state;
+ }
telephony_ag_register(rfcomm->telephony_ag);
/* Report volume on SLC establishment */
@@ -2909,8 +2926,7 @@ static void codec_switch_timer_event(struct spa_source *source)
/* Failure, try falling back to CVSD. */
rfcomm->hfp_ag_initial_codec_setup = HFP_AG_INITIAL_CODEC_SETUP_NONE;
if (rfcomm->transport == NULL) {
- if (rfcomm_new_transport(rfcomm) == 0) {
- rfcomm->transport->codec = HFP_AUDIO_CODEC_CVSD;
+ if (rfcomm_new_transport(rfcomm, HFP_AUDIO_CODEC_CVSD) == 0) {
spa_bt_device_connect_profile(rfcomm->device, rfcomm->profile);
}
}
@@ -3085,10 +3101,9 @@ static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessag
spa_list_append(&backend->rfcomm_list, &rfcomm->link);
if (profile == SPA_BT_PROFILE_HSP_HS || profile == SPA_BT_PROFILE_HSP_AG) {
- if (rfcomm_new_transport(rfcomm) < 0)
+ if (rfcomm_new_transport(rfcomm, HFP_AUDIO_CODEC_CVSD) < 0)
goto fail_need_memory;
- rfcomm->transport->codec = HFP_AUDIO_CODEC_CVSD;
rfcomm->has_volume = rfcomm_volume_enabled(rfcomm);
if (profile == SPA_BT_PROFILE_HSP_AG) {
diff --git a/spa/plugins/bluez5/telephony.c b/spa/plugins/bluez5/telephony.c
index 348a70c0a..2e88e866a 100644
--- a/spa/plugins/bluez5/telephony.c
+++ b/spa/plugins/bluez5/telephony.c
@@ -18,6 +18,7 @@
#define PW_TELEPHONY_OBJECT_PATH "/org/freedesktop/PipeWire/Telephony"
#define PW_TELEPHONY_AG_IFACE "org.freedesktop.PipeWire.Telephony.AudioGateway1"
+#define PW_TELEPHONY_AG_TRANSPORT_IFACE "org.freedesktop.PipeWire.Telephony.AudioGatewayTransport1"
#define PW_TELEPHONY_CALL_IFACE "org.freedesktop.PipeWire.Telephony.Call1"
#define OFONO_MANAGER_IFACE "org.ofono.Manager"
@@ -114,6 +115,10 @@
" " \
PW_TELEPHONY_AG_COMMON_INTROSPECT_XML \
" " \
+ " " \
+ " " \
+ " " \
+ " " \
" " \
PW_TELEPHONY_AG_COMMON_INTROSPECT_XML \
" " \
@@ -128,6 +133,7 @@
" " \
" " \
DBUS_OBJECT_MANAGER_IFACE_INTROSPECT_XML \
+ DBUS_PROPERTIES_IFACE_INTROSPECT_XML \
DBUS_INTROSPECTABLE_IFACE_INTROSPECT_XML \
""
@@ -190,6 +196,10 @@ struct agimpl {
bool dial_in_progress;
struct callimpl *dial_return;
+
+ struct {
+ struct spa_bt_telephony_ag_transport transport;
+ } prev;
};
struct callimpl {
@@ -222,6 +232,7 @@ struct callimpl {
#define call_emit_answer(s,e) call_emit(s,answer,0,e)
#define call_emit_hangup(s,e) call_emit(s,hangup,0,e)
+static void dbus_iter_append_ag_interfaces(DBusMessageIter *i, struct spa_bt_telephony_ag *ag);
static void dbus_iter_append_call_properties(DBusMessageIter *i, struct spa_bt_telephony_call *call, bool all);
#define PW_TELEPHONY_ERROR_FAILED "org.freedesktop.PipeWire.Telephony.Error.Failed"
@@ -292,8 +303,7 @@ static DBusMessage *manager_get_managed_objects(struct impl *impl, DBusMessage *
{
struct agimpl *agimpl;
spa_autoptr(DBusMessage) r = NULL;
- DBusMessageIter iter, array1, entry1, array2, entry2, props_dict;
- const char *interface = PW_TELEPHONY_AG_IFACE;
+ DBusMessageIter iter, array1, entry1, props_dict;
if ((r = dbus_message_new_method_return(m)) == NULL)
return NULL;
@@ -305,18 +315,12 @@ static DBusMessage *manager_get_managed_objects(struct impl *impl, DBusMessage *
spa_list_for_each (agimpl, &impl->ag_list, link) {
if (agimpl->path) {
dbus_message_iter_open_container(&array1, DBUS_TYPE_DICT_ENTRY, NULL, &entry1);
- dbus_message_iter_append_basic(&entry1, DBUS_TYPE_OBJECT_PATH, &agimpl->path);
if (ofono_compat) {
+ dbus_message_iter_append_basic(&entry1, DBUS_TYPE_OBJECT_PATH, &agimpl->path);
dbus_message_iter_open_container(&entry1, DBUS_TYPE_ARRAY, "{sv}", &props_dict);
dbus_message_iter_close_container(&entry1, &props_dict);
} else {
- dbus_message_iter_open_container(&entry1, DBUS_TYPE_ARRAY, "{sa{sv}}", &array2);
- dbus_message_iter_open_container(&array2, DBUS_TYPE_DICT_ENTRY, NULL, &entry2);
- dbus_message_iter_append_basic(&entry2, DBUS_TYPE_STRING, &interface);
- dbus_message_iter_open_container(&entry2, DBUS_TYPE_ARRAY, "{sv}", &props_dict);
- dbus_message_iter_close_container(&entry2, &props_dict);
- dbus_message_iter_close_container(&array2, &entry2);
- dbus_message_iter_close_container(&entry1, &array2);
+ dbus_iter_append_ag_interfaces(&entry1, &agimpl->this);
}
dbus_message_iter_close_container(&array1, &entry1);
}
@@ -466,6 +470,90 @@ void telephony_free(struct spa_bt_telephony *telephony)
free(impl);
}
+static void telephony_ag_transport_commit_properties(struct spa_bt_telephony_ag *ag)
+{
+ struct agimpl *agimpl = SPA_CONTAINER_OF(ag, struct agimpl, this);
+ agimpl->prev.transport = ag->transport;
+}
+
+static const char * const * transport_state_to_string(int state)
+{
+ static const char * const state_str[] = {
+ "error",
+ "idle",
+ "pending",
+ "active",
+ };
+ if (state < -1 || state > 2)
+ state = -1;
+ return &state_str[state + 1];
+}
+
+static bool
+dbus_iter_append_ag_transport_properties(DBusMessageIter *i, struct spa_bt_telephony_ag *ag, bool all)
+{
+ struct agimpl *agimpl = SPA_CONTAINER_OF(ag, struct agimpl, this);
+ DBusMessageIter dict, entry, variant;
+ bool changed = false;
+
+ dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "{sv}", &dict);
+
+ if (all || ag->transport.codec != agimpl->prev.transport.codec) {
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+ const char *name = "Codec";
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &name);
+ dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_BYTE_AS_STRING,
+ &variant);
+ dbus_message_iter_append_basic(&variant, DBUS_TYPE_BYTE, &ag->transport.codec);
+ dbus_message_iter_close_container(&entry, &variant);
+ dbus_message_iter_close_container(&dict, &entry);
+ changed = true;
+ }
+
+ if (all || ag->transport.state != agimpl->prev.transport.state) {
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+ const char *name = "State";
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &name);
+ dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_STRING_AS_STRING,
+ &variant);
+ dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING,
+ transport_state_to_string(ag->transport.state));
+ dbus_message_iter_close_container(&entry, &variant);
+ dbus_message_iter_close_container(&dict, &entry);
+ changed = true;
+ }
+
+ dbus_message_iter_close_container(i, &dict);
+ return changed;
+}
+
+static void
+dbus_iter_append_ag_interfaces(DBusMessageIter *i, struct spa_bt_telephony_ag *ag)
+{
+ struct agimpl *agimpl = SPA_CONTAINER_OF(ag, struct agimpl, this);
+ DBusMessageIter entry, dict, props_dict;
+
+ dbus_message_iter_append_basic(i, DBUS_TYPE_OBJECT_PATH, &agimpl->path);
+ dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "{sa{sv}}", &dict);
+
+ const char *interface = PW_TELEPHONY_AG_IFACE;
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &interface);
+ dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY, "{sv}", &props_dict);
+ dbus_message_iter_close_container(&entry, &props_dict);
+ dbus_message_iter_close_container(&dict, &entry);
+
+ const char *interface2 = PW_TELEPHONY_AG_TRANSPORT_IFACE;
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &interface2);
+ dbus_iter_append_ag_transport_properties(&entry, ag, true);
+ dbus_message_iter_close_container(&dict, &entry);
+
+ dbus_message_iter_close_container(i, &dict);
+}
+
static DBusMessage *ag_introspect(struct agimpl *agimpl, DBusMessage *m)
{
const char *xml = PW_TELEPHONY_AG_INTROSPECT_XML;
@@ -511,6 +599,80 @@ static DBusMessage *ag_get_managed_objects(struct agimpl *agimpl, DBusMessage *m
return spa_steal_ptr(r);
}
+static DBusMessage *ag_properties_get(struct agimpl *agimpl, DBusMessage *m)
+{
+ const char *iface, *name;
+ DBusMessage *r;
+ DBusMessageIter i, v;
+
+ if (!dbus_message_get_args(m, NULL,
+ DBUS_TYPE_STRING, &iface,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID))
+ return NULL;
+
+ if (spa_streq(iface, PW_TELEPHONY_AG_TRANSPORT_IFACE))
+ return dbus_message_new_error(m, DBUS_ERROR_UNKNOWN_INTERFACE,
+ "No such interface");
+
+ if (spa_streq(name, "Codec")) {
+ r = dbus_message_new_method_return(m);
+ if (r == NULL)
+ return NULL;
+ dbus_message_iter_init_append(r, &i);
+ dbus_message_iter_open_container(&i, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_BYTE_AS_STRING, &v);
+ dbus_message_iter_append_basic(&v, DBUS_TYPE_BYTE,
+ &agimpl->this.transport.codec);
+ dbus_message_iter_close_container(&i, &v);
+ return r;
+ } else if (spa_streq(name, "State")) {
+ r = dbus_message_new_method_return(m);
+ if (r == NULL)
+ return NULL;
+ dbus_message_iter_init_append(r, &i);
+ dbus_message_iter_open_container(&i, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_STRING_AS_STRING, &v);
+ dbus_message_iter_append_basic(&v, DBUS_TYPE_STRING,
+ transport_state_to_string(agimpl->this.transport.state));
+ dbus_message_iter_close_container(&i, &v);
+ return r;
+ }
+
+ return dbus_message_new_error(m, DBUS_ERROR_UNKNOWN_PROPERTY,
+ "No such property");
+}
+
+static DBusMessage *ag_properties_get_all(struct agimpl *agimpl, DBusMessage *m)
+{
+ DBusMessage *r;
+ DBusMessageIter i;
+ const char *iface;
+
+ if (!dbus_message_get_args(m, NULL,
+ DBUS_TYPE_STRING, &iface,
+ DBUS_TYPE_INVALID))
+ return NULL;
+
+ if (!spa_streq(iface, PW_TELEPHONY_AG_TRANSPORT_IFACE))
+ return dbus_message_new_error(m, DBUS_ERROR_UNKNOWN_INTERFACE,
+ "No such interface");
+
+ r = dbus_message_new_method_return(m);
+ if (r == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(r, &i);
+ dbus_iter_append_ag_transport_properties(&i, &agimpl->this, true);
+ return r;
+}
+
+static DBusMessage *ag_properties_set(struct agimpl *agimpl, DBusMessage *m)
+{
+ return dbus_message_new_error(m, DBUS_ERROR_PROPERTY_READ_ONLY,
+ "Property not writable");
+}
+
static bool validate_phone_number(const char *number)
{
const char *c;
@@ -693,6 +855,12 @@ static DBusHandlerResult ag_handler(DBusConnection *c, DBusMessage *m, void *use
r = ag_introspect(agimpl, m);
} else if (dbus_message_is_method_call(m, DBUS_INTERFACE_OBJECT_MANAGER, "GetManagedObjects")) {
r = ag_get_managed_objects(agimpl, m, false);
+ } else if (dbus_message_is_method_call(m, DBUS_INTERFACE_PROPERTIES, "Get")) {
+ r = ag_properties_get(agimpl, m);
+ } else if (dbus_message_is_method_call(m, DBUS_INTERFACE_PROPERTIES, "GetAll")) {
+ r = ag_properties_get_all(agimpl, m);
+ } else if (dbus_message_is_method_call(m, DBUS_INTERFACE_PROPERTIES, "Set")) {
+ r = ag_properties_set(agimpl, m);
} else if (dbus_message_is_method_call(m, PW_TELEPHONY_AG_IFACE, "Dial") ||
dbus_message_is_method_call(m, OFONO_VOICE_CALL_MANAGER_IFACE, "Dial")) {
r = ag_dial(agimpl, m);
@@ -799,20 +967,12 @@ int telephony_ag_register(struct spa_bt_telephony_ag *ag)
/* notify on ObjectManager of the Manager object */
{
spa_autoptr(DBusMessage) msg = NULL;
- DBusMessageIter iter, entry, dict, props_dict;
- const char *interface = PW_TELEPHONY_AG_IFACE;
+ DBusMessageIter iter;
msg = dbus_message_new_signal(impl->path, DBUS_INTERFACE_OBJECT_MANAGER,
"InterfacesAdded");
dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sa{sv}}", &dict);
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &interface);
- dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY, "{sv}", &props_dict);
- dbus_message_iter_close_container(&entry, &props_dict);
- dbus_message_iter_close_container(&dict, &entry);
- dbus_message_iter_close_container(&iter, &dict);
+ dbus_iter_append_ag_interfaces(&iter, ag);
if (!dbus_connection_send(impl->conn, msg, NULL)) {
spa_log_error(impl->log, "failed to send InterfacesAdded for %s", path);
@@ -859,6 +1019,7 @@ void telephony_ag_unregister(struct spa_bt_telephony_ag *ag)
spa_autoptr(DBusMessage) msg = NULL;
DBusMessageIter iter, entry;
const char *interface = PW_TELEPHONY_AG_IFACE;
+ const char *interface2 = PW_TELEPHONY_AG_TRANSPORT_IFACE;
msg = dbus_message_new_signal(impl->path, DBUS_INTERFACE_OBJECT_MANAGER,
"InterfacesRemoved");
@@ -867,6 +1028,7 @@ void telephony_ag_unregister(struct spa_bt_telephony_ag *ag)
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING_AS_STRING, &entry);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &interface);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &interface2);
dbus_message_iter_close_container(&iter, &entry);
if (!dbus_connection_send(impl->conn, msg, NULL)) {
@@ -895,6 +1057,37 @@ void telephony_ag_unregister(struct spa_bt_telephony_ag *ag)
agimpl->path = NULL;
}
+/* send message to notify about property changes */
+void telephony_ag_transport_notify_updated_props(struct spa_bt_telephony_ag *ag)
+{
+ struct agimpl *agimpl = SPA_CONTAINER_OF(ag, struct agimpl, this);
+ struct impl *impl = SPA_CONTAINER_OF(agimpl->this.telephony, struct impl, this);
+
+ spa_autoptr(DBusMessage) msg = NULL;
+ const char *interface = PW_TELEPHONY_AG_TRANSPORT_IFACE;
+ DBusMessageIter i, a;
+
+ msg = dbus_message_new_signal(agimpl->path,
+ DBUS_INTERFACE_PROPERTIES,
+ "PropertiesChanged");
+
+ dbus_message_iter_init_append(msg, &i);
+ dbus_message_iter_append_basic(&i, DBUS_TYPE_STRING, &interface);
+
+ if (!dbus_iter_append_ag_transport_properties(&i, ag, false))
+ return;
+
+ dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &a);
+ dbus_message_iter_close_container(&i, &a);
+
+ if (!dbus_connection_send(impl->conn, msg, NULL)){
+ spa_log_warn(impl->log, "sending PropertiesChanged failed");
+ }
+
+ telephony_ag_transport_commit_properties(ag);
+}
+
void telephony_ag_add_listener(struct spa_bt_telephony_ag *ag,
struct spa_hook *listener,
const struct spa_bt_telephony_ag_events *events,
diff --git a/spa/plugins/bluez5/telephony.h b/spa/plugins/bluez5/telephony.h
index dfbdc73d4..725fb663b 100644
--- a/spa/plugins/bluez5/telephony.h
+++ b/spa/plugins/bluez5/telephony.h
@@ -30,11 +30,19 @@ struct spa_bt_telephony {
};
+struct spa_bt_telephony_ag_transport {
+ int8_t codec;
+ enum spa_bt_transport_state state;
+};
+
struct spa_bt_telephony_ag {
struct spa_bt_telephony *telephony;
struct spa_list call_list;
int id;
+
+ /* D-Bus properties */
+ struct spa_bt_telephony_ag_transport transport;
};
struct spa_bt_telephony_call {
@@ -91,6 +99,8 @@ void telephony_ag_add_listener(struct spa_bt_telephony_ag *ag,
const struct spa_bt_telephony_ag_events *events,
void *data);
+void telephony_ag_transport_notify_updated_props(struct spa_bt_telephony_ag *ag);
+
/* register/unregister AudioGateway object on the bus */
int telephony_ag_register(struct spa_bt_telephony_ag *ag);
void telephony_ag_unregister(struct spa_bt_telephony_ag *ag);