All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Handsfree profile plugins update
@ 2009-10-19 14:41 Zhang, Zhenhua
  2009-10-19 22:12 ` Denis Kenzior
  0 siblings, 1 reply; 2+ messages in thread
From: Zhang, Zhenhua @ 2009-10-19 14:41 UTC (permalink / raw)
  To: ofono

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

Hi,

Attached is update patch for handsfree profile plugin. I move most stuff in 
drivers/hfpmodem/hfp.c into plugins/hfp.c and simplify them. GSList *indies
is replaced as two indexable arrays (cind_names and cind_values), to improve
efficiency when we need access name and value by index. The whole logic is
the same comparing with previous patch.

Thanks for Denis and Gustavo for comments. Please review it.

Regards,
Zhenhua
 

[-- Attachment #2: 0001-handsfree-profile-plugin-update.patch --]
[-- Type: application/octet-stream, Size: 12783 bytes --]

From 68fef17d1918abf01ca6dc7a9bd5eb395cb21ddf Mon Sep 17 00:00:00 2001
From: Zhenhua Zhang <zhenhua.zhang@intel.com>
Date: Mon, 19 Oct 2009 06:20:25 +0800
Subject: [PATCH] handsfree profile plugin update

---
 Makefile.am            |    8 +
 drivers/hfpmodem/hfp.c |   53 ++++++++
 drivers/hfpmodem/hfp.h |   48 +++++++
 plugins/hfp.c          |  332 ++++++++++++++++++++++++++++++++++++++++++++++++
 plugins/modemconf.c    |    3 +-
 5 files changed, 443 insertions(+), 1 deletions(-)
 create mode 100644 drivers/hfpmodem/hfp.c
 create mode 100644 drivers/hfpmodem/hfp.h
 create mode 100644 plugins/hfp.c

diff --git a/Makefile.am b/Makefile.am
index cf84bf7..94b48dd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -116,6 +116,11 @@ builtin_sources += drivers/atmodem/atutil.h \
 			drivers/calypsomodem/calypsomodem.c \
 			drivers/calypsomodem/voicecall.c
 
+builtin_modules += hfpmodem
+builtin_sources += drivers/atmodem/atutil.h \
+			drivers/hfpmodem/hfp.h \
+			drivers/hfpmodem/hfp.c
+
 builtin_modules += modemconf
 builtin_sources += plugins/modemconf.c
 
@@ -146,6 +151,9 @@ builtin_sources += plugins/huawei.c
 
 builtin_modules += novatel
 builtin_sources += plugins/novatel.c
+
+builtin_modules += hfp
+builtin_sources += plugins/hfp.c
 endif
 
 if MAINTAINER_MODE
diff --git a/drivers/hfpmodem/hfp.c b/drivers/hfpmodem/hfp.c
new file mode 100644
index 0000000..fa59aa9
--- /dev/null
+++ b/drivers/hfpmodem/hfp.c
@@ -0,0 +1,53 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2008-2009  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/plugin.h>
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <dbus.h>
+
+#include <gatchat.h>
+#include <gatresult.h>
+
+#include "hfp.h"
+
+static int hfpmodem_init(void)
+{
+	return 0;
+}
+
+static void hfpmodem_exit(void)
+{
+}
+
+OFONO_PLUGIN_DEFINE(hfpmodem, "Hands-Free Profile Driver", VERSION,
+		OFONO_PLUGIN_PRIORITY_DEFAULT, hfpmodem_init, hfpmodem_exit)
diff --git a/drivers/hfpmodem/hfp.h b/drivers/hfpmodem/hfp.h
new file mode 100644
index 0000000..831dd5e
--- /dev/null
+++ b/drivers/hfpmodem/hfp.h
@@ -0,0 +1,48 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2008-2009  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+#ifndef __BLUETOOTH_H__
+#define __BLUETOOTH_H__
+
+#include <drivers/atmodem/atutil.h>
+
+/* AG supported features bitmap. Bluetooth HFP 1.5 spec page 77 */
+#define AG_FEATURE_3WAY 0x1
+#define AG_FEATURE_ECNR 0x2
+#define AG_FEATURE_VOICE_RECOG 0x4
+#define AG_FEATURE_IN_BAND_RING_TONE 0x8
+#define AG_FEATURE_ATTACH_VOICE_TAG 0x10
+#define AG_FEATURE_REJECT_CALL 0x20
+#define AG_FEATURE_ENHANCED_CALL_STATUS 0x40
+#define AG_FEATURE_ENHANCED_CALL_CONTROL 0x80
+#define AG_FEATURE_EXTENDED_RES_CODE 0x100
+
+struct hfp_data {
+	GAtChat *chat;
+	int ag_features;
+	char **cind_names;
+	int *cind_values;
+	int cind_length;
+};
+
+extern void hfp_voicecall_init();
+extern void hfp_voicecall_exit();
+
+#endif
diff --git a/plugins/hfp.c b/plugins/hfp.c
new file mode 100644
index 0000000..8961b66
--- /dev/null
+++ b/plugins/hfp.c
@@ -0,0 +1,332 @@
+/*
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2008-2009  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2009  Collabora Ltd. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <glib.h>
+#include <gatchat.h>
+#include <gattty.h>
+#include <dbus.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/plugin.h>
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/call-barring.h>
+#include <ofono/call-forwarding.h>
+#include <ofono/call-meter.h>
+#include <ofono/call-settings.h>
+#include <ofono/devinfo.h>
+#include <ofono/message-waiting.h>
+#include <ofono/netreg.h>
+#include <ofono/phonebook.h>
+#include <ofono/sim.h>
+#include <ofono/sms.h>
+#include <ofono/ssn.h>
+#include <ofono/ussd.h>
+#include <ofono/voicecall.h>
+
+#include <drivers/hfpmodem/hfp.h>
+
+static const char *brsf_prefix[] = { "+BRSF:", NULL };
+static const char *cind_prefix[] = { "+CIND:", NULL };
+static const char *cmer_prefix[] = { "+CMER:", NULL };
+
+static int hfp_disable(struct ofono_modem *modem);
+
+static void hfp_debug(const char *str, void *user_data)
+{
+	ofono_info("%s", str);
+}
+
+static void cind_status_cb(gboolean ok, GAtResult *result,
+				gpointer user_data)
+{
+	struct ofono_modem *modem = user_data;
+	struct hfp_data *data = ofono_modem_get_data(modem);
+	GAtResultIter iter;
+	int index = 0, value = 0;
+
+	if (!ok)
+		goto error;
+
+	g_at_result_iter_init(&iter, result);
+
+	if (!g_at_result_iter_next(&iter, "+CIND:"))
+		goto error;
+
+	while (g_at_result_iter_next_number(&iter, &value))
+		data->cind_values[++index] = value;
+
+	ofono_info("Service level connection established");
+	g_at_chat_send(data->chat, "AT+CMEE=1", NULL, NULL, NULL, NULL);
+
+	ofono_modem_set_powered(modem, TRUE);
+	return;
+
+error:
+	hfp_disable(modem);
+}
+
+static void cmer_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct ofono_modem *modem = user_data;
+	struct hfp_data *data = ofono_modem_get_data(modem);
+
+	if (!ok) {
+		hfp_disable(modem);
+		return;
+	}
+
+	g_at_chat_send(data->chat, "AT+CIND?", cind_prefix,
+			cind_status_cb, modem, NULL);
+}
+
+static void set_cind_data(GSList *l, struct hfp_data *data)
+{
+	int len = g_slist_length(l);
+	int i = 0;
+
+	data->cind_names = g_new0(char *, len + 1);
+	data->cind_values = g_new0(int, len + 1);
+	data->cind_length = len;
+
+	data->cind_names[0] = NULL;
+	for (; l; l = l->next)
+		data->cind_names[++i] = g_strdup(l->data);
+}
+
+static void cind_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct ofono_modem *modem = user_data;
+	struct hfp_data *data = ofono_modem_get_data(modem);
+	GSList *l = NULL;
+	GAtResultIter iter;
+	const char *str;
+	int min, max;
+
+	if (!ok)
+		goto error;
+
+	g_at_result_iter_init(&iter, result);
+	if (!g_at_result_iter_next(&iter, "+CIND:"))
+		goto error;
+
+	while (g_at_result_iter_open_list(&iter)) {
+		if (!g_at_result_iter_next_string(&iter, &str))
+			goto error;
+
+		l = g_slist_append(l, (gpointer)g_strdup(str));
+
+		if (!g_at_result_iter_open_list(&iter))
+			goto error;
+
+		while (g_at_result_iter_next_range(&iter, &min, &max))
+			;
+
+		if (!g_at_result_iter_close_list(&iter))
+			goto error;
+
+		if (!g_at_result_iter_close_list(&iter))
+			goto error;
+	}
+
+	set_cind_data(l, data);
+	g_slist_foreach(l, (GFunc) g_free, 0);
+	g_slist_free(l);
+
+	g_at_chat_send(data->chat, "AT+CMER=3,0,0,1", cmer_prefix,
+				cmer_cb, modem, NULL);
+	return;
+
+error:
+	hfp_disable(modem);
+}
+
+static void brsf_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+	struct ofono_modem *modem = user_data;
+	struct hfp_data *data = ofono_modem_get_data(modem);
+	GAtResultIter iter;
+
+	if (!ok)
+		goto error;
+
+	g_at_result_iter_init(&iter, result);
+
+	if (!g_at_result_iter_next(&iter, "+BRSF:"))
+		goto error;
+
+	g_at_result_iter_next_number(&iter, &data->ag_features);
+
+	g_at_chat_send(data->chat, "AT+CIND=?", cind_prefix,
+				cind_cb, modem, NULL);
+	return;
+
+error:
+	hfp_disable(modem);
+}
+
+/* either oFono or Phone could request SLC connection */
+static int service_level_connection(struct ofono_modem *modem,
+				const char *tty)
+{
+	struct hfp_data *data = ofono_modem_get_data(modem);
+	GIOChannel *io;
+	GAtSyntax *syntax;
+	GAtChat *chat;
+
+	io = g_at_tty_open(tty, NULL);
+	if (!io) {
+		ofono_error("Service level connection failed: %s (%d)",
+			strerror(errno), errno);
+		return -EIO;
+	}
+
+	syntax = g_at_syntax_new_gsmv1();
+	chat = g_at_chat_new(io, syntax);
+	g_at_syntax_unref(syntax);
+	g_io_channel_unref(io);
+
+	if (!chat)
+		return -ENOMEM;
+
+	if (getenv("OFONO_AT_DEBUG"))
+		g_at_chat_set_debug(chat, hfp_debug, NULL);
+
+	/* 118 = 0x76, support multiparty calling, enhanced call status
+	* and enhanced call control */
+	g_at_chat_send(chat, "AT+BRSF=118", brsf_prefix,
+				brsf_cb, modem, NULL);
+	data->chat = chat;
+
+	return -EINPROGRESS;
+}
+
+static int hfp_probe(struct ofono_modem *modem)
+{
+	struct hfp_data *data;
+
+	data = g_try_new0(struct hfp_data, 1);
+	if (!data)
+		return -ENOMEM;
+
+	ofono_modem_set_data(modem, data);
+
+	return 0;
+}
+
+static void hfp_remove(struct ofono_modem *modem)
+{
+	gpointer data = ofono_modem_get_data(modem);
+
+	if (data)
+		g_free(data);
+
+	ofono_modem_set_data(modem, NULL);
+}
+
+/* power up hardware */
+static int hfp_enable(struct ofono_modem *modem)
+{
+	const char *tty;
+	int ret;
+
+	DBG("%p", modem);
+
+	tty = ofono_modem_get_string(modem, "Device");
+	if (tty == NULL)
+		return -EINVAL;
+
+	ret = service_level_connection(modem, tty);
+
+	return ret;
+}
+
+static int hfp_disable(struct ofono_modem *modem)
+{
+	struct hfp_data *data = ofono_modem_get_data(modem);
+	int i;
+
+	DBG("%p", modem);
+
+	if (!data->chat)
+		return 0;
+
+	g_at_chat_unref(data->chat);
+	data->chat = NULL;
+
+	if (data->cind_length) {
+		for (i = 1; i < data->cind_length + 1; i++)
+			g_free(data->cind_names[i]);
+
+		g_free(data->cind_names);
+		data->cind_names = NULL;
+
+		g_free(data->cind_values);
+		data->cind_values = NULL;
+
+		data->cind_length = 0;
+	}
+
+	ofono_modem_set_powered(modem, FALSE);
+
+	return 0;
+}
+
+static void hfp_pre_sim(struct ofono_modem *modem)
+{
+	DBG("%p", modem);
+}
+
+static void hfp_post_sim(struct ofono_modem *modem)
+{
+	DBG("%p", modem);
+}
+
+static struct ofono_modem_driver hfp_driver = {
+	.name		= "hfp",
+	.probe		= hfp_probe,
+	.remove		= hfp_remove,
+	.enable		= hfp_enable,
+	.disable	= hfp_disable,
+	.pre_sim	= hfp_pre_sim,
+	.post_sim	= hfp_post_sim,
+};
+
+static int hfp_init(void)
+{
+	DBG("");
+	return ofono_modem_driver_register(&hfp_driver);
+}
+
+static void hfp_exit(void)
+{
+	ofono_modem_driver_unregister(&hfp_driver);
+}
+
+OFONO_PLUGIN_DEFINE(hfp, "Hands-Free Profile Plugins", VERSION,
+			OFONO_PLUGIN_PRIORITY_DEFAULT, hfp_init, hfp_exit)
diff --git a/plugins/modemconf.c b/plugins/modemconf.c
index 4795749..192faa6 100644
--- a/plugins/modemconf.c
+++ b/plugins/modemconf.c
@@ -100,7 +100,8 @@ static struct ofono_modem *create_modem(GKeyFile *keyfile, const char *group)
 		set_address(modem, keyfile, group);
 
 	if (!g_strcmp0(driver, "atgen") || !g_strcmp0(driver, "g1") ||
-						!g_strcmp0(driver, "calypso"))
+						!g_strcmp0(driver, "calypso") ||
+						!g_strcmp0(driver, "hfp"))
 		set_device(modem, keyfile, group);
 
 	g_free(driver);
-- 
1.6.1.3


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

* Re: [PATCH] Handsfree profile plugins update
  2009-10-19 14:41 [PATCH] Handsfree profile plugins update Zhang, Zhenhua
@ 2009-10-19 22:12 ` Denis Kenzior
  0 siblings, 0 replies; 2+ messages in thread
From: Denis Kenzior @ 2009-10-19 22:12 UTC (permalink / raw)
  To: ofono

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

Hi Zhenhua,

> Hi,
>
> Attached is update patch for handsfree profile plugin. I move most stuff in
> drivers/hfpmodem/hfp.c into plugins/hfp.c and simplify them. GSList *indies
> is replaced as two indexable arrays (cind_names and cind_values), to
> improve efficiency when we need access name and value by index. The whole
> logic is the same comparing with previous patch.
>
> Thanks for Denis and Gustavo for comments. Please review it.

This patch has been applied with some additional fixes by me.  Please let me 
know if I broke something.

Regards,
-Denis

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

end of thread, other threads:[~2009-10-19 22:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-19 14:41 [PATCH] Handsfree profile plugins update Zhang, Zhenhua
2009-10-19 22:12 ` 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.