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

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

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

For HFP AG plugin, 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

Since latest RFC :
- Patche 1
  move agent registration from adapter_added() to adapter_properties_cb()
- Patches 4 to 10:
  Rewrote support of AT+NREC, AT+VGM, +VGM, AT+VGS, +VGS and +BSIR into
  bluetooth plugin

Frédéric Danis (10):
  bluetooth: Add org.bluez.Telephony helpers
  hfp_hf: Update to org.bluez.Telephony interface
  hfp_ag: Update to org.bluez.Telephony interface
  bluetooth: Add audio APIs for HFP AG
  bluetooth: Add AT+NREC support
  bluetooth: Add +BSIR support
  bluetooth: Add AT+VGM support
  bluetooth: Add AT+VGS support
  hfp_ag: Add media transport support
  emulator: Update supported features

 plugins/bluetooth.c |  531 +++++++++++++++++++++++++++++++++++++++++++++++++++
 plugins/bluetooth.h |   18 ++
 plugins/hfp_ag.c    |  143 +++++++-------
 plugins/hfp_hf.c    |  165 ++++++----------
 src/emulator.c      |    2 +
 5 files changed, 686 insertions(+), 173 deletions(-)


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

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

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

Add function to register/unregister Telephony agent to BlueZ
---
 plugins/bluetooth.c |  198 +++++++++++++++++++++++++++++++++++++++++++++++++++
 plugins/bluetooth.h |   14 ++++
 2 files changed, 212 insertions(+), 0 deletions(-)

diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index dbf79eb..971e2c6 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);
@@ -982,5 +1047,138 @@ void bluetooth_unregister_server(struct server *server)
 	bluetooth_unref();
 }
 
+int bluetooth_parse_newconnection_message(DBusMessage *msg, const char **device,
+					const char **uuid, guint16 *version,
+					guint16 *features,
+					const char **transport_path)
+{
+	DBusMessageIter args, props;
+	int fd;
+	gboolean has_device = FALSE;
+	gboolean has_uuid = 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, "UUID") == 0) {
+			if (var != DBUS_TYPE_STRING)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, uuid);
+			has_uuid = 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 && has_uuid) ? 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 daa1873..f81fc99 100644
--- a/plugins/bluetooth.h
+++ b/plugins/bluetooth.h
@@ -21,12 +21,15 @@
 
 #include <ofono/modem.h>
 #include <ofono/dbus.h>
+#include <gdbus.h>
 
 #define	BLUEZ_SERVICE "org.bluez"
 #define	BLUEZ_MANAGER_INTERFACE		BLUEZ_SERVICE ".Manager"
 #define	BLUEZ_ADAPTER_INTERFACE		BLUEZ_SERVICE ".Adapter"
 #define	BLUEZ_DEVICE_INTERFACE		BLUEZ_SERVICE ".Device"
 #define	BLUEZ_SERVICE_INTERFACE		BLUEZ_SERVICE ".Service"
+#define	BLUEZ_TELEPHONY_INTERFACE	BLUEZ_SERVICE ".Telephony"
+#define	BLUEZ_TELEPHONY_AGENT_INTERFACE	BLUEZ_SERVICE ".TelephonyAgent"
 
 #define DBUS_TIMEOUT 15
 
@@ -81,3 +84,14 @@ 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,
+					const char **uuid, 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.1


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

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

[-- Attachment #1: Type: text/plain, Size: 7474 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 |  165 ++++++++++++++++++++---------------------------------
 1 files changed, 62 insertions(+), 103 deletions(-)

diff --git a/plugins/hfp_hf.c b/plugins/hfp_hf.c
index 48a734a..7c3747b 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,52 +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;
-
-	ofono_modem_remove(modem);
-
-	return dbus_message_new_method_return(msg);
-}
-
-static GDBusMethodTable agent_methods[] = {
-	{ "NewConnection", "hq", "", hfp_agent_new_connection,
-		G_DBUS_METHOD_FLAG_ASYNC },
-	{ "Release", "", "", hfp_agent_release },
-	{ NULL, NULL, NULL, NULL }
-};
-
 static int hfp_hf_probe(const char *device, const char *dev_addr,
 				const char *adapter_addr, const char *alias)
 {
@@ -295,77 +248,23 @@ 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);
@@ -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,59 @@ 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, *uuid;
+	const char *path = NULL;
+	guint16 features = 0;
+	guint16 version = 0;
+
+	fd = bluetooth_parse_newconnection_message(msg, &device, &uuid,
+						&version, &features, &path);
+	if (fd < 0)
+		return __ofono_error_invalid_args(msg);
+
+	DBG("New connection for %s on %s (version 0x%04X, features 0x%02X, " \
+					"media transport path: %s)",
+					device, uuid, 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 GDBusMethodTable agent_methods[] = {
+	{ "NewConnection", "ha{sv}", "", hfp_agent_new_connection,
+		G_DBUS_METHOD_FLAG_ASYNC },
+	{ "Release", "", "", hfp_agent_release },
+	{ NULL, NULL, NULL, NULL }
+};
+
 static struct ofono_modem_driver hfp_driver = {
 	.name		= "hfp",
 	.modem_type	= OFONO_MODEM_TYPE_HFP,
@@ -517,6 +469,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 +491,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.1


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

* [RFC v4 03/10] hfp_ag: Update to org.bluez.Telephony interface
  2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 13:17 ` [RFC v4 01/10] bluetooth: Add org.bluez.Telephony helpers =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 13:17 ` [RFC v4 02/10] hfp_hf: Update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 13:17 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 13:17 ` [RFC v4 04/10] bluetooth: Add audio APIs for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-04-06 13:17 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 5570 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 |  126 ++++++++++++++++++++++++------------------------------
 1 files changed, 56 insertions(+), 70 deletions(-)

diff --git a/plugins/hfp_ag.c b/plugins/hfp_ag.c
index c2d1d30..ea9c112 100644
--- a/plugins/hfp_ag.c
+++ b/plugins/hfp_ag.c
@@ -35,97 +35,83 @@
 
 #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, *uuid;
+	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, &uuid,
+						&version, &features, &path);
+	if (fd < 0)
+		return __ofono_error_invalid_args(msg);
 
-	if (err) {
-		DBG("%s", err->message);
-		return;
-	}
+	DBG("New connection for %s on %s (version 0x%04X, features 0x%02X, " \
+					"media transport path: %s)",
+					device, uuid, 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 GDBusMethodTable agent_methods[] = {
+	{ "NewConnection", "ha{sv}", "", hfp_ag_agent_new_connection,
+		G_DBUS_METHOD_FLAG_ASYNC },
+	{ "Release", "", "", hfp_ag_agent_release },
+	{ NULL, NULL, NULL, NULL }
+};
+
 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 +124,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 +179,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 +193,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.1


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

* [RFC v4 04/10] bluetooth: Add audio APIs for HFP AG
  2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (2 preceding siblings ...)
  2012-04-06 13:17 ` [RFC v4 03/10] hfp_ag: " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 13:17 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 17:27   ` Denis Kenzior
  2012-04-06 13:17 ` [RFC v4 05/10] bluetooth: Add AT+NREC support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-04-06 13:17 UTC (permalink / raw)
  To: ofono

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

---
 plugins/bluetooth.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h
index f81fc99..41ce112 100644
--- a/plugins/bluetooth.h
+++ b/plugins/bluetooth.h
@@ -30,6 +30,7 @@
 #define	BLUEZ_SERVICE_INTERFACE		BLUEZ_SERVICE ".Service"
 #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
 
@@ -85,6 +86,9 @@ int bluetooth_sap_client_register(struct bluetooth_sap_driver *sap,
 					struct ofono_modem *modem);
 void bluetooth_sap_client_unregister(struct ofono_modem *modem);
 
+void *bluetooth_set_audio_management(void *em, const char *path,
+							guint16 features);
+void bluetooth_free_audio_management(void *data);
 int bluetooth_parse_newconnection_message(DBusMessage *msg, const char **device,
 					const char **uuid, guint16 *version,
 					guint16 *features,
-- 
1.7.1


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

* [RFC v4 05/10] bluetooth: Add AT+NREC support
  2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (3 preceding siblings ...)
  2012-04-06 13:17 ` [RFC v4 04/10] bluetooth: Add audio APIs for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 13:17 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 17:32   ` Denis Kenzior
  2012-04-06 13:17 ` [RFC v4 06/10] bluetooth: Add +BSIR support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-04-06 13:17 UTC (permalink / raw)
  To: ofono

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

---
 plugins/bluetooth.c |  142 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 142 insertions(+), 0 deletions(-)

diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index 971e2c6..b6328bc 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -38,6 +38,7 @@
 
 #include <btio.h>
 #include "bluetooth.h"
+#include "ofono.h"
 
 static DBusConnection *connection;
 static GHashTable *uuid_hash = NULL;
@@ -73,6 +74,12 @@ struct agent {
 	guint16 features;
 };
 
+struct hfp_data {
+	struct ofono_emulator *em;
+	char *path;
+	guint16 r_features;
+};
+
 void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
 				char *buf, int size)
 {
@@ -154,6 +161,141 @@ fail:
 	return err;
 }
 
+static void audio_transport_set_property_cb(DBusPendingCall *call,
+						gpointer user_data)
+{
+	struct ofono_emulator *em = 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(em, &result);
+
+	dbus_message_unref(reply);
+}
+
+static void audio_transport_set_property(struct hfp_data *hfp, const char *name,
+						int type, const void *value)
+{
+	DBusMessage *msg;
+	DBusMessageIter iter, var;
+	const char *str_type;
+	DBusConnection *connection;
+	DBusPendingCall *c;
+
+	if (hfp->path == NULL)
+		return;
+
+	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:
+		return;
+	}
+
+	msg = dbus_message_new_method_call(BLUEZ_SERVICE, hfp->path,
+				BLUEZ_TRANSPORT_INTERFACE, "SetProperty");
+	if (msg == NULL)
+		return;
+
+	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, &c, -1)) {
+		ofono_error("Sending SetProperty failed");
+		goto fail;
+	}
+
+	dbus_pending_call_set_notify(c, audio_transport_set_property_cb,
+								hfp->em, NULL);
+	dbus_pending_call_unref(c);
+
+fail:
+	dbus_message_unref(msg);
+}
+
+static void emulator_nrec_cb(struct ofono_emulator *em,
+			struct ofono_emulator_request *req, void *userdata)
+{
+	struct hfp_data *hfp = 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(hfp, "NREC", DBUS_TYPE_BOOLEAN,
+									&val);
+		break;
+
+	default:
+fail:
+		result.error = 0;
+		result.type = OFONO_ERROR_TYPE_FAILURE;
+		ofono_emulator_send_final(em, &result);
+	};
+}
+
+void bluetooth_free_audio_management(void *data)
+{
+	struct hfp_data *hfp = data;
+
+	DBG("");
+
+	ofono_emulator_remove_handler(hfp->em, "+NREC");
+
+	g_free(hfp->path);
+	g_free(hfp);
+}
+
+void *bluetooth_set_audio_management(void *em, const char *path,
+							guint16 features)
+{
+	struct hfp_data *hfp;
+
+	DBG("");
+
+	hfp = g_new0(struct hfp_data, 1);
+	hfp->em = em;
+	hfp->path = g_strdup(path);
+	hfp->r_features = features;
+
+	ofono_emulator_add_handler(em, "+NREC", emulator_nrec_cb, hfp, NULL);
+
+	return hfp;
+}
+
 static void register_telephony_agent(const char *path, const char *handle,
 						struct agent *agent)
 {
-- 
1.7.1


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

* [RFC v4 06/10] bluetooth: Add +BSIR support
  2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (4 preceding siblings ...)
  2012-04-06 13:17 ` [RFC v4 05/10] bluetooth: Add AT+NREC support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 13:17 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 13:17 ` [RFC v4 07/10] bluetooth: Add AT+VGM support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-04-06 13:17 UTC (permalink / raw)
  To: ofono

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

---
 plugins/bluetooth.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index b6328bc..b90852d 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -78,6 +78,7 @@ struct hfp_data {
 	struct ofono_emulator *em;
 	char *path;
 	guint16 r_features;
+	guint watch;
 };
 
 void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
@@ -267,6 +268,46 @@ fail:
 	};
 }
 
+static gboolean audio_property_changed(DBusConnection *connection,
+					DBusMessage *message, void *user_data)
+{
+	struct hfp_data *hfp = 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(hfp->em, buf);
+	}
+
+	return TRUE;
+}
+
 void bluetooth_free_audio_management(void *data)
 {
 	struct hfp_data *hfp = data;
@@ -275,6 +316,8 @@ void bluetooth_free_audio_management(void *data)
 
 	ofono_emulator_remove_handler(hfp->em, "+NREC");
 
+	g_dbus_remove_watch(connection, hfp->watch);
+
 	g_free(hfp->path);
 	g_free(hfp);
 }
@@ -293,6 +336,12 @@ void *bluetooth_set_audio_management(void *em, const char *path,
 
 	ofono_emulator_add_handler(em, "+NREC", emulator_nrec_cb, hfp, NULL);
 
+	hfp->watch = g_dbus_add_signal_watch(connection, NULL, path,
+						BLUEZ_TRANSPORT_INTERFACE,
+						"PropertyChanged",
+						audio_property_changed,
+						hfp, NULL);
+
 	return hfp;
 }
 
-- 
1.7.1


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

* [RFC v4 07/10] bluetooth: Add AT+VGM support
  2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (5 preceding siblings ...)
  2012-04-06 13:17 ` [RFC v4 06/10] bluetooth: Add +BSIR support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 13:17 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 13:17 ` [RFC v4 08/10] bluetooth: Add AT+VGS support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-04-06 13:17 UTC (permalink / raw)
  To: ofono

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

---
 plugins/bluetooth.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index b90852d..3560440 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -79,6 +79,8 @@ struct hfp_data {
 	char *path;
 	guint16 r_features;
 	guint watch;
+	int mic_gain;
+	int mic_pending;
 };
 
 void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
@@ -268,6 +270,37 @@ fail:
 	};
 }
 
+static void emulator_vgm_cb(struct ofono_emulator *em,
+			struct ofono_emulator_request *req, void *userdata)
+{
+	struct hfp_data *hfp = 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 > 15)
+			goto fail;
+
+		if (hfp->mic_pending != -1)
+			ofono_error("Receiving AT+VGM while processing one");
+
+		hfp->mic_pending = val;
+		audio_transport_set_property(hfp, "MicrophoneGain",
+							DBUS_TYPE_UINT16, &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)
 {
@@ -303,6 +336,41 @@ static gboolean audio_property_changed(DBusConnection *connection,
 
 		sprintf(buf, "+BSIR: %d", value);
 		ofono_emulator_send_unsolicited(hfp->em, buf);
+	} else if (g_str_equal(property, "MicrophoneGain") == TRUE) {
+		DBusMessageIter variant;
+		int value;
+
+		if (!(hfp->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, &value);
+
+		/* 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 (hfp->mic_pending != value && hfp->mic_gain != value) {
+			sprintf(buf, "+VGM: %d", value);
+			ofono_emulator_send_unsolicited(hfp->em, buf);
+			hfp->mic_pending = -1;
+		} else if (hfp->mic_pending == value)
+			hfp->mic_pending = -1;
+		hfp->mic_gain = value;
 	}
 
 	return TRUE;
@@ -315,6 +383,7 @@ void bluetooth_free_audio_management(void *data)
 	DBG("");
 
 	ofono_emulator_remove_handler(hfp->em, "+NREC");
+	ofono_emulator_remove_handler(hfp->em, "+VGM");
 
 	g_dbus_remove_watch(connection, hfp->watch);
 
@@ -333,8 +402,10 @@ void *bluetooth_set_audio_management(void *em, const char *path,
 	hfp->em = em;
 	hfp->path = g_strdup(path);
 	hfp->r_features = features;
+	hfp->mic_pending = -1;
 
 	ofono_emulator_add_handler(em, "+NREC", emulator_nrec_cb, hfp, NULL);
+	ofono_emulator_add_handler(em, "+VGM", emulator_vgm_cb, hfp, NULL);
 
 	hfp->watch = g_dbus_add_signal_watch(connection, NULL, path,
 						BLUEZ_TRANSPORT_INTERFACE,
-- 
1.7.1


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

* [RFC v4 08/10] bluetooth: Add AT+VGS support
  2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (6 preceding siblings ...)
  2012-04-06 13:17 ` [RFC v4 07/10] bluetooth: Add AT+VGM support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 13:17 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 13:17 ` [RFC v4 09/10] hfp_ag: Add media transport support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 13:17 ` [RFC v4 10/10] emulator: Update supported features =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  9 siblings, 0 replies; 19+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-04-06 13:17 UTC (permalink / raw)
  To: ofono

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

---
 plugins/bluetooth.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index 3560440..107c197 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -81,6 +81,8 @@ struct hfp_data {
 	guint watch;
 	int mic_gain;
 	int mic_pending;
+	int sp_gain;
+	int sp_pending;
 };
 
 void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
@@ -301,6 +303,37 @@ fail:
 	};
 }
 
+static void emulator_vgs_cb(struct ofono_emulator *em,
+		struct ofono_emulator_request *req, void *userdata)
+{
+	struct hfp_data *hfp = 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 > 15)
+			goto fail;
+
+		if (hfp->sp_pending != -1)
+			ofono_error("Receiving AT+VGS while processing one");
+
+		hfp->sp_pending = val;
+		audio_transport_set_property(hfp, "SpeakerGain",
+							DBUS_TYPE_UINT16, &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)
 {
@@ -371,6 +404,41 @@ static gboolean audio_property_changed(DBusConnection *connection,
 		} else if (hfp->mic_pending == value)
 			hfp->mic_pending = -1;
 		hfp->mic_gain = value;
+	} else if (g_str_equal(property, "SpeakerGain") == TRUE) {
+		DBusMessageIter variant;
+		int value;
+
+		if (!(hfp->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, &value);
+
+		/* 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 (hfp->sp_pending != value && hfp->sp_gain != value) {
+			sprintf(buf, "+VGS: %d", value);
+			ofono_emulator_send_unsolicited(hfp->em, buf);
+			hfp->sp_pending = -1;
+		} else if (hfp->sp_pending == value)
+			hfp->sp_pending = -1;
+		hfp->sp_gain = value;
 	}
 
 	return TRUE;
@@ -384,6 +452,7 @@ void bluetooth_free_audio_management(void *data)
 
 	ofono_emulator_remove_handler(hfp->em, "+NREC");
 	ofono_emulator_remove_handler(hfp->em, "+VGM");
+	ofono_emulator_remove_handler(hfp->em, "+VGS");
 
 	g_dbus_remove_watch(connection, hfp->watch);
 
@@ -403,9 +472,11 @@ void *bluetooth_set_audio_management(void *em, const char *path,
 	hfp->path = g_strdup(path);
 	hfp->r_features = features;
 	hfp->mic_pending = -1;
+	hfp->sp_pending = -1;
 
 	ofono_emulator_add_handler(em, "+NREC", emulator_nrec_cb, hfp, NULL);
 	ofono_emulator_add_handler(em, "+VGM", emulator_vgm_cb, hfp, NULL);
+	ofono_emulator_add_handler(em, "+VGS", emulator_vgs_cb, hfp, NULL);
 
 	hfp->watch = g_dbus_add_signal_watch(connection, NULL, path,
 						BLUEZ_TRANSPORT_INTERFACE,
-- 
1.7.1


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

* [RFC v4 09/10] hfp_ag: Add media transport support
  2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (7 preceding siblings ...)
  2012-04-06 13:17 ` [RFC v4 08/10] bluetooth: Add AT+VGS support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 13:17 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 17:38   ` Denis Kenzior
  2012-04-06 13:17 ` [RFC v4 10/10] emulator: Update supported features =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  9 siblings, 1 reply; 19+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-04-06 13:17 UTC (permalink / raw)
  To: ofono

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

---
 plugins/hfp_ag.c |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/plugins/hfp_ag.c b/plugins/hfp_ag.c
index ea9c112..8500bff 100644
--- a/plugins/hfp_ag.c
+++ b/plugins/hfp_ag.c
@@ -37,7 +37,9 @@
 
 #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_IN_BAND_RING_TONE | \
+			HFP_AG_FEATURE_REJECT_CALL | \
 			HFP_AG_FEATURE_ENHANCED_CALL_STATUS | \
 			HFP_AG_FEATURE_ENHANCED_CALL_CONTROL | \
 			HFP_AG_FEATURE_EXTENDED_RES_CODE)
@@ -50,6 +52,13 @@ static guint modemwatch_id;
 static GList *modems;
 static GHashTable *sim_hash = NULL;
 
+static gboolean client_event(GIOChannel *chan, GIOCondition cond, gpointer data)
+{
+	bluetooth_free_audio_management(data);
+
+	return FALSE;
+}
+
 static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
 						DBusMessage *msg, void *data)
 {
@@ -60,6 +69,8 @@ static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
 	guint16 features = 0;
 	struct ofono_emulator *em;
 	struct ofono_modem *modem;
+	void *audio;
+	GIOChannel *io;
 
 	fd = bluetooth_parse_newconnection_message(msg, &device, &uuid,
 						&version, &features, &path);
@@ -82,6 +93,12 @@ static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
 		return __ofono_error_failed(msg);
 
 	ofono_emulator_register(em, fd);
+	audio = bluetooth_set_audio_management(em, path, features);
+
+	io = g_io_channel_unix_new(fd);
+	g_io_add_watch_full(io, G_PRIORITY_HIGH,
+				G_IO_HUP | G_IO_ERR | G_IO_NVAL, client_event,
+				audio, NULL);
 
 	return dbus_message_new_method_return(msg);
 }
-- 
1.7.1


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

* [RFC v4 10/10] emulator: Update supported features
  2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
                   ` (8 preceding siblings ...)
  2012-04-06 13:17 ` [RFC v4 09/10] hfp_ag: Add media transport support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 13:17 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
  2012-04-06 17:38   ` Denis Kenzior
  9 siblings, 1 reply; 19+ messages in thread
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis @ 2012-04-06 13:17 UTC (permalink / raw)
  To: ofono

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

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

diff --git a/src/emulator.c b/src/emulator.c
index e7c7d41..371e96c 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -979,6 +979,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.1


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

* Re: [RFC v4 04/10] bluetooth: Add audio APIs for HFP AG
  2012-04-06 13:17 ` [RFC v4 04/10] bluetooth: Add audio APIs for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 17:27   ` Denis Kenzior
  0 siblings, 0 replies; 19+ messages in thread
From: Denis Kenzior @ 2012-04-06 17:27 UTC (permalink / raw)
  To: ofono

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

Hi Frédéric,

On 04/06/2012 08:17 AM, Frédéric Danis wrote:
> ---
>  plugins/bluetooth.h |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h
> index f81fc99..41ce112 100644
> --- a/plugins/bluetooth.h
> +++ b/plugins/bluetooth.h
> @@ -30,6 +30,7 @@
>  #define	BLUEZ_SERVICE_INTERFACE		BLUEZ_SERVICE ".Service"
>  #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
>  
> @@ -85,6 +86,9 @@ int bluetooth_sap_client_register(struct bluetooth_sap_driver *sap,
>  					struct ofono_modem *modem);
>  void bluetooth_sap_client_unregister(struct ofono_modem *modem);
>  
> +void *bluetooth_set_audio_management(void *em, const char *path,
> +							guint16 features);
> +void bluetooth_free_audio_management(void *data);

I don't like passing around void pointers.  We should either try to
avoid this altogether or forward declare the struct.

>  int bluetooth_parse_newconnection_message(DBusMessage *msg, const char **device,
>  					const char **uuid, guint16 *version,
>  					guint16 *features,

Regards,
-Denis

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

* Re: [RFC v4 05/10] bluetooth: Add AT+NREC support
  2012-04-06 13:17 ` [RFC v4 05/10] bluetooth: Add AT+NREC support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 17:32   ` Denis Kenzior
  0 siblings, 0 replies; 19+ messages in thread
From: Denis Kenzior @ 2012-04-06 17:32 UTC (permalink / raw)
  To: ofono

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

Hi Frédéric,

On 04/06/2012 08:17 AM, Frédéric Danis wrote:
> ---
>  plugins/bluetooth.c |  142 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 142 insertions(+), 0 deletions(-)
> 
> diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
> index 971e2c6..b6328bc 100644
> --- a/plugins/bluetooth.c
> +++ b/plugins/bluetooth.c
> @@ -38,6 +38,7 @@
>  
>  #include <btio.h>
>  #include "bluetooth.h"
> +#include "ofono.h"

Why do you need ofono.h?

>  
>  static DBusConnection *connection;
>  static GHashTable *uuid_hash = NULL;
> @@ -73,6 +74,12 @@ struct agent {
>  	guint16 features;
>  };
>  
> +struct hfp_data {
> +	struct ofono_emulator *em;
> +	char *path;
> +	guint16 r_features;
> +};
> +
>  void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
>  				char *buf, int size)
>  {
> @@ -154,6 +161,141 @@ fail:
>  	return err;
>  }
>  
> +static void audio_transport_set_property_cb(DBusPendingCall *call,
> +						gpointer user_data)
> +{
> +	struct ofono_emulator *em = 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(em, &result);
> +
> +	dbus_message_unref(reply);
> +}
> +
> +static void audio_transport_set_property(struct hfp_data *hfp, const char *name,
> +						int type, const void *value)
> +{
> +	DBusMessage *msg;
> +	DBusMessageIter iter, var;
> +	const char *str_type;
> +	DBusConnection *connection;
> +	DBusPendingCall *c;
> +
> +	if (hfp->path == NULL)
> +		return;
> +
> +	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:
> +		return;
> +	}
> +
> +	msg = dbus_message_new_method_call(BLUEZ_SERVICE, hfp->path,
> +				BLUEZ_TRANSPORT_INTERFACE, "SetProperty");
> +	if (msg == NULL)
> +		return;
> +
> +	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, &c, -1)) {
> +		ofono_error("Sending SetProperty failed");
> +		goto fail;
> +	}
> +
> +	dbus_pending_call_set_notify(c, audio_transport_set_property_cb,
> +								hfp->em, NULL);

So what happens if the emulator is removed during a pending call? E.g.
by the modem being powered down.

> +	dbus_pending_call_unref(c);
> +
> +fail:
> +	dbus_message_unref(msg);
> +}
> +
> +static void emulator_nrec_cb(struct ofono_emulator *em,
> +			struct ofono_emulator_request *req, void *userdata)
> +{
> +	struct hfp_data *hfp = 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(hfp, "NREC", DBUS_TYPE_BOOLEAN,
> +									&val);
> +		break;
> +
> +	default:
> +fail:
> +		result.error = 0;
> +		result.type = OFONO_ERROR_TYPE_FAILURE;
> +		ofono_emulator_send_final(em, &result);
> +	};
> +}
> +
> +void bluetooth_free_audio_management(void *data)
> +{
> +	struct hfp_data *hfp = data;
> +
> +	DBG("");
> +
> +	ofono_emulator_remove_handler(hfp->em, "+NREC");

Do you really need to do this?

> +
> +	g_free(hfp->path);
> +	g_free(hfp);
> +}
> +
> +void *bluetooth_set_audio_management(void *em, const char *path,
> +							guint16 features)
> +{
> +	struct hfp_data *hfp;
> +
> +	DBG("");
> +
> +	hfp = g_new0(struct hfp_data, 1);
> +	hfp->em = em;
> +	hfp->path = g_strdup(path);
> +	hfp->r_features = features;
> +
> +	ofono_emulator_add_handler(em, "+NREC", emulator_nrec_cb, hfp, NULL);
> +
> +	return hfp;
> +}
> +
>  static void register_telephony_agent(const char *path, const char *handle,
>  						struct agent *agent)
>  {

Regards,
-Denis

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

* Re: [RFC v4 09/10] hfp_ag: Add media transport support
  2012-04-06 13:17 ` [RFC v4 09/10] hfp_ag: Add media transport support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 17:38   ` Denis Kenzior
  2012-04-24 16:19     ` Frederic Danis
  0 siblings, 1 reply; 19+ messages in thread
From: Denis Kenzior @ 2012-04-06 17:38 UTC (permalink / raw)
  To: ofono

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

Hi Frédéric,

> @@ -82,6 +93,12 @@ static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
>  		return __ofono_error_failed(msg);
>  
>  	ofono_emulator_register(em, fd);
> +	audio = bluetooth_set_audio_management(em, path, features);
> +
> +	io = g_io_channel_unix_new(fd);
> +	g_io_add_watch_full(io, G_PRIORITY_HIGH,
> +				G_IO_HUP | G_IO_ERR | G_IO_NVAL, client_event,
> +				audio, NULL);

It might be better to register to atom removal rather than an IO watch.

>  
>  	return dbus_message_new_method_return(msg);
>  }

Regards,
-Denis

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

* Re: [RFC v4 10/10] emulator: Update supported features
  2012-04-06 13:17 ` [RFC v4 10/10] emulator: Update supported features =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
@ 2012-04-06 17:38   ` Denis Kenzior
  2012-04-23 14:01     ` Frederic Danis
  0 siblings, 1 reply; 19+ messages in thread
From: Denis Kenzior @ 2012-04-06 17:38 UTC (permalink / raw)
  To: ofono

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

Hi Frédéric,

On 04/06/2012 08:17 AM, Frédéric Danis wrote:
> Add ECNR (Echo Cancelation/Noise Reduction) and Inband Ringtone
> capabilities to supported features (+BRSF event)
> ---
>  src/emulator.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/src/emulator.c b/src/emulator.c
> index e7c7d41..371e96c 100644
> --- a/src/emulator.c
> +++ b/src/emulator.c
> @@ -979,6 +979,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;

I think it would be better for the features to be modified based on what
command handlers are registered.  E.g. if NREC handler is registered in
ofono_emulator_add_handler then add ECNR to local features, etc.

Regards,
-Denis


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

* Re: [RFC v4 10/10] emulator: Update supported features
  2012-04-23 14:01     ` Frederic Danis
@ 2012-04-23  0:03       ` Denis Kenzior
  0 siblings, 0 replies; 19+ messages in thread
From: Denis Kenzior @ 2012-04-23  0:03 UTC (permalink / raw)
  To: ofono

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

Hi Frederic,

>> I think it would be better for the features to be modified based on what
>> command handlers are registered.  E.g. if NREC handler is registered in
>> ofono_emulator_add_handler then add ECNR to local features, etc.
> 
> Local features are sent during reply to AT+BRSF command (after emulator
> creation and command handlers registration), but also in the Bluetooth
> SDP record, before client connection (so before emulator creation).
> 

Fair enough, however the SDP record is not a 1:1 mapping to BRSF, only a
subset is covered.

> Imho, local features value should only be created in hfp_ag.c file, and
> passed to the emulator through ofono_emulator_create() or a new
> ofono_emulator_set_features() API.

The thing is that the plugin has no knowledge of whether 3WAY, enhanced
call status, enhanced call control, etc are supported.  Right now these
are hard-coded, but they might depend on driver / technology.  So at
best the emulator_create would be a mask to be ORed onto the local
features set from the core.

In the end I'm fine either way, but it might be easier to avoid the
extra step in the plugin if the core can do this easily just based on
the command handlers being registered.

Regards,
-Denis

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

* Re: [RFC v4 10/10] emulator: Update supported features
  2012-04-06 17:38   ` Denis Kenzior
@ 2012-04-23 14:01     ` Frederic Danis
  2012-04-23  0:03       ` Denis Kenzior
  0 siblings, 1 reply; 19+ messages in thread
From: Frederic Danis @ 2012-04-23 14:01 UTC (permalink / raw)
  To: ofono

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

Hello Denis,

Le 06/04/2012 19:38, Denis Kenzior a écrit :
> Hi Frédéric,
>
> On 04/06/2012 08:17 AM, Frédéric Danis wrote:
>> Add ECNR (Echo Cancelation/Noise Reduction) and Inband Ringtone
>> capabilities to supported features (+BRSF event)
>> ---
>>   src/emulator.c |    2 ++
>>   1 files changed, 2 insertions(+), 0 deletions(-)
>>
>> diff --git a/src/emulator.c b/src/emulator.c
>> index e7c7d41..371e96c 100644
>> --- a/src/emulator.c
>> +++ b/src/emulator.c
>> @@ -979,6 +979,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;
>
> I think it would be better for the features to be modified based on what
> command handlers are registered.  E.g. if NREC handler is registered in
> ofono_emulator_add_handler then add ECNR to local features, etc.

Local features are sent during reply to AT+BRSF command (after emulator 
creation and command handlers registration), but also in the Bluetooth 
SDP record, before client connection (so before emulator creation).

Imho, local features value should only be created in hfp_ag.c file, and 
passed to the emulator through ofono_emulator_create() or a new 
ofono_emulator_set_features() API.

Regards,

Fred

-- 
Frederic Danis                            Open Source Technology Center
frederic.danis(a)intel.com                              Intel Corporation


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

* Re: [RFC v4 09/10] hfp_ag: Add media transport support
  2012-04-24 16:19     ` Frederic Danis
@ 2012-04-23 19:24       ` Denis Kenzior
  0 siblings, 0 replies; 19+ messages in thread
From: Denis Kenzior @ 2012-04-23 19:24 UTC (permalink / raw)
  To: ofono

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

Hi Frederic,

On 04/24/2012 11:19 AM, Frederic Danis wrote:
> Hello Denis,
> 
> Le 06/04/2012 19:38, Denis Kenzior a écrit :
>> Hi Frédéric,
>>
>>> @@ -82,6 +93,12 @@ static DBusMessage
>>> *hfp_ag_agent_new_connection(DBusConnection *conn,
>>>           return __ofono_error_failed(msg);
>>>
>>>       ofono_emulator_register(em, fd);
>>> +    audio = bluetooth_set_audio_management(em, path, features);
>>> +
>>> +    io = g_io_channel_unix_new(fd);
>>> +    g_io_add_watch_full(io, G_PRIORITY_HIGH,
>>> +                G_IO_HUP | G_IO_ERR | G_IO_NVAL, client_event,
>>> +                audio, NULL);
>>
>> It might be better to register to atom removal rather than an IO watch.
> 
> As modem can have multiple emulator atoms (in case of connection to
> multiple headsets), I do not think that registering for atom removal
> using __ofono_modem_add_atom_watch() will be OK.

Not sure I'm following, the core will still fire the atom watch for each
and every atom, even if there are multiple of the same type.  So the
worst case you might need a hashtable to map between atoms and your own
data structure.

> 
> I may add an API to emulator to register a disconnection callback:
>     ofono_emulator_set_disconnect_cb(em, cb, cb_data)

And maybe ofono_emulator_set/get_data might be even easier and more
flexible.

Regards,
-Denis

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

* Re: [RFC v4 09/10] hfp_ag: Add media transport support
  2012-04-06 17:38   ` Denis Kenzior
@ 2012-04-24 16:19     ` Frederic Danis
  2012-04-23 19:24       ` Denis Kenzior
  0 siblings, 1 reply; 19+ messages in thread
From: Frederic Danis @ 2012-04-24 16:19 UTC (permalink / raw)
  To: ofono

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

Hello Denis,

Le 06/04/2012 19:38, Denis Kenzior a écrit :
> Hi Frédéric,
>
>> @@ -82,6 +93,12 @@ static DBusMessage *hfp_ag_agent_new_connection(DBusConnection *conn,
>>   		return __ofono_error_failed(msg);
>>
>>   	ofono_emulator_register(em, fd);
>> +	audio = bluetooth_set_audio_management(em, path, features);
>> +
>> +	io = g_io_channel_unix_new(fd);
>> +	g_io_add_watch_full(io, G_PRIORITY_HIGH,
>> +				G_IO_HUP | G_IO_ERR | G_IO_NVAL, client_event,
>> +				audio, NULL);
>
> It might be better to register to atom removal rather than an IO watch.

As modem can have multiple emulator atoms (in case of connection to 
multiple headsets), I do not think that registering for atom removal 
using __ofono_modem_add_atom_watch() will be OK.

I may add an API to emulator to register a disconnection callback:
     ofono_emulator_set_disconnect_cb(em, cb, cb_data)

This keep separation between oFono core and HFP AG plug-in.

Regards

Fred

-- 
Frederic Danis                            Open Source Technology Center
frederic.danis(a)intel.com                              Intel Corporation


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

end of thread, other threads:[~2012-04-24 16:19 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 01/10] bluetooth: Add org.bluez.Telephony helpers =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 02/10] hfp_hf: Update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 03/10] hfp_ag: " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 04/10] bluetooth: Add audio APIs for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 17:27   ` Denis Kenzior
2012-04-06 13:17 ` [RFC v4 05/10] bluetooth: Add AT+NREC support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 17:32   ` Denis Kenzior
2012-04-06 13:17 ` [RFC v4 06/10] bluetooth: Add +BSIR support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 07/10] bluetooth: Add AT+VGM support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 08/10] bluetooth: Add AT+VGS support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 09/10] hfp_ag: Add media transport support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 17:38   ` Denis Kenzior
2012-04-24 16:19     ` Frederic Danis
2012-04-23 19:24       ` Denis Kenzior
2012-04-06 13:17 ` [RFC v4 10/10] emulator: Update supported features =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 17:38   ` Denis Kenzior
2012-04-23 14:01     ` Frederic Danis
2012-04-23  0:03       ` Denis Kenzior

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.