All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Zhurakivskyy <oleg.zhurakivskyy@nokia.com>
To: ofono@ofono.org
Subject: [PATCH 1/9] SMS history plugin.
Date: Wed, 29 Dec 2010 14:51:17 +0200	[thread overview]
Message-ID: <1293627085-24428-2-git-send-email-oleg.zhurakivskyy@nokia.com> (raw)
In-Reply-To: <1293627085-24428-1-git-send-email-oleg.zhurakivskyy@nokia.com>

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

---
 plugins/messaging-agent.c |  403 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 403 insertions(+), 0 deletions(-)
 create mode 100644 plugins/messaging-agent.c

diff --git a/plugins/messaging-agent.c b/plugins/messaging-agent.c
new file mode 100644
index 0000000..fa93fe8
--- /dev/null
+++ b/plugins/messaging-agent.c
@@ -0,0 +1,403 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ *  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 <errno.h>
+
+#include <glib.h>
+#include <gdbus.h>
+
+#include <ofono.h>
+#include <smsagent.h>
+
+#define MESSAGING_INTERFACE OFONO_SERVICE ".Messaging"
+#define MESSAGING_AGENT_INTERFACE OFONO_SERVICE ".MessagingAgent"
+
+struct messaging_context_data {
+	struct ofono_history_context *context;
+	GSList *agents;
+};
+
+struct messaging_agent_data {
+	struct messaging_context_data *data;
+	struct sms_agent *agent;
+};
+
+static void messaging_agent_delete(void *data)
+{
+	struct messaging_agent_data *agent_data = data;
+
+	if (!g_slist_find(agent_data->data->agents, agent_data))
+		return;
+
+	DBG("modem=%s: agent=%p",
+		ofono_modem_get_path(agent_data->data->context->modem),
+		agent_data->agent);
+
+	agent_data->data->agents = g_slist_remove(agent_data->data->agents,
+							agent_data);
+	g_free(agent_data);
+}
+
+static void messaging_agents_delete(gpointer user)
+{
+	struct messaging_context_data *data = user;
+
+	DBG("modem=%s", ofono_modem_get_path(data->context->modem));
+
+	while (data->agents) {
+		struct messaging_agent_data *agent_data = data->agents->data;
+		sms_agent_free(agent_data->agent);
+	}
+}
+
+static DBusMessage *messaging_agent_register(DBusConnection *conn,
+						DBusMessage *msg, void *param)
+{
+	const char *agent_path;
+	const char *agent_bus = dbus_message_get_sender(msg);
+	struct messaging_context_data *data = param;
+	struct messaging_agent_data *agent_data;
+	GSList *node;
+
+	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH,
+			&agent_path, DBUS_TYPE_INVALID) == FALSE)
+		return __ofono_error_invalid_args(msg);
+
+	if (!__ofono_dbus_valid_object_path(agent_path))
+		return __ofono_error_invalid_format(msg);
+
+	for (node = data->agents; node; node = g_slist_next(node)) {
+
+		agent_data = node->data;
+
+		if (sms_agent_matches(agent_data->agent, agent_bus,
+					agent_path) == TRUE)
+			return __ofono_error_busy(msg);
+	}
+
+	agent_data = g_try_new0(struct messaging_agent_data, 1);
+	if (agent_data == NULL)
+		return __ofono_error_failed(msg);
+
+	agent_data->data = data;
+	agent_data->agent = sms_agent_new(MESSAGING_AGENT_INTERFACE,
+				dbus_message_get_sender(msg), agent_path);
+	if (agent_data->agent == NULL) {
+		g_free(agent_data);
+		return __ofono_error_failed(msg);
+	}
+
+	data->agents = g_slist_append(data->agents, agent_data);
+
+	DBG("modem=%s: agent=%p %s:%s:%s",
+		ofono_modem_get_path(data->context->modem), agent_data->agent,
+		dbus_message_get_sender(msg), agent_path,
+		MESSAGING_AGENT_INTERFACE);
+
+	sms_agent_set_removed_notify(agent_data->agent, messaging_agent_delete,
+					agent_data);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *messaging_agent_unregister(DBusConnection *conn,
+						DBusMessage *msg, void *param)
+{
+	const char *agent_path;
+	const char *agent_bus = dbus_message_get_sender(msg);
+	struct messaging_context_data *data = param;
+	GSList *node;
+
+	DBG("");
+
+	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &agent_path,
+				DBUS_TYPE_INVALID) == FALSE)
+		return __ofono_error_invalid_args(msg);
+
+	for (node = data->agents; node; node = g_slist_next(node)) {
+
+		struct messaging_agent_data *agent_data = node->data;
+
+		if (sms_agent_matches(agent_data->agent,
+					agent_bus, agent_path) == FALSE)
+			continue;
+
+		sms_agent_free(agent_data->agent);
+		return dbus_message_new_method_return(msg);
+	}
+
+	return __ofono_error_failed(msg);
+}
+
+struct messaging_agent_dict_entry {
+	char *s;
+	char *v;
+};
+
+static GSList *messaging_agent_dict_entry_append(GSList *l, char *s, char *v)
+{
+	struct messaging_agent_dict_entry *e;
+
+	e = g_try_new0(struct messaging_agent_dict_entry, 1);
+	if (e == NULL)
+		return NULL;
+
+	e->s = g_strdup(s);
+	e->v = g_strdup(v);
+	if (e->s == NULL || e->v == NULL) {
+		g_free(e);
+		return NULL;
+	}
+
+	return g_slist_append(l, e);
+}
+
+static void messaging_agent_dict_delete(GSList *l)
+{
+	while (l) {
+		struct messaging_agent_dict_entry *e = l->data;
+
+		l = g_slist_remove(l, l->data);
+		g_free(e->s);
+		g_free(e->v);
+		g_free(e);
+	}
+}
+
+static void messaging_agent_dict_append_cb(DBusMessageIter *dict, void *param)
+{
+	GSList *node;
+
+	for (node = (GSList *)param; node; node = g_slist_next(node)) {
+
+		struct messaging_agent_dict_entry *e = node->data;
+
+		ofono_dbus_dict_append(dict, e->s, DBUS_TYPE_STRING, &e->v);
+	}
+}
+
+static void messaging_agent_sms_received(struct ofono_history_context *context,
+						const struct ofono_uuid *uuid,
+						const char *from,
+						const struct tm *remote,
+						const struct tm *local,
+						const char *text)
+{
+	GSList *node;
+	GSList *entries = NULL;
+	struct messaging_context_data *data = context->data;
+
+	entries = messaging_agent_dict_entry_append(entries, (char *)"UUID",
+					(char *)ofono_uuid_to_str(uuid));
+
+	for (node = data->agents; node; node = g_slist_next(node)) {
+		struct messaging_agent_data *agent_data = node->data;
+
+		DBG("modem=%s -> agent=%p: text=\"%s\"",
+			ofono_modem_get_path(data->context->modem),
+			agent_data->agent, text);
+
+		sms_agent_dispatch_datagram(agent_data->agent,
+					"MessageReceived",
+					from, remote, local,
+					(unsigned char *)text,
+					strlen(text), NULL, NULL,
+					messaging_agent_dict_append_cb,
+					(void *)entries, NULL);
+	}
+
+	messaging_agent_dict_delete(entries);
+}
+
+static void messaging_agent_sms_send_pending(
+				struct ofono_history_context *context,
+				const struct ofono_uuid *uuid,
+				const char *to, time_t when,
+				const char *text)
+{
+	GSList *node;
+	GSList *entries = NULL;
+	struct messaging_context_data *data = context->data;
+
+	entries = messaging_agent_dict_entry_append(entries, (char *)"UUID",
+					(char *)ofono_uuid_to_str(uuid));
+
+	for (node = data->agents; node; node = g_slist_next(node)) {
+		struct messaging_agent_data *agent_data = node->data;
+
+		DBG("modem=%s -> agent=%p: text=\"%s\"",
+			ofono_modem_get_path(data->context->modem),
+			agent_data->agent, text);
+
+		sms_agent_dispatch_datagram(agent_data->agent,
+						"MessageSendPending",
+						to, localtime(&when),
+						localtime(&when),
+						(unsigned char *)text,
+						strlen(text), NULL, NULL,
+						messaging_agent_dict_append_cb,
+						(void *)entries, NULL);
+	}
+
+	messaging_agent_dict_delete(entries);
+}
+
+#undef _
+#define _(_x) case _x: return #_x
+
+static char *messaging_agent_sms_status(enum ofono_history_sms_status s)
+{
+	switch (s) {
+		_(OFONO_HISTORY_SMS_STATUS_PENDING);
+		_(OFONO_HISTORY_SMS_STATUS_SUBMITTED);
+		_(OFONO_HISTORY_SMS_STATUS_SUBMIT_FAILED);
+		_(OFONO_HISTORY_SMS_STATUS_DELIVERED);
+		_(OFONO_HISTORY_SMS_STATUS_DELIVER_FAILED);
+	}
+	return "OFONO_HISTORY_SMS_STATUS_<UNKNOWN>";
+}
+
+static void messaging_agent_sms_send_status(
+					struct ofono_history_context *context,
+					const struct ofono_uuid *uuid,
+					time_t when,
+					enum ofono_history_sms_status s)
+{
+	GSList *node;
+	GSList *entries = NULL;
+	struct messaging_context_data *data = context->data;
+
+	entries = messaging_agent_dict_entry_append(entries, (char *)"UUID",
+			(char *)ofono_uuid_to_str(uuid));
+	entries = messaging_agent_dict_entry_append(entries, (char *)"Status",
+			(char *)messaging_agent_sms_status(s));
+
+	for (node = data->agents; node; node = g_slist_next(node)) {
+		struct messaging_agent_data *agent_data = node->data;
+
+		DBG("modem=%s -> agent=%p: status=%s",
+			ofono_modem_get_path(data->context->modem),
+			agent_data->agent,
+			messaging_agent_sms_status(s));
+
+		sms_agent_dispatch_datagram(agent_data->agent,
+						"MessageSendStatus",
+						NULL, localtime(&when),
+						localtime(&when), NULL, 0,
+						NULL, NULL,
+						messaging_agent_dict_append_cb,
+						(void *)entries, NULL);
+	}
+
+	messaging_agent_dict_delete(entries);
+}
+
+static GDBusMethodTable messaging_agent_methods[] = {
+	{ "AgentRegister",	"o", "", messaging_agent_register },
+	{ "AgentUnregister",	"o", "", messaging_agent_unregister },
+	{ }
+};
+
+static int messaging_agent_probe(struct ofono_history_context *context)
+{
+	if (context->data) {
+		ofono_error("modem=%s: data already exists: data=%p",
+				ofono_modem_get_path(context->modem),
+				context->data);
+		return -EEXIST;
+	}
+
+	context->data = g_try_new0(struct messaging_context_data, 1);
+	if (context->data == NULL)
+		return -ENOMEM;
+
+	memset(context->data, 0, sizeof(struct messaging_context_data));
+	((struct messaging_context_data *)context->data)->context = context;
+
+	DBG("modem=%s: data=%p", ofono_modem_get_path(context->modem),
+		context->data);
+
+	if (!g_dbus_register_interface(ofono_dbus_get_connection(),
+					ofono_modem_get_path(context->modem),
+					MESSAGING_INTERFACE,
+					messaging_agent_methods,
+					NULL, NULL, context->data, NULL)) {
+		ofono_error("Can't register dbus interface %s",
+				MESSAGING_INTERFACE);
+		return -1;
+	}
+
+	ofono_modem_add_interface(context->modem, MESSAGING_INTERFACE);
+
+	return 0;
+}
+
+static void messaging_agent_remove(struct ofono_history_context *context)
+{
+	DBG("modem=%s data=%p", ofono_modem_get_path(context->modem),
+		context->data);
+
+	messaging_agents_delete(context->data);
+
+	ofono_modem_remove_interface(context->modem, MESSAGING_INTERFACE);
+
+	if (!g_dbus_unregister_interface(ofono_dbus_get_connection(),
+		ofono_modem_get_path(context->modem),
+		MESSAGING_INTERFACE))
+		ofono_error("Can't unregister dbus interface %s",
+				MESSAGING_INTERFACE);
+
+	g_free(context->data);
+}
+
+static struct ofono_history_driver messaging_agent_driver = {
+	.name = "Messaging Agent",
+	.probe = messaging_agent_probe,
+	.remove = messaging_agent_remove,
+	.sms_received = messaging_agent_sms_received,
+	.sms_send_pending = messaging_agent_sms_send_pending,
+	.sms_send_status = messaging_agent_sms_send_status,
+};
+
+static int messaging_agent_init()
+{
+	DBG("");
+
+	ofono_history_driver_register(&messaging_agent_driver);
+
+	return 0;
+}
+
+static void messaging_agent_exit()
+{
+	DBG("");
+
+	ofono_history_driver_unregister(&messaging_agent_driver);
+}
+
+OFONO_PLUGIN_DEFINE(messaging_agent, "Messaging Agent", VERSION,
+			OFONO_PLUGIN_PRIORITY_DEFAULT,
+			messaging_agent_init, messaging_agent_exit)
-- 
1.7.1


  reply	other threads:[~2010-12-29 12:51 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-29 12:51 [PATCH 0/9] SMS history plugin Oleg Zhurakivskyy
2010-12-29 12:51 ` Oleg Zhurakivskyy [this message]
2010-12-29 12:51 ` [PATCH 2/9] " Oleg Zhurakivskyy
2010-12-29 12:51 ` [PATCH 3/9] SMS history plugin documentation Oleg Zhurakivskyy
2010-12-29 12:51 ` [PATCH 4/9] SMS history plugin test script Oleg Zhurakivskyy
2010-12-29 12:51 ` [PATCH 5/9] oFono smsagent enhancements to permit more flexible parameter set to be dispatched Oleg Zhurakivskyy
2010-12-29 12:51 ` [PATCH 6/9] " Oleg Zhurakivskyy
2011-01-27 13:18   ` Marcel Holtmann
2011-01-27 14:38     ` oleg.zhurakivskyy
2011-01-27 22:40       ` Marcel Holtmann
2011-01-31  8:30         ` Oleg Zhurakivskyy
2010-12-29 12:51 ` [PATCH 7/9] Minor modifications due to sms_agent_dispatch_datagram() enhancements Oleg Zhurakivskyy
2010-12-29 12:51 ` [PATCH 8/9] " Oleg Zhurakivskyy
2010-12-29 12:51 ` [PATCH 9/9] D-Bus rules for SMS history plugin Oleg Zhurakivskyy

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=1293627085-24428-2-git-send-email-oleg.zhurakivskyy@nokia.com \
    --to=oleg.zhurakivskyy@nokia.com \
    --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.