All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lucas De Marchi <lucas.demarchi@profusion.mobi>
To: ofono@ofono.org
Subject: [PATCH 1/3] Add TTY (hearing impaired) support
Date: Wed, 17 Nov 2010 23:58:39 -0200	[thread overview]
Message-ID: <1290045521-28215-1-git-send-email-lucas.demarchi@profusion.mobi> (raw)

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

---
 Makefile.am              |    5 +-
 include/dbus.h           |    1 +
 include/text-telephony.h |   71 ++++++++++
 src/modem.c              |    1 +
 src/ofono.h              |    2 +
 src/text-telephony.c     |  333 ++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 411 insertions(+), 2 deletions(-)
 create mode 100644 include/text-telephony.h
 create mode 100644 src/text-telephony.c

diff --git a/Makefile.am b/Makefile.am
index f841b4c..ee1313d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,7 +13,8 @@ include_HEADERS = include/log.h include/plugin.h include/history.h \
 			include/cbs.h include/call-volume.h \
 			include/gprs.h include/gprs-context.h \
 			include/radio-settings.h include/stk.h \
-			include/audio-settings.h include/nettime.h
+			include/audio-settings.h include/nettime.h \
+			include/text-telephony.h
 
 nodist_include_HEADERS = include/version.h
 
@@ -318,7 +319,7 @@ src_ofonod_SOURCES = $(gdbus_sources) $(builtin_sources) src/ofono.ver \
 			src/radio-settings.c src/stkutil.h src/stkutil.c \
 			src/nettime.c src/stkagent.c src/stkagent.h \
 			src/simfs.c src/simfs.h src/audio-settings.c \
-			src/smsagent.c src/smsagent.h
+			src/smsagent.c src/smsagent.h src/text-telephony.c
 
 src_ofonod_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LIBS@ -ldl
 
diff --git a/include/dbus.h b/include/dbus.h
index 59b2aae..9e29afb 100644
--- a/include/dbus.h
+++ b/include/dbus.h
@@ -48,6 +48,7 @@ extern "C" {
 #define OFONO_PHONEBOOK_INTERFACE "org.ofono.Phonebook"
 #define OFONO_RADIO_SETTINGS_INTERFACE "org.ofono.RadioSettings"
 #define OFONO_AUDIO_SETTINGS_INTERFACE "org.ofono.AudioSettings"
+#define OFONO_TEXT_TELEPHONY_INTERFACE "org.ofono.TextTelephony"
 #define OFONO_SIM_MANAGER_INTERFACE "org.ofono.SimManager"
 #define OFONO_VOICECALL_INTERFACE "org.ofono.VoiceCall"
 #define OFONO_VOICECALL_MANAGER_INTERFACE "org.ofono.VoiceCallManager"
diff --git a/include/text-telephony.h b/include/text-telephony.h
new file mode 100644
index 0000000..fafa7dd
--- /dev/null
+++ b/include/text-telephony.h
@@ -0,0 +1,71 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *  Copyright (C) 2010  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 __OFONO_TEXT_TELEPHONY_H
+#define __OFONO_TEXT_TELEPHONY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ofono/types.h>
+
+struct ofono_text_telephony;
+
+typedef void (*ofono_text_telephony_set_cb_t)(const struct ofono_error *error,
+						void *data);
+typedef void (*ofono_text_telephony_query_cb_t)(const struct ofono_error *error,
+						ofono_bool_t enable, void *data);
+
+struct ofono_text_telephony_driver {
+	const char *name;
+	int (*probe)(struct ofono_text_telephony *tt, unsigned int vendor,
+			void *data);
+	void (*remove)(struct ofono_text_telephony *tt);
+	void (*query_tty)(struct ofono_text_telephony *tt,
+				ofono_text_telephony_query_cb_t cb,
+				void *data);
+	void (*set_tty)(struct ofono_text_telephony *tt,
+				int enable,
+				ofono_text_telephony_set_cb_t cb,
+				void *data);
+};
+
+int ofono_text_telephony_driver_register(const struct ofono_text_telephony_driver *d);
+void ofono_text_telephony_driver_unregister(const struct ofono_text_telephony_driver *d);
+
+struct ofono_text_telephony *ofono_text_telephony_create(struct ofono_modem *modem,
+								unsigned int vendor,
+								const char *driver,
+								void *data);
+
+void ofono_text_telephony_register(struct ofono_text_telephony *tt);
+void ofono_text_telephony_remove(struct ofono_text_telephony *tt);
+
+void ofono_text_telephony_set_data(struct ofono_text_telephony *tt, void *data);
+void *ofono_text_telephony_get_data(struct ofono_text_telephony *tt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OFONO_TEXT_TELEPHONY_H */
diff --git a/src/modem.c b/src/modem.c
index 3776461..6f1db7c 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -857,6 +857,7 @@ static const struct {
 	{ OFONO_SIM_MANAGER_INTERFACE,			"sim"	},
 	{ OFONO_STK_INTERFACE,				"stk"	},
 	{ OFONO_CONNECTION_MANAGER_INTERFACE,		"gprs"	},
+	{ OFONO_TEXT_TELEPHONY_INTERFACE,		"tty"	},
 	{ },
 };
 
diff --git a/src/ofono.h b/src/ofono.h
index 4d76d20..5218f42 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -124,6 +124,7 @@ enum ofono_atom_type {
 	OFONO_ATOM_TYPE_AUDIO_SETTINGS = 19,
 	OFONO_ATOM_TYPE_STK = 20,
 	OFONO_ATOM_TYPE_NETTIME = 21,
+	OFONO_ATOM_TYPE_TEXT_TELEPHONY = 22
 };
 
 enum ofono_atom_watch_condition {
@@ -197,6 +198,7 @@ gboolean __ofono_call_settings_is_busy(struct ofono_call_settings *cs);
 #include <ofono/gprs-context.h>
 #include <ofono/radio-settings.h>
 #include <ofono/audio-settings.h>
+#include <ofono/text-telephony.h>
 
 #include <ofono/voicecall.h>
 
diff --git a/src/text-telephony.c b/src/text-telephony.c
new file mode 100644
index 0000000..4640bd8
--- /dev/null
+++ b/src/text-telephony.c
@@ -0,0 +1,333 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *  Copyright (C) 2010  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
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <gdbus.h>
+
+#include "ofono.h"
+#include "common.h"
+
+static GSList *g_drivers = NULL;
+
+struct ofono_text_telephony {
+	DBusMessage *pending;
+	ofono_bool_t powered;
+	ofono_bool_t powered_pending;
+	const struct ofono_text_telephony_driver *driver;
+	void *driver_data;
+	struct ofono_atom *atom;
+};
+
+static DBusMessage *tt_get_properties_reply(DBusMessage *msg,
+						struct ofono_text_telephony *tt)
+{
+	DBusMessage *reply;
+	DBusMessageIter iter;
+	DBusMessageIter dict;
+	dbus_bool_t value;
+
+	reply = dbus_message_new_method_return(msg);
+	if (!reply)
+		return NULL;
+
+	dbus_message_iter_init_append(reply, &iter);
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+					OFONO_PROPERTIES_ARRAY_SIGNATURE,
+					&dict);
+
+	value = tt->powered;
+	ofono_dbus_dict_append(&dict, "Powered", DBUS_TYPE_BOOLEAN, &value);
+	dbus_message_iter_close_container(&iter, &dict);
+
+	return reply;
+}
+
+static void tt_set_powered(struct ofono_text_telephony *tt,
+					ofono_bool_t enable)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	const char *path = __ofono_atom_get_path(tt->atom);
+	dbus_bool_t value = enable;
+
+	if (tt->powered == enable)
+		return;
+
+	ofono_dbus_signal_property_changed(conn, path,
+						OFONO_TEXT_TELEPHONY_INTERFACE,
+						"Powered",
+						DBUS_TYPE_BOOLEAN, &value);
+	tt->powered = enable;
+}
+
+static void tt_set_powered_callback(const struct ofono_error *error,
+						void *data)
+{
+	struct ofono_text_telephony *tt = data;
+	DBusMessage *reply;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		DBG("Error setting powered property");
+
+		tt->powered_pending = tt->powered;
+
+		reply = __ofono_error_failed(tt->pending);
+		__ofono_dbus_pending_reply(&tt->pending, reply);
+
+		return;
+	}
+
+	reply = dbus_message_new_method_return(tt->pending);
+	__ofono_dbus_pending_reply(&tt->pending, reply);
+
+	tt_set_powered(tt, tt->powered_pending);
+}
+
+static void tt_send_properties_reply(struct ofono_text_telephony *tt)
+{
+	DBusMessage *reply;
+
+	reply = tt_get_properties_reply(tt->pending, tt);
+	__ofono_dbus_pending_reply(&tt->pending, reply);
+}
+
+static void tt_query_powered_callback(const struct ofono_error *error,
+						ofono_bool_t enable, void *data)
+{
+	struct ofono_text_telephony *tt = data;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		DBusMessage *reply;
+
+		ofono_debug("Error during powered query");
+
+		reply = __ofono_error_failed(tt->pending);
+		__ofono_dbus_pending_reply(&tt->pending, reply);
+
+		return;
+	}
+
+	tt_set_powered(tt, enable);
+	tt_send_properties_reply(tt);
+}
+
+static DBusMessage *tt_get_properties(DBusConnection *conn,
+						DBusMessage *msg, void *data)
+{
+	struct ofono_text_telephony *tt = data;
+
+	if (tt->pending)
+		return __ofono_error_busy(msg);
+
+	tt->pending = dbus_message_ref(msg);
+	tt->driver->query_tty(tt, tt_query_powered_callback, tt);
+
+	return NULL;
+}
+
+static DBusMessage *tt_set_property(DBusConnection *conn, DBusMessage *msg,
+					void *data)
+{
+	struct ofono_text_telephony *tt = data;
+	DBusMessageIter iter;
+	DBusMessageIter var;
+	const char *property;
+
+	if (tt->pending)
+		return __ofono_error_busy(msg);
+
+	if (!dbus_message_iter_init(msg, &iter))
+		return __ofono_error_invalid_args(msg);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+		return __ofono_error_invalid_args(msg);
+
+	dbus_message_iter_get_basic(&iter, &property);
+	dbus_message_iter_next(&iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+		return __ofono_error_invalid_args(msg);
+
+	dbus_message_iter_recurse(&iter, &var);
+
+	if (g_strcmp0(property, "Powered") == 0) {
+		dbus_bool_t value;
+		int target;
+
+		if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
+			return __ofono_error_invalid_args(msg);
+
+		dbus_message_iter_get_basic(&var, &value);
+		target = value;
+
+		if (tt->powered == target)
+			return dbus_message_new_method_return(msg);
+
+		tt->pending = dbus_message_ref(msg);
+		tt->powered_pending = target;
+
+		tt->driver->set_tty(tt, target,
+					tt_set_powered_callback, tt);
+		return NULL;
+	}
+
+	return __ofono_error_invalid_args(msg);
+}
+
+static GDBusMethodTable tt_methods[] = {
+	{ "GetProperties",  "",    "a{sv}",  tt_get_properties,
+						G_DBUS_METHOD_FLAG_ASYNC },
+	{ "SetProperty",    "sv",  "",       tt_set_property,
+						G_DBUS_METHOD_FLAG_ASYNC },
+	{ }
+};
+
+static GDBusSignalTable tt_signals[] = {
+	{ "PropertyChanged",	"sv" },
+	{ }
+};
+
+int ofono_text_telephony_driver_register(const struct ofono_text_telephony_driver *d)
+{
+	DBG("driver: %p, name: %s", d, d->name);
+
+	if (!d || !d->probe)
+		return -EINVAL;
+
+	g_drivers = g_slist_prepend(g_drivers, (void *)d);
+
+	return 0;
+}
+
+void ofono_text_telephony_driver_unregister(const struct ofono_text_telephony_driver *d)
+{
+	DBG("driver: %p, name: %s", d, d->name);
+
+	if (!d)
+		return;
+
+	g_drivers = g_slist_remove(g_drivers, (void *)d);
+}
+
+static void text_telephony_unregister(struct ofono_atom *atom)
+{
+	struct ofono_text_telephony *tt = __ofono_atom_get_data(atom);
+	const char *path = __ofono_atom_get_path(tt->atom);
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_modem *modem = __ofono_atom_get_modem(tt->atom);
+
+	ofono_modem_remove_interface(modem, OFONO_TEXT_TELEPHONY_INTERFACE);
+	g_dbus_unregister_interface(conn, path, OFONO_TEXT_TELEPHONY_INTERFACE);
+}
+
+static void text_telephony_remove(struct ofono_atom *atom)
+{
+	struct ofono_text_telephony *tt = __ofono_atom_get_data(atom);
+
+	DBG("atom: %p", atom);
+
+	if (!tt)
+		return;
+
+	if (tt->driver && tt->driver->remove)
+		tt->driver->remove(tt);
+
+	g_free(tt);
+}
+
+struct ofono_text_telephony *ofono_text_telephony_create(struct ofono_modem *modem,
+							unsigned int vendor,
+							const char *driver,
+							void *data)
+{
+	struct ofono_text_telephony *tt;
+	GSList *l;
+	if (!driver)
+		return NULL;
+
+	tt = g_try_new0(struct ofono_text_telephony, 1);
+	if (!tt)
+		return NULL;
+
+	tt->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_TEXT_TELEPHONY,
+						text_telephony_remove, tt);
+
+	tt->powered = -1;
+
+	for (l = g_drivers; l; l = l->next) {
+		const struct ofono_text_telephony_driver *drv = l->data;
+
+		if (g_strcmp0(drv->name, driver) != 0)
+			continue;
+
+		if (drv->probe(tt, vendor, data) < 0)
+			continue;
+
+		tt->driver = drv;
+		break;
+	}
+
+	return tt;
+}
+
+void ofono_text_telephony_register(struct ofono_text_telephony *tt)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_modem *modem = __ofono_atom_get_modem(tt->atom);
+	const char *path = __ofono_atom_get_path(tt->atom);
+
+	if (!g_dbus_register_interface(conn, path,
+					OFONO_TEXT_TELEPHONY_INTERFACE,
+						tt_methods, tt_signals,
+					NULL, tt, NULL)) {
+		ofono_error("Could not create %s interface",
+				OFONO_TEXT_TELEPHONY_INTERFACE);
+
+		return;
+	}
+
+	ofono_modem_add_interface(modem, OFONO_TEXT_TELEPHONY_INTERFACE);
+	__ofono_atom_register(tt->atom, text_telephony_unregister);
+}
+
+void ofono_text_telephony_remove(struct ofono_text_telephony *tt)
+{
+	__ofono_atom_free(tt->atom);
+}
+
+void ofono_text_telephony_set_data(struct ofono_text_telephony *tt,
+					void *data)
+{
+	tt->driver_data = data;
+}
+
+void *ofono_text_telephony_get_data(struct ofono_text_telephony *tt)
+{
+	return tt->driver_data;
+}
-- 
1.7.3.2


             reply	other threads:[~2010-11-18  1:58 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-18  1:58 Lucas De Marchi [this message]
2010-11-18  3:51 ` [PATCH 1/3] Add TTY (hearing impaired) support Marcel Holtmann
2010-11-18 11:26   ` Lucas De Marchi
2010-11-18 11:26 Lucas De Marchi
2010-11-18 11:30 ` Lucas De Marchi
2010-11-22 11:21   ` Denis Kenzior
2010-11-19 22:18 ` Gustavo F. Padovan
2010-11-19 22:26   ` Lucas De Marchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1290045521-28215-1-git-send-email-lucas.demarchi@profusion.mobi \
    --to=lucas.demarchi@profusion.mobi \
    --cc=ofono@ofono.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.