All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v6 00/12] Add org.bluez.Telephony interface
@ 2012-08-01 10:09 =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 01/12] bluetooth: Add org.bluez.Telephony helpers =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 2036 bytes --]

Those patches integrates the future org.bluez.Telephony interface into
oFono for HFP HF, HFP AG and DUN GW plugins.

For HFP AG and DUN GW plugins, the bluetooth rfcomm server is replaced
by a Telephony Agent registered to org.bluez.Telephony.
For HFP HF plugin, RegisterAgent call of org.bluez.HandsfreeGateway is
replaced by the one of org.bluez.Telephony

Any comments appreciated.

Regards

PS: 
This version works with version 16 of "Add org.bluez.Telephony interface"
patches sent to BlueZ mailing list.

Since latest RFC :
- Patches 1, 2 and 3: remove UUID when parsing properties of NewConnection method
- Patch 3: update to use new GDBus
- Patches 7 to 10 (previously 5 to 8): move audio code from bluetooth.c to
  hfp_ag.c (dundee did not build if code is in bluetooth.c)
- Patch 9 (previously 7):
  - use right dbus_uint16_t variables when sending volume properties
  - changes volume management from MicrophoneGain to InputGain
- Patch 10 (previously 8):
  - use right dbus_uint16_t variables when sending volume properties
  - changes volume management from SpeakerGain to OutputGain

Frédéric Danis (12):
  bluetooth: Add org.bluez.Telephony helpers
  hfp_hf: Update to org.bluez.Telephony interface
  hfp_ag: Update to org.bluez.Telephony interface
  bluetooth: Add define for MediaTransport interface
  include: Add set/get data APIs to emulator
  emulator: Add set/get data APIs
  hfp_ag: Add AT+NREC support
  hfp_ag: Add +BSIR support
  hfp_ag: Add AT+VGM support
  hfp_ag: Add AT+VGS support
  emulator: Update supported features
  dun_gw: Update to org.bluez.Telephony interface

 include/emulator.h  |    5 +
 plugins/bluetooth.c |  191 +++++++++++++++++++++
 plugins/bluetooth.h |   14 ++
 plugins/dun_gw.c    |  119 ++++++-------
 plugins/hfp_ag.c    |  477 +++++++++++++++++++++++++++++++++++++++++++--------
 plugins/hfp_hf.c    |  169 +++++++-----------
 src/emulator.c      |   19 ++
 7 files changed, 754 insertions(+), 240 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [RFC v6 01/12] bluetooth: Add org.bluez.Telephony helpers
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 02/12] hfp_hf: Update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 8052 bytes --]

Add function to register/unregister Telephony agent to BlueZ
---
 plugins/bluetooth.c |  191 +++++++++++++++++++++++++++++++++++++++++++++++++++
 plugins/bluetooth.h |   13 ++++
 2 files changed, 204 insertions(+)

diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index 5d28530..3e8291a 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -44,6 +44,7 @@ static GHashTable *uuid_hash = NULL;
 static GHashTable *adapter_address_hash = NULL;
 static gint bluetooth_refcount;
 static GSList *server_list = NULL;
+static GSList *telephony_list = NULL;
 static const char *adapter_any_name = "any";
 static char *adapter_any_path;
 
@@ -65,6 +66,13 @@ struct cb_data {
 	GIOChannel *io;
 };
 
+struct agent {
+	char *path;
+	char *uuid;
+	guint16 version;
+	guint16 features;
+};
+
 void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
 				char *buf, int size)
 {
@@ -146,6 +154,60 @@ fail:
 	return err;
 }
 
+static void register_telephony_agent(const char *path, const char *handle,
+						struct agent *agent)
+{
+	DBusMessage *msg;
+	DBusMessageIter iter, dict;
+
+	DBG("Registering oFono Agent for %s to %s", agent->uuid, path);
+
+	msg = dbus_message_new_method_call(BLUEZ_SERVICE, path,
+				BLUEZ_TELEPHONY_INTERFACE, "RegisterAgent");
+	if (msg == NULL)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+							&agent->path);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+	ofono_dbus_dict_append(&dict, "UUID", DBUS_TYPE_STRING, &agent->uuid);
+
+	ofono_dbus_dict_append(&dict, "Version", DBUS_TYPE_UINT16,
+							&agent->version);
+	ofono_dbus_dict_append(&dict, "Features", DBUS_TYPE_UINT16,
+							&agent->features);
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	g_dbus_send_message(connection, msg);
+}
+
+static void unregister_telephony_agent(const char *path, const char *handle,
+						struct agent *agent)
+{
+	DBusMessage *msg;
+
+	DBG("Unregistering oFono Agent for %s from %s", agent->uuid, path);
+
+	msg = dbus_message_new_method_call(BLUEZ_SERVICE, path,
+					BLUEZ_TELEPHONY_INTERFACE,
+					"UnregisterAgent");
+	if (msg == NULL)
+		return;
+
+	dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent->path,
+					DBUS_TYPE_INVALID);
+
+	g_dbus_send_message(connection, msg);
+}
+
 typedef void (*PropertyHandler)(DBusMessageIter *iter, gpointer user_data);
 
 struct property_handler {
@@ -455,6 +517,9 @@ static void adapter_properties_cb(DBusPendingCall *call, gpointer user_data)
 					g_free, -1, DBUS_TYPE_INVALID);
 	}
 
+	for (l = telephony_list; l; l = l->next)
+		register_telephony_agent(path, NULL, l->data);
+
 done:
 	g_slist_free(device_list);
 	dbus_message_unref(reply);
@@ -985,5 +1050,131 @@ void bluetooth_unregister_server(struct server *server)
 	bluetooth_unref();
 }
 
+int bluetooth_parse_newconnection_message(DBusMessage *msg, const char **device,
+					guint16 *version, guint16 *features,
+					const char **transport_path)
+{
+	DBusMessageIter args, props;
+	int fd;
+	gboolean has_device = FALSE;
+
+	dbus_message_iter_init(msg, &args);
+
+	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_UNIX_FD)
+		return -EINVAL;
+
+	dbus_message_iter_get_basic(&args, &fd);
+	dbus_message_iter_next(&args);
+
+	dbus_message_iter_recurse(&args, &props);
+	if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
+		return -EINVAL;
+
+	while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) {
+		const char *key;
+		DBusMessageIter value, entry;
+		int var;
+
+		dbus_message_iter_recurse(&props, &entry);
+		dbus_message_iter_get_basic(&entry, &key);
+
+		dbus_message_iter_next(&entry);
+		dbus_message_iter_recurse(&entry, &value);
+
+		var = dbus_message_iter_get_arg_type(&value);
+		if (strcasecmp(key, "Device") == 0) {
+			if (var != DBUS_TYPE_OBJECT_PATH)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, device);
+			has_device = TRUE;
+		} else if (strcasecmp(key, "Version") == 0) {
+			if (var != DBUS_TYPE_UINT16)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, version);
+		} else if (strcasecmp(key, "Features") == 0) {
+			if (var != DBUS_TYPE_UINT16)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, features);
+		} else if (strcasecmp(key, "Transport") == 0) {
+			if (var != DBUS_TYPE_OBJECT_PATH)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, transport_path);
+		}
+
+		dbus_message_iter_next(&props);
+	}
+
+	return has_device ? fd : -EINVAL;
+}
+
+void bluetooth_register_telephony_agent(const char *path, const char *uuid,
+					guint16 version, guint16 features,
+					const GDBusMethodTable *methods,
+					void *user_data,
+					GDBusDestroyFunction destroy)
+{
+	GSList *l;
+	struct agent *agent;
+
+	for (l = telephony_list; l; l = l->next) {
+		agent = l->data;
+
+		if (g_strcmp0(path, agent->path) == 0) {
+			ofono_error("Telephony agent path \"%s\" already " \
+					"registered", path);
+			return;
+		}
+	}
+
+	agent = g_try_new0(struct agent, 1);
+	if (!agent)
+		return;
+
+	agent->path = g_strdup(path);
+	agent->uuid = g_strdup(uuid);
+	agent->version = version;
+	agent->features = features;
+
+	bluetooth_ref();
+
+	g_dbus_register_interface(connection, path,
+				BLUEZ_TELEPHONY_AGENT_INTERFACE, methods, NULL,
+				NULL, user_data, destroy);
+
+	telephony_list = g_slist_prepend(telephony_list, agent);
+
+	g_hash_table_foreach(adapter_address_hash,
+			(GHFunc) register_telephony_agent, agent);
+}
+
+void bluetooth_unregister_telephony_agent(const char *path)
+{
+	GSList *l;
+	struct agent *agent;
+
+	for (l = telephony_list; l; l = l->next) {
+		agent = l->data;
+
+		if (g_strcmp0(path, agent->path) == 0)
+			break;
+	}
+
+	if (l == NULL)
+		return;
+
+	g_hash_table_foreach(adapter_address_hash,
+			(GHFunc) unregister_telephony_agent, agent);
+
+	telephony_list = g_slist_remove(telephony_list, agent);
+	g_free(agent->path);
+	g_free(agent->uuid);
+	g_free(agent);
+
+	g_dbus_unregister_interface(connection, path,
+				BLUEZ_TELEPHONY_AGENT_INTERFACE);
+
+	bluetooth_unref();
+}
+
 OFONO_PLUGIN_DEFINE(bluetooth, "Bluetooth Utils Plugins", VERSION,
 			OFONO_PLUGIN_PRIORITY_DEFAULT, NULL, NULL)
diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h
index 4fc16ad..6a2fbf0 100644
--- a/plugins/bluetooth.h
+++ b/plugins/bluetooth.h
@@ -21,6 +21,7 @@
 
 #include <ofono/modem.h>
 #include <ofono/dbus.h>
+#include <gdbus.h>
 
 #define	BLUEZ_SERVICE "org.bluez"
 #define	BLUEZ_MANAGER_INTERFACE		BLUEZ_SERVICE ".Manager"
@@ -28,6 +29,8 @@
 #define	BLUEZ_DEVICE_INTERFACE		BLUEZ_SERVICE ".Device"
 #define	BLUEZ_SERVICE_INTERFACE		BLUEZ_SERVICE ".Service"
 #define BLUEZ_SERIAL_INTERFACE		BLUEZ_SERVICE ".Serial"
+#define	BLUEZ_TELEPHONY_INTERFACE	BLUEZ_SERVICE ".Telephony"
+#define	BLUEZ_TELEPHONY_AGENT_INTERFACE	BLUEZ_SERVICE ".TelephonyAgent"
 
 #define DBUS_TIMEOUT 15
 
@@ -82,3 +85,13 @@ void bluetooth_parse_properties(DBusMessage *reply, const char *property, ...);
 int bluetooth_sap_client_register(struct bluetooth_sap_driver *sap,
 					struct ofono_modem *modem);
 void bluetooth_sap_client_unregister(struct ofono_modem *modem);
+
+int bluetooth_parse_newconnection_message(DBusMessage *msg, const char **device,
+					guint16 *version, guint16 *features,
+					const char **transport_path);
+void bluetooth_register_telephony_agent(const char *path, const char *uuid,
+					guint16 version, guint16 features,
+					const GDBusMethodTable *methods,
+					void *user_data,
+					GDBusDestroyFunction destroy);
+void bluetooth_unregister_telephony_agent(const char *path);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 02/12] hfp_hf: Update to org.bluez.Telephony interface
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 01/12] bluetooth: Add org.bluez.Telephony helpers =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 03/12] hfp_ag: " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 7644 bytes --]

Bluez moves agent registration from a per device interface to
a per adapter interface.
Update hfp_hf modem to reflect this change.
---
 plugins/hfp_hf.c |  169 +++++++++++++++++++++---------------------------------
 1 file changed, 65 insertions(+), 104 deletions(-)

diff --git a/plugins/hfp_hf.c b/plugins/hfp_hf.c
index 7c500e3..e618518 100644
--- a/plugins/hfp_hf.c
+++ b/plugins/hfp_hf.c
@@ -51,7 +51,7 @@
 
 #define	BLUEZ_GATEWAY_INTERFACE		BLUEZ_SERVICE ".HandsfreeGateway"
 
-#define HFP_AGENT_INTERFACE "org.bluez.HandsfreeAgent"
+#define HFP_AGENT_PATH "/hfp_hf"
 #define HFP_AGENT_ERROR_INTERFACE "org.bluez.Error"
 
 #ifndef DBUS_TYPE_UNIX_FD
@@ -66,7 +66,6 @@ struct hfp_data {
 	char *handsfree_path;
 	char *handsfree_address;
 	DBusMessage *slc_msg;
-	gboolean agent_registered;
 	DBusPendingCall *call;
 };
 
@@ -158,54 +157,6 @@ static int service_level_connection(struct ofono_modem *modem, int fd)
 	return -EINPROGRESS;
 }
 
-static DBusMessage *hfp_agent_new_connection(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	int fd, err;
-	struct ofono_modem *modem = data;
-	struct hfp_data *hfp_data = ofono_modem_get_data(modem);
-	guint16 version;
-
-	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UNIX_FD, &fd,
-				DBUS_TYPE_UINT16, &version, DBUS_TYPE_INVALID))
-		return __ofono_error_invalid_args(msg);
-
-	hfp_slc_info_init(&hfp_data->info, version);
-
-	err = service_level_connection(modem, fd);
-	if (err < 0 && err != -EINPROGRESS)
-		return __ofono_error_failed(msg);
-
-	hfp_data->slc_msg = msg;
-	dbus_message_ref(msg);
-
-	return NULL;
-}
-
-static DBusMessage *hfp_agent_release(DBusConnection *conn,
-					DBusMessage *msg, void *data)
-{
-	struct ofono_modem *modem = data;
-	struct hfp_data *hfp_data = ofono_modem_get_data(modem);
-	const char *obj_path = ofono_modem_get_path(modem);
-
-	g_dbus_unregister_interface(connection, obj_path, HFP_AGENT_INTERFACE);
-	hfp_data->agent_registered = FALSE;
-
-	g_hash_table_remove(modem_hash, hfp_data->handsfree_path);
-	ofono_modem_remove(modem);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static const GDBusMethodTable agent_methods[] = {
-	{ GDBUS_ASYNC_METHOD("NewConnection",
-				GDBUS_ARGS({ "fd", "h" }, { "version", "q" }),
-				NULL, hfp_agent_new_connection) },
-	{ GDBUS_METHOD("Release", NULL, NULL, hfp_agent_release) },
-	{ }
-};
-
 static int hfp_hf_probe(const char *device, const char *dev_addr,
 				const char *adapter_addr, const char *alias)
 {
@@ -297,76 +248,24 @@ static void hfp_hf_set_alias(const char *device, const char *alias)
 	ofono_modem_set_name(modem, alias);
 }
 
-static int hfp_register_ofono_handsfree(struct ofono_modem *modem)
-{
-	const char *obj_path = ofono_modem_get_path(modem);
-	struct hfp_data *data = ofono_modem_get_data(modem);
-	DBusMessage *msg;
-
-	DBG("Registering oFono Agent to bluetooth daemon");
-
-	msg = dbus_message_new_method_call(BLUEZ_SERVICE, data->handsfree_path,
-				BLUEZ_GATEWAY_INTERFACE, "RegisterAgent");
-	if (msg == NULL)
-		return -ENOMEM;
-
-	dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &obj_path,
-				DBUS_TYPE_INVALID);
-
-	g_dbus_send_message(connection, msg);
-	return 0;
-}
-
-static int hfp_unregister_ofono_handsfree(struct ofono_modem *modem)
-{
-	const char *obj_path = ofono_modem_get_path(modem);
-	struct hfp_data *data = ofono_modem_get_data(modem);
-	DBusMessage *msg;
-
-	DBG("Unregistering oFono Agent from bluetooth daemon");
-
-	msg = dbus_message_new_method_call(BLUEZ_SERVICE, data->handsfree_path,
-				BLUEZ_GATEWAY_INTERFACE, "UnregisterAgent");
-	if (msg == NULL)
-		return -ENOMEM;
-
-	dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &obj_path,
-				DBUS_TYPE_INVALID);
-
-	g_dbus_send_message(connection, msg);
-	return 0;
-}
-
 static int hfp_probe(struct ofono_modem *modem)
 {
-	const char *obj_path = ofono_modem_get_path(modem);
 	struct hfp_data *data = ofono_modem_get_data(modem);
 
 	if (data == NULL)
 		return -EINVAL;
 
-	g_dbus_register_interface(connection, obj_path, HFP_AGENT_INTERFACE,
-			agent_methods, NULL, NULL, modem, NULL);
-
-	data->agent_registered = TRUE;
-
-	if (hfp_register_ofono_handsfree(modem) != 0)
-		return -EINVAL;
-
 	return 0;
 }
 
 static void hfp_remove(struct ofono_modem *modem)
 {
 	struct hfp_data *data = ofono_modem_get_data(modem);
-	const char *obj_path = ofono_modem_get_path(modem);
 
 	if (data->call != NULL)
 		dbus_pending_call_cancel(data->call);
 
-	if (g_dbus_unregister_interface(connection, obj_path,
-					HFP_AGENT_INTERFACE))
-		hfp_unregister_ofono_handsfree(modem);
+	g_hash_table_remove(modem_hash, data->handsfree_path);
 
 	g_free(data->handsfree_address);
 	g_free(data->handsfree_path);
@@ -465,7 +364,7 @@ static int hfp_disable(struct ofono_modem *modem)
 	g_at_chat_unref(data->info.chat);
 	data->info.chat = NULL;
 
-	if (data->agent_registered) {
+	if (ofono_modem_get_powered(modem)) {
 		status = bluetooth_send_with_reply(data->handsfree_path,
 					BLUEZ_GATEWAY_INTERFACE, "Disconnect",
 					&data->call, hfp_power_down,
@@ -497,6 +396,61 @@ static void hfp_post_sim(struct ofono_modem *modem)
 	DBG("%p", modem);
 }
 
+static DBusMessage *hfp_agent_new_connection(DBusConnection *conn,
+						DBusMessage *msg, void *data)
+{
+	int fd, err;
+	struct ofono_modem *modem;
+	struct hfp_data *hfp_data;
+	const char *device;
+	const char *path = NULL;
+	guint16 features = 0;
+	guint16 version = 0;
+
+	fd = bluetooth_parse_newconnection_message(msg, &device, &version,
+							&features, &path);
+	if (fd < 0)
+		return __ofono_error_invalid_args(msg);
+
+	DBG("New connection for %s (version 0x%04X, features 0x%02X, " \
+					"media transport path: %s)",
+					device, version, features, path);
+
+	modem = g_hash_table_lookup(modem_hash, device);
+	if (modem == NULL)
+		return __ofono_error_invalid_args(msg);
+
+	hfp_data = ofono_modem_get_data(modem);
+
+	hfp_slc_info_init(&hfp_data->info, version);
+
+	err = service_level_connection(modem, fd);
+	if (err < 0 && err != -EINPROGRESS)
+		return __ofono_error_failed(msg);
+
+	hfp_data->slc_msg = msg;
+	dbus_message_ref(msg);
+
+	return NULL;
+}
+
+static DBusMessage *hfp_agent_release(DBusConnection *conn,
+					DBusMessage *msg, void *data)
+{
+	DBG("");
+
+	return dbus_message_new_method_return(msg);
+}
+
+static const GDBusMethodTable agent_methods[] = {
+	{ GDBUS_ASYNC_METHOD("NewConnection",
+				GDBUS_ARGS({ "fd", "h" },
+						{ "property", "a{sv}" }),
+				NULL, hfp_agent_new_connection) },
+	{ GDBUS_METHOD("Release", NULL, NULL, hfp_agent_release) },
+	{ }
+};
+
 static struct ofono_modem_driver hfp_driver = {
 	.name		= "hfp",
 	.modem_type	= OFONO_MODEM_TYPE_HFP,
@@ -517,6 +471,8 @@ static struct bluetooth_profile hfp_hf = {
 
 static int hfp_init(void)
 {
+	dbus_uint16_t features = HFP_HF_FEATURE_3WAY | HFP_HF_FEATURE_CLIP |
+					HFP_HF_FEATURE_REMOTE_VOLUME_CONTROL;
 	int err;
 
 	if (DBUS_TYPE_UNIX_FD < 0)
@@ -537,11 +493,16 @@ static int hfp_init(void)
 	modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
 						g_free, NULL);
 
+	bluetooth_register_telephony_agent(HFP_AGENT_PATH, HFP_HS_UUID,
+						HFP_VERSION_1_5, features,
+						agent_methods, NULL, NULL);
+
 	return 0;
 }
 
 static void hfp_exit(void)
 {
+	bluetooth_unregister_telephony_agent(HFP_AGENT_PATH);
 	bluetooth_unregister_uuid(HFP_AG_UUID);
 	ofono_modem_driver_unregister(&hfp_driver);
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 03/12] hfp_ag: Update to org.bluez.Telephony interface
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 01/12] bluetooth: Add org.bluez.Telephony helpers =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 02/12] hfp_hf: Update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 04/12] bluetooth: Add define for MediaTransport interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 5601 bytes --]

Bluez moves agent registration from a per device interface to
a per adapter interface.
Update hfp_ag modem emulator to reflect this change.
---
 plugins/hfp_ag.c |  128 +++++++++++++++++++++++++-----------------------------
 1 file changed, 58 insertions(+), 70 deletions(-)

diff --git a/plugins/hfp_ag.c b/plugins/hfp_ag.c
index c2d1d30..2652f3f 100644
--- a/plugins/hfp_ag.c
+++ b/plugins/hfp_ag.c
@@ -35,97 +35,85 @@
 
 #include "bluetooth.h"
 
-#define HFP_AG_CHANNEL	13
+#define AGENT_PATH "/hfp_ag"
+#define VERSION_1_5 0x0105
+#define FEATURES	(HFP_AG_FEATURE_3WAY | HFP_AG_FEATURE_REJECT_CALL | \
+			HFP_AG_FEATURE_ENHANCED_CALL_STATUS | \
+			HFP_AG_FEATURE_ENHANCED_CALL_CONTROL | \
+			HFP_AG_FEATURE_EXTENDED_RES_CODE)
+
+#ifndef DBUS_TYPE_UNIX_FD
+#define DBUS_TYPE_UNIX_FD -1
+#endif
 
-static struct server *server;
 static guint modemwatch_id;
 static GList *modems;
 static GHashTable *sim_hash = NULL;
 
-static const gchar *hfp_ag_record =
-"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
-"<record>\n"
-"  <attribute id=\"0x0001\">\n"
-"    <sequence>\n"
-"      <uuid value=\"0x111F\"/>\n"
-"      <uuid value=\"0x1203\"/>\n"
-"    </sequence>\n"
-"  </attribute>\n"
-"\n"
-"  <attribute id=\"0x0004\">\n"
-"    <sequence>\n"
-"      <sequence>\n"
-"        <uuid value=\"0x0100\"/>\n"
-"      </sequence>\n"
-"      <sequence>\n"
-"        <uuid value=\"0x0003\"/>\n"
-"        <uint8 value=\"13\" name=\"channel\"/>\n"
-"      </sequence>\n"
-"    </sequence>\n"
-"  </attribute>\n"
-"\n"
-"  <attribute id=\"0x0009\">\n"
-"    <sequence>\n"
-"      <sequence>\n"
-"        <uuid value=\"0x111E\"/>\n"
-"        <uint16 value=\"0x0105\" name=\"version\"/>\n"
-"      </sequence>\n"
-"    </sequence>\n"
-"  </attribute>\n"
-"\n"
-"  <attribute id=\"0x0100\">\n"
-"    <text value=\"Hands-Free Audio Gateway\" name=\"name\"/>\n"
-"  </attribute>\n"
-"\n"
-"  <attribute id=\"0x0301\">\n"
-"    <uint8 value=\"0x01\" />\n"
-"  </attribute>\n"
-"\n"
-"  <attribute id=\"0x0311\">\n"
-"    <uint16 value=\"0x0001\" />\n"
-"  </attribute>\n"
-"</record>\n";
-
-static void hfp_ag_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
+static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
+						DBusMessage *msg, void *data)
 {
-	struct ofono_modem *modem;
-	struct ofono_emulator *em;
 	int fd;
+	const char *device;
+	const char *path = NULL;
+	guint16 version = 0;
+	guint16 features = 0;
+	struct ofono_emulator *em;
+	struct ofono_modem *modem;
 
-	DBG("");
+	fd = bluetooth_parse_newconnection_message(msg, &device, &version,
+							&features, &path);
+	if (fd < 0)
+		return __ofono_error_invalid_args(msg);
 
-	if (err) {
-		DBG("%s", err->message);
-		return;
-	}
+	DBG("New connection for %s (version 0x%04X, features 0x%02X, " \
+					"media transport path: %s)",
+					device, version, features, path);
 
 	/* Pick the first voicecall capable modem */
 	modem = modems->data;
 	if (modem == NULL)
-		return;
+		return __ofono_error_failed(msg);
 
 	DBG("Picked modem %p for emulator", modem);
 
 	em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_HFP);
 	if (em == NULL)
-		return;
-
-	fd = g_io_channel_unix_get_fd(io);
-	g_io_channel_set_close_on_unref(io, FALSE);
+		return __ofono_error_failed(msg);
 
 	ofono_emulator_register(em, fd);
+
+	return dbus_message_new_method_return(msg);
 }
 
+static DBusMessage *hfp_ag_agent_release(DBusConnection *conn,
+					DBusMessage *msg, void *data)
+{
+	DBG("");
+
+	return dbus_message_new_method_return(msg);
+}
+
+static const GDBusMethodTable agent_methods[] = {
+	{ GDBUS_ASYNC_METHOD("NewConnection",
+				GDBUS_ARGS({ "fd", "h" },
+						{ "property", "a{sv}" }),
+				NULL, hfp_ag_agent_new_connection) },
+	{ GDBUS_METHOD("Release", NULL, NULL, hfp_ag_agent_release) },
+	{ }
+};
+
 static void sim_state_watch(enum ofono_sim_state new_state, void *data)
 {
 	struct ofono_modem *modem = data;
 
 	if (new_state != OFONO_SIM_STATE_READY) {
+		if (modems == NULL)
+			return;
+
 		modems = g_list_remove(modems, modem);
-		if (modems == NULL && server != NULL) {
-			bluetooth_unregister_server(server);
-			server = NULL;
-		}
+		if (modems == NULL)
+			bluetooth_unregister_telephony_agent(AGENT_PATH);
 
 		return;
 	}
@@ -138,8 +126,9 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *data)
 	if (modems->next != NULL)
 		return;
 
-	server = bluetooth_register_server(HFP_AG_CHANNEL, hfp_ag_record,
-						hfp_ag_connect_cb, NULL);
+	bluetooth_register_telephony_agent(AGENT_PATH, HFP_AG_UUID,
+						VERSION_1_5, FEATURES,
+						agent_methods, NULL, NULL);
 }
 
 static gboolean sim_watch_remove(gpointer key, gpointer value,
@@ -192,6 +181,9 @@ static void call_modemwatch(struct ofono_modem *modem, void *user)
 
 static int hfp_ag_init(void)
 {
+	if (DBUS_TYPE_UNIX_FD < 0)
+		return -EBADF;
+
 	sim_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
 
 	modemwatch_id = __ofono_modemwatch_add(modem_watch, NULL, NULL);
@@ -203,14 +195,10 @@ static int hfp_ag_init(void)
 static void hfp_ag_exit(void)
 {
 	__ofono_modemwatch_remove(modemwatch_id);
+
 	g_list_free(modems);
 	g_hash_table_foreach_remove(sim_hash, sim_watch_remove, NULL);
 	g_hash_table_destroy(sim_hash);
-
-	if (server) {
-		bluetooth_unregister_server(server);
-		server = NULL;
-	}
 }
 
 OFONO_PLUGIN_DEFINE(hfp_ag, "Hands-Free Audio Gateway Profile Plugins", VERSION,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 04/12] bluetooth: Add define for MediaTransport interface
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (2 preceding siblings ...)
  2012-08-01 10:09 ` [RFC v6 03/12] hfp_ag: " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 05/12] include: Add set/get data APIs to emulator =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 542 bytes --]

---
 plugins/bluetooth.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h
index 6a2fbf0..ecc89c3 100644
--- a/plugins/bluetooth.h
+++ b/plugins/bluetooth.h
@@ -31,6 +31,7 @@
 #define BLUEZ_SERIAL_INTERFACE		BLUEZ_SERVICE ".Serial"
 #define	BLUEZ_TELEPHONY_INTERFACE	BLUEZ_SERVICE ".Telephony"
 #define	BLUEZ_TELEPHONY_AGENT_INTERFACE	BLUEZ_SERVICE ".TelephonyAgent"
+#define	BLUEZ_TRANSPORT_INTERFACE	BLUEZ_SERVICE ".MediaTransport"
 
 #define DBUS_TIMEOUT 15
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 05/12] include: Add set/get data APIs to emulator
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (3 preceding siblings ...)
  2012-08-01 10:09 ` [RFC v6 04/12] bluetooth: Add define for MediaTransport interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 06/12] emulator: Add set/get data APIs =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 715 bytes --]

---
 include/emulator.h |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/emulator.h b/include/emulator.h
index 5cd894b..6dc1938 100644
--- a/include/emulator.h
+++ b/include/emulator.h
@@ -74,6 +74,11 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd);
 
 void ofono_emulator_remove(struct ofono_emulator *em);
 
+void ofono_emulator_set_data(struct ofono_emulator *em, void *data,
+						ofono_destroy_func destroy);
+
+void *ofono_emulator_get_data(struct ofono_emulator *em);
+
 void ofono_emulator_send_final(struct ofono_emulator *em,
 				const struct ofono_error *final);
 void ofono_emulator_send_unsolicited(struct ofono_emulator *em,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 06/12] emulator: Add set/get data APIs
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (4 preceding siblings ...)
  2012-08-01 10:09 ` [RFC v6 05/12] include: Add set/get data APIs to emulator =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 07/12] hfp_ag: Add AT+NREC support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1039 bytes --]

---
 src/emulator.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/emulator.c b/src/emulator.c
index c3165eb..14a39f3 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -52,6 +52,8 @@ struct ofono_emulator {
 	gboolean clip;
 	gboolean ccwa;
 	int pns_id;
+	void *data;
+	ofono_destroy_func destroy;
 };
 
 struct indicator {
@@ -951,6 +953,9 @@ static void emulator_remove(struct ofono_atom *atom)
 
 	DBG("atom: %p", atom);
 
+	if (em->destroy)
+		em->destroy(em->data);
+
 	g_free(em);
 }
 
@@ -994,6 +999,18 @@ void ofono_emulator_remove(struct ofono_emulator *em)
 	__ofono_atom_free(em->atom);
 }
 
+void ofono_emulator_set_data(struct ofono_emulator *em, void *data,
+						ofono_destroy_func destroy)
+{
+	em->data = data;
+	em->destroy = destroy;
+}
+
+void *ofono_emulator_get_data(struct ofono_emulator *em)
+{
+	return em->data;
+}
+
 void ofono_emulator_send_final(struct ofono_emulator *em,
 				const struct ofono_error *final)
 {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 07/12] hfp_ag: Add AT+NREC support
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (5 preceding siblings ...)
  2012-08-01 10:09 ` [RFC v6 06/12] emulator: Add set/get data APIs =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 08/12] hfp_ag: Add +BSIR support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 5074 bytes --]

---
 plugins/hfp_ag.c |  153 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 152 insertions(+), 1 deletion(-)

diff --git a/plugins/hfp_ag.c b/plugins/hfp_ag.c
index 2652f3f..342f959 100644
--- a/plugins/hfp_ag.c
+++ b/plugins/hfp_ag.c
@@ -37,7 +37,8 @@
 
 #define AGENT_PATH "/hfp_ag"
 #define VERSION_1_5 0x0105
-#define FEATURES	(HFP_AG_FEATURE_3WAY | HFP_AG_FEATURE_REJECT_CALL | \
+#define FEATURES	(HFP_AG_FEATURE_3WAY | HFP_AG_FEATURE_ECNR | \
+			HFP_AG_FEATURE_REJECT_CALL | \
 			HFP_AG_FEATURE_ENHANCED_CALL_STATUS | \
 			HFP_AG_FEATURE_ENHANCED_CALL_CONTROL | \
 			HFP_AG_FEATURE_EXTENDED_RES_CODE)
@@ -46,10 +47,150 @@
 #define DBUS_TYPE_UNIX_FD -1
 #endif
 
+struct bt_audio {
+	struct ofono_emulator *em;
+	char *path;
+	guint16 r_features;
+	DBusPendingCall *call;
+};
+
 static guint modemwatch_id;
 static GList *modems;
 static GHashTable *sim_hash = NULL;
 
+static void audio_transport_set_property_cb(DBusPendingCall *call,
+						gpointer user_data)
+{
+	struct bt_audio *audio = user_data;
+	DBusMessage *reply;
+	struct DBusError derr;
+	struct ofono_error result;
+
+	reply = dbus_pending_call_steal_reply(call);
+
+	dbus_error_init(&derr);
+
+	if (dbus_set_error_from_message(&derr, reply)) {
+		ofono_error("MediaTransport.SetProperties replied an error: " \
+				"%s, %s", derr.name, derr.message);
+		dbus_error_free(&derr);
+		result.type = OFONO_ERROR_TYPE_FAILURE;
+	} else
+		result.type = OFONO_ERROR_TYPE_NO_ERROR;
+
+	result.error = 0;
+	ofono_emulator_send_final(audio->em, &result);
+
+	dbus_message_unref(reply);
+
+	dbus_pending_call_unref(audio->call);
+	audio->call = NULL;
+}
+
+static void audio_transport_set_property(struct bt_audio *audio,
+				const char *name, int type, const void *value)
+{
+	DBusMessage *msg;
+	DBusMessageIter iter, var;
+	const char *str_type;
+	DBusConnection *connection;
+	struct ofono_error result;
+
+	if (audio->call != NULL)
+		goto fail;
+
+	if (audio->path == NULL)
+		goto fail;
+
+	switch (type) {
+	case DBUS_TYPE_BOOLEAN:
+		str_type = DBUS_TYPE_BOOLEAN_AS_STRING;
+		break;
+
+	case DBUS_TYPE_UINT16:
+		str_type = DBUS_TYPE_UINT16_AS_STRING;
+		break;
+
+	default:
+		goto fail;
+	}
+
+	msg = dbus_message_new_method_call(BLUEZ_SERVICE, audio->path,
+				BLUEZ_TRANSPORT_INTERFACE, "SetProperty");
+	if (msg == NULL)
+		goto fail;
+
+	dbus_message_iter_init_append(msg, &iter);
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, str_type,
+						&var);
+	dbus_message_iter_append_basic(&var, type, value);
+	dbus_message_iter_close_container(&iter, &var);
+
+	connection = ofono_dbus_get_connection();
+
+	if (!dbus_connection_send_with_reply(connection, msg, &audio->call,
+									-1)) {
+		ofono_error("Sending SetProperty failed");
+		dbus_message_unref(msg);
+		goto fail;
+	}
+
+	dbus_pending_call_set_notify(audio->call,
+						audio_transport_set_property_cb,
+						audio, NULL);
+
+	dbus_message_unref(msg);
+	return;
+
+fail:
+	result.error = 0;
+	result.type = OFONO_ERROR_TYPE_FAILURE;
+	ofono_emulator_send_final(audio->em, &result);
+}
+
+static void emulator_nrec_cb(struct ofono_emulator *em,
+			struct ofono_emulator_request *req, void *userdata)
+{
+	struct bt_audio *audio = userdata;
+	struct ofono_error result;
+	int val;
+
+	switch (ofono_emulator_request_get_type(req)) {
+	case OFONO_EMULATOR_REQUEST_TYPE_SET:
+		if (!ofono_emulator_request_next_number(req, &val))
+			goto fail;
+
+		if (val != 0 && val != 1)
+			goto fail;
+
+		audio_transport_set_property(audio, "NREC", DBUS_TYPE_BOOLEAN,
+									&val);
+		break;
+
+	default:
+fail:
+		result.error = 0;
+		result.type = OFONO_ERROR_TYPE_FAILURE;
+		ofono_emulator_send_final(em, &result);
+	};
+}
+
+static void free_audio_management(struct bt_audio *audio)
+{
+	DBG("");
+
+	if (audio == NULL)
+		return;
+
+	if (audio->call)
+		dbus_pending_call_cancel(audio->call);
+
+	g_free(audio->path);
+	g_free(audio);
+}
+
 static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
 						DBusMessage *msg, void *data)
 {
@@ -60,6 +201,7 @@ static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
 	guint16 features = 0;
 	struct ofono_emulator *em;
 	struct ofono_modem *modem;
+	struct bt_audio *audio;
 
 	fd = bluetooth_parse_newconnection_message(msg, &device, &version,
 							&features, &path);
@@ -83,6 +225,15 @@ static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
 
 	ofono_emulator_register(em, fd);
 
+	audio = g_new0(struct bt_audio, 1);
+	audio->em = em;
+	audio->path = g_strdup(path);
+	audio->r_features = features;
+	ofono_emulator_set_data(em, audio,
+				(ofono_destroy_func)free_audio_management);
+
+	ofono_emulator_add_handler(em, "+NREC", emulator_nrec_cb, audio, NULL);
+
 	return dbus_message_new_method_return(msg);
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 08/12] hfp_ag: Add +BSIR support
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (6 preceding siblings ...)
  2012-08-01 10:09 ` [RFC v6 07/12] hfp_ag: Add AT+NREC support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 09/12] hfp_ag: Add AT+VGM support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 2593 bytes --]

---
 plugins/hfp_ag.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/plugins/hfp_ag.c b/plugins/hfp_ag.c
index 342f959..6821500 100644
--- a/plugins/hfp_ag.c
+++ b/plugins/hfp_ag.c
@@ -38,6 +38,7 @@
 #define AGENT_PATH "/hfp_ag"
 #define VERSION_1_5 0x0105
 #define FEATURES	(HFP_AG_FEATURE_3WAY | HFP_AG_FEATURE_ECNR | \
+			HFP_AG_FEATURE_IN_BAND_RING_TONE | \
 			HFP_AG_FEATURE_REJECT_CALL | \
 			HFP_AG_FEATURE_ENHANCED_CALL_STATUS | \
 			HFP_AG_FEATURE_ENHANCED_CALL_CONTROL | \
@@ -52,6 +53,7 @@ struct bt_audio {
 	char *path;
 	guint16 r_features;
 	DBusPendingCall *call;
+	guint watch;
 };
 
 static guint modemwatch_id;
@@ -177,8 +179,50 @@ fail:
 	};
 }
 
+static gboolean audio_property_changed(DBusConnection *connection,
+					DBusMessage *message, void *user_data)
+{
+	struct bt_audio *audio = user_data;
+	const char *property;
+	char buf[10];
+	DBusMessageIter iter;
+
+	dbus_message_iter_init(message, &iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+		return FALSE;
+
+	dbus_message_iter_get_basic(&iter, &property);
+
+	if (g_str_equal(property, "InbandRingtone") == TRUE) {
+		DBusMessageIter variant;
+		gboolean value;
+
+		if (!dbus_message_iter_next(&iter))
+			return TRUE;
+
+		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+			return TRUE;
+
+		dbus_message_iter_recurse(&iter, &variant);
+
+		if (dbus_message_iter_get_arg_type(&variant) !=
+							DBUS_TYPE_BOOLEAN)
+			return TRUE;
+
+		dbus_message_iter_get_basic(&variant, &value);
+
+		sprintf(buf, "+BSIR: %d", value);
+		ofono_emulator_send_unsolicited(audio->em, buf);
+	}
+
+	return TRUE;
+}
+
 static void free_audio_management(struct bt_audio *audio)
 {
+	DBusConnection *connection = ofono_dbus_get_connection();
+
 	DBG("");
 
 	if (audio == NULL)
@@ -187,6 +231,8 @@ static void free_audio_management(struct bt_audio *audio)
 	if (audio->call)
 		dbus_pending_call_cancel(audio->call);
 
+	g_dbus_remove_watch(connection, audio->watch);
+
 	g_free(audio->path);
 	g_free(audio);
 }
@@ -234,6 +280,12 @@ static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
 
 	ofono_emulator_add_handler(em, "+NREC", emulator_nrec_cb, audio, NULL);
 
+	audio->watch = g_dbus_add_signal_watch(conn, NULL, path,
+						BLUEZ_TRANSPORT_INTERFACE,
+						"PropertyChanged",
+						audio_property_changed,
+						audio, NULL);
+
 	return dbus_message_new_method_return(msg);
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 09/12] hfp_ag: Add AT+VGM support
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (7 preceding siblings ...)
  2012-08-01 10:09 ` [RFC v6 08/12] hfp_ag: Add +BSIR support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 10/12] hfp_ag: Add AT+VGS support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 3412 bytes --]

---
 plugins/hfp_ag.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/plugins/hfp_ag.c b/plugins/hfp_ag.c
index 6821500..f865208 100644
--- a/plugins/hfp_ag.c
+++ b/plugins/hfp_ag.c
@@ -54,6 +54,8 @@ struct bt_audio {
 	guint16 r_features;
 	DBusPendingCall *call;
 	guint watch;
+	int mic_gain;
+	int mic_pending;
 };
 
 static guint modemwatch_id;
@@ -179,6 +181,39 @@ fail:
 	};
 }
 
+static void emulator_vgm_cb(struct ofono_emulator *em,
+			struct ofono_emulator_request *req, void *userdata)
+{
+	struct bt_audio *audio = userdata;
+	struct ofono_error result;
+	int val;
+	dbus_uint16_t dbus_val;
+
+	switch (ofono_emulator_request_get_type(req)) {
+	case OFONO_EMULATOR_REQUEST_TYPE_SET:
+		if (!ofono_emulator_request_next_number(req, &val))
+			goto fail;
+
+		if (val < 0 && val > 15)
+			goto fail;
+
+		if (audio->mic_pending != -1)
+			ofono_error("Receiving AT+VGM while processing one");
+
+		audio->mic_pending = val;
+		dbus_val = val;
+		audio_transport_set_property(audio, "InputGain",
+						DBUS_TYPE_UINT16, &dbus_val);
+		break;
+
+	default:
+fail:
+		result.error = 0;
+		result.type = OFONO_ERROR_TYPE_FAILURE;
+		ofono_emulator_send_final(em, &result);
+	};
+}
+
 static gboolean audio_property_changed(DBusConnection *connection,
 					DBusMessage *message, void *user_data)
 {
@@ -214,6 +249,43 @@ static gboolean audio_property_changed(DBusConnection *connection,
 
 		sprintf(buf, "+BSIR: %d", value);
 		ofono_emulator_send_unsolicited(audio->em, buf);
+	} else if (g_str_equal(property, "InputGain") == TRUE) {
+		DBusMessageIter variant;
+		dbus_uint16_t dbus_val;
+		int value;
+
+		if (!(audio->r_features & HFP_HF_FEATURE_REMOTE_VOLUME_CONTROL))
+			return TRUE;
+
+		if (!dbus_message_iter_next(&iter))
+			return TRUE;
+
+		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+			return TRUE;
+
+		dbus_message_iter_recurse(&iter, &variant);
+
+		if (dbus_message_iter_get_arg_type(&variant) !=
+							DBUS_TYPE_UINT16)
+			return TRUE;
+
+		dbus_message_iter_get_basic(&variant, &dbus_val);
+		value = dbus_val;
+
+		/* Send unsolicited +VGM only if :
+		 *   - the value has changed
+		 *   - and this is not a side effect of AT+VGM
+		 * But, if we receive a value change while waiting for another
+		 * pending change, we may have to send +VGM for other changes
+		 * (multiple AT+VGM received) to keep mic gain in sync
+		 */
+		if (audio->mic_pending != value && audio->mic_gain != value) {
+			sprintf(buf, "+VGM: %d", value);
+			ofono_emulator_send_unsolicited(audio->em, buf);
+			audio->mic_pending = -1;
+		} else if (audio->mic_pending == value)
+			audio->mic_pending = -1;
+		audio->mic_gain = value;
 	}
 
 	return TRUE;
@@ -275,10 +347,12 @@ static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
 	audio->em = em;
 	audio->path = g_strdup(path);
 	audio->r_features = features;
+	audio->mic_pending = -1;
 	ofono_emulator_set_data(em, audio,
 				(ofono_destroy_func)free_audio_management);
 
 	ofono_emulator_add_handler(em, "+NREC", emulator_nrec_cb, audio, NULL);
+	ofono_emulator_add_handler(em, "+VGM", emulator_vgm_cb, audio, NULL);
 
 	audio->watch = g_dbus_add_signal_watch(conn, NULL, path,
 						BLUEZ_TRANSPORT_INTERFACE,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 10/12] hfp_ag: Add AT+VGS support
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (8 preceding siblings ...)
  2012-08-01 10:09 ` [RFC v6 09/12] hfp_ag: Add AT+VGM support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 11/12] emulator: Update supported features =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 12/12] dun_gw: Update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 3485 bytes --]

---
 plugins/hfp_ag.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/plugins/hfp_ag.c b/plugins/hfp_ag.c
index f865208..3084cd6 100644
--- a/plugins/hfp_ag.c
+++ b/plugins/hfp_ag.c
@@ -56,6 +56,8 @@ struct bt_audio {
 	guint watch;
 	int mic_gain;
 	int mic_pending;
+	int sp_gain;
+	int sp_pending;
 };
 
 static guint modemwatch_id;
@@ -214,6 +216,39 @@ fail:
 	};
 }
 
+static void emulator_vgs_cb(struct ofono_emulator *em,
+		struct ofono_emulator_request *req, void *userdata)
+{
+	struct bt_audio *audio = userdata;
+	struct ofono_error result;
+	int val;
+	dbus_uint16_t dbus_val;
+
+	switch (ofono_emulator_request_get_type(req)) {
+	case OFONO_EMULATOR_REQUEST_TYPE_SET:
+		if (!ofono_emulator_request_next_number(req, &val))
+			goto fail;
+
+		if (val < 0 && val > 15)
+			goto fail;
+
+		if (audio->sp_pending != -1)
+			ofono_error("Receiving AT+VGS while processing one");
+
+		audio->sp_pending = val;
+		dbus_val = val;
+		audio_transport_set_property(audio, "OutputGain",
+						DBUS_TYPE_UINT16, &dbus_val);
+		break;
+
+	default:
+fail:
+		result.error = 0;
+		result.type = OFONO_ERROR_TYPE_FAILURE;
+		ofono_emulator_send_final(em, &result);
+	};
+}
+
 static gboolean audio_property_changed(DBusConnection *connection,
 					DBusMessage *message, void *user_data)
 {
@@ -286,6 +321,43 @@ static gboolean audio_property_changed(DBusConnection *connection,
 		} else if (audio->mic_pending == value)
 			audio->mic_pending = -1;
 		audio->mic_gain = value;
+	} else if (g_str_equal(property, "OutputGain") == TRUE) {
+		DBusMessageIter variant;
+		dbus_uint16_t dbus_val;
+		int value;
+
+		if (!(audio->r_features & HFP_HF_FEATURE_REMOTE_VOLUME_CONTROL))
+			return TRUE;
+
+		if (!dbus_message_iter_next(&iter))
+			return TRUE;
+
+		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+			return TRUE;
+
+		dbus_message_iter_recurse(&iter, &variant);
+
+		if (dbus_message_iter_get_arg_type(&variant) !=
+							DBUS_TYPE_UINT16)
+			return TRUE;
+
+		dbus_message_iter_get_basic(&variant, &dbus_val);
+		value = dbus_val;
+
+		/* Send unsolicited +VGS only if :
+		 *   - the value has changed
+		 *   - and this is not a side effect of AT+VGS
+		 * But, if we receive a value change while waiting for another
+		 * pending change, we may have to send +VGS for other changes
+		 * (multiple AT+VGS received) to keep speaker gain in sync
+		 */
+		if (audio->sp_pending != value && audio->sp_gain != value) {
+			sprintf(buf, "+VGS: %d", value);
+			ofono_emulator_send_unsolicited(audio->em, buf);
+			audio->sp_pending = -1;
+		} else if (audio->sp_pending == value)
+			audio->sp_pending = -1;
+		audio->sp_gain = value;
 	}
 
 	return TRUE;
@@ -348,11 +420,13 @@ static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
 	audio->path = g_strdup(path);
 	audio->r_features = features;
 	audio->mic_pending = -1;
+	audio->sp_pending = -1;
 	ofono_emulator_set_data(em, audio,
 				(ofono_destroy_func)free_audio_management);
 
 	ofono_emulator_add_handler(em, "+NREC", emulator_nrec_cb, audio, NULL);
 	ofono_emulator_add_handler(em, "+VGM", emulator_vgm_cb, audio, NULL);
+	ofono_emulator_add_handler(em, "+VGS", emulator_vgs_cb, audio, NULL);
 
 	audio->watch = g_dbus_add_signal_watch(conn, NULL, path,
 						BLUEZ_TRANSPORT_INTERFACE,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 11/12] emulator: Update supported features
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (9 preceding siblings ...)
  2012-08-01 10:09 ` [RFC v6 10/12] hfp_ag: Add AT+VGS support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-08-01 10:09 ` [RFC v6 12/12] dun_gw: Update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 741 bytes --]

Add ECNR (Echo Cancelation/Noise Reduction) and Inband Ringtone
capabilities to supported features (+BRSF event)
---
 src/emulator.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/emulator.c b/src/emulator.c
index 14a39f3..791d88b 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -981,6 +981,8 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
 
 	em->type = type;
 	em->l_features |= HFP_AG_FEATURE_3WAY;
+	em->l_features |= HFP_AG_FEATURE_ECNR;
+	em->l_features |= HFP_AG_FEATURE_IN_BAND_RING_TONE;
 	em->l_features |= HFP_AG_FEATURE_REJECT_CALL;
 	em->l_features |= HFP_AG_FEATURE_ENHANCED_CALL_STATUS;
 	em->l_features |= HFP_AG_FEATURE_ENHANCED_CALL_CONTROL;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC v6 12/12] dun_gw: Update to org.bluez.Telephony interface
  2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (10 preceding siblings ...)
  2012-08-01 10:09 ` [RFC v6 11/12] emulator: Update supported features =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-08-01 10:09 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  11 siblings, 0 replies; 13+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-08-01 10:09 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 4832 bytes --]

Bluez moves agent registration from a per device interface to
a per adapter interface.
Update dun_gw modem emulator to reflect this change.
---
 plugins/dun_gw.c |  119 ++++++++++++++++++++++++------------------------------
 1 file changed, 52 insertions(+), 67 deletions(-)

diff --git a/plugins/dun_gw.c b/plugins/dun_gw.c
index 75b62eb..5cc839e 100644
--- a/plugins/dun_gw.c
+++ b/plugins/dun_gw.c
@@ -35,77 +35,65 @@
 
 #include "bluetooth.h"
 
-#define DUN_GW_CHANNEL	1
+#define AGENT_PATH	"/dun_gw"
+#define VERSION_1_0	0x0100
+
+#ifndef DBUS_TYPE_UNIX_FD
+#define DBUS_TYPE_UNIX_FD -1
+#endif
 
-static struct server *server;
 static guint modemwatch_id;
 static GList *modems;
 
-static const gchar *dun_record =
-"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
-"<record>\n"
-"  <attribute id=\"0x0001\">\n"
-"    <sequence>\n"
-"      <uuid value=\"0x1103\"/>\n"
-"    </sequence>\n"
-"  </attribute>\n"
-"\n"
-"  <attribute id=\"0x0004\">\n"
-"    <sequence>\n"
-"      <sequence>\n"
-"        <uuid value=\"0x0100\"/>\n"
-"      </sequence>\n"
-"      <sequence>\n"
-"        <uuid value=\"0x0003\"/>\n"
-"        <uint8 value=\"1\" name=\"channel\"/>\n"
-"      </sequence>\n"
-"    </sequence>\n"
-"  </attribute>\n"
-"\n"
-"  <attribute id=\"0x0009\">\n"
-"    <sequence>\n"
-"      <sequence>\n"
-"        <uuid value=\"0x1103\"/>\n"
-"        <uint16 value=\"0x0100\" name=\"version\"/>\n"
-"      </sequence>\n"
-"    </sequence>\n"
-"  </attribute>\n"
-"\n"
-"  <attribute id=\"0x0100\">\n"
-"    <text value=\"Dial-up Networking\" name=\"name\"/>\n"
-"  </attribute>\n"
-"</record>\n";
-
-static void dun_gw_connect_cb(GIOChannel *io, GError *err, gpointer user_data)
+static DBusMessage *dun_gw_agent_new_connection(DBusConnection *conn,
+						DBusMessage *msg, void *data)
 {
-	struct ofono_emulator *em = user_data;
-	struct ofono_modem *modem;
 	int fd;
+	const char *device;
+	guint16 version = 0;
+	struct ofono_emulator *em;
+	struct ofono_modem *modem;
 
-	DBG("");
+	fd = bluetooth_parse_newconnection_message(msg, &device, &version, NULL,
+							NULL);
+	if (fd < 0)
+		return __ofono_error_invalid_args(msg);
 
-	if (err) {
-		DBG("%s", err->message);
-		g_io_channel_shutdown(io, TRUE, NULL);
-		return;
-	}
+	DBG("New connection for %s (version 0x%04X)", device, version);
 
 	/* Pick the first powered modem */
 	modem = modems->data;
+	if (modem == NULL)
+		return __ofono_error_failed(msg);
+
 	DBG("Picked modem %p for emulator", modem);
 
 	em = ofono_emulator_create(modem, OFONO_EMULATOR_TYPE_DUN);
-	if (em == NULL) {
-		g_io_channel_shutdown(io, TRUE, NULL);
-		return;
-	}
-
-	fd = g_io_channel_unix_get_fd(io);
-	g_io_channel_set_close_on_unref(io, FALSE);
+	if (em == NULL)
+		return __ofono_error_failed(msg);
 
 	ofono_emulator_register(em, fd);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *dun_gw_agent_release(DBusConnection *conn,
+					DBusMessage *msg, void *data)
+{
+	DBG("");
+
+	return dbus_message_new_method_return(msg);
 }
 
+static const GDBusMethodTable agent_methods[] = {
+	{ GDBUS_ASYNC_METHOD("NewConnection",
+				GDBUS_ARGS({ "fd", "h" },
+						{ "property", "a{sv}" }),
+				NULL, dun_gw_agent_new_connection) },
+	{ GDBUS_METHOD("Release", NULL, NULL, dun_gw_agent_release) },
+	{ }
+};
+
 static void gprs_watch(struct ofono_atom *atom,
 				enum ofono_atom_watch_condition cond,
 				void *data)
@@ -115,17 +103,16 @@ static void gprs_watch(struct ofono_atom *atom,
 	if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED) {
 		modems = g_list_append(modems, modem);
 
-		if (modems->next == NULL)
-			server = bluetooth_register_server(DUN_GW_CHANNEL,
-					dun_record,
-					dun_gw_connect_cb,
-					NULL);
+		if (modems->next != NULL)
+			return;
+
+		bluetooth_register_telephony_agent(AGENT_PATH, DUN_GW_UUID,
+						   VERSION_1_0, 0,
+						   agent_methods, NULL, NULL);
 	} else {
 		modems = g_list_remove(modems, modem);
-		if (modems == NULL && server != NULL) {
-			bluetooth_unregister_server(server);
-			server = NULL;
-		}
+		if (modems == NULL)
+			bluetooth_unregister_telephony_agent(AGENT_PATH);
 	}
 }
 
@@ -149,6 +136,9 @@ static int dun_gw_init(void)
 {
 	DBG("");
 
+	if (DBUS_TYPE_UNIX_FD < 0)
+		return -EBADF;
+
 	modemwatch_id = __ofono_modemwatch_add(modem_watch, NULL, NULL);
 
 	__ofono_modem_foreach(call_modemwatch, NULL);
@@ -160,11 +150,6 @@ static void dun_gw_exit(void)
 {
 	__ofono_modemwatch_remove(modemwatch_id);
 	g_list_free(modems);
-
-	if (server) {
-		bluetooth_unregister_server(server);
-		server = NULL;
-	}
 }
 
 OFONO_PLUGIN_DEFINE(dun_gw, "Dial-up Networking Profile Plugins", VERSION,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2012-08-01 10:09 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-01 10:09 [RFC v6 00/12] Add org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 01/12] bluetooth: Add org.bluez.Telephony helpers =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 02/12] hfp_hf: Update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 03/12] hfp_ag: " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 04/12] bluetooth: Add define for MediaTransport interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 05/12] include: Add set/get data APIs to emulator =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 06/12] emulator: Add set/get data APIs =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 07/12] hfp_ag: Add AT+NREC support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 08/12] hfp_ag: Add +BSIR support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 09/12] hfp_ag: Add AT+VGM support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 10/12] hfp_ag: Add AT+VGS support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 11/12] emulator: Update supported features =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-08-01 10:09 ` [RFC v6 12/12] dun_gw: Update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.