All of lore.kernel.org
 help / color / mirror / Atom feed
From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [PATCH] Added implementation for "ReportVoiceCall", "ReportTextMessage", "Release" methods and related code.Please take a look and give me feedback on the code quality , thinks that need to be changed. Signed-off-by: Rajyalakshmi Bommaraju <Rajyalakshmi.Bommaraju@intel.com>
Date: Tue, 09 Nov 2010 11:19:56 -0600	[thread overview]
Message-ID: <4CD982BC.9000102@gmail.com> (raw)
In-Reply-To: <1288826447-19225-2-git-send-email-Rajyalakshmi.Bommaraju@intel.com>

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

On 11/03/2010 06:20 PM, Rajyalakshmi Bommaraju wrote:
> ---
>  Makefile.am             |    6 +
>  plugins/history.c       |  438 +++++++++++++++++++++++++++++++++++++++++++++
>  plugins/history_agent.c |  453 +++++++++++++++++++++++++++++++++++++++++++++++
>  plugins/history_agent.h |  103 +++++++++++

You might want to separate this patch into a series of patches.  Start
with the API definition in the oFono API documentation format.  Then the
history_agent implementation.  Then the actual history plugin
implementation.

>  4 files changed, 1000 insertions(+), 0 deletions(-)
>  create mode 100755 plugins/history.c
>  create mode 100644 plugins/history_agent.c
>  create mode 100644 plugins/history_agent.h
> 
> diff --git a/Makefile.am b/Makefile.am
> index cd17fa2..530c2de 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -286,6 +286,12 @@ builtin_sources += plugins/ste.c
>  
>  builtin_modules += caif
>  builtin_sources += plugins/caif.c
> +
> +
> +builtin_modules += history
> +builtin_sources += plugins/history_agent.h
> +builtin_sources += plugins/history_agent.c
> +builtin_sources += plugins/history.c
>  endif
>  
>  if MAINTAINER_MODE
> diff --git a/plugins/history.c b/plugins/history.c
> new file mode 100755
> index 0000000..f5d4ba0
> --- /dev/null
> +++ b/plugins/history.c
> @@ -0,0 +1,438 @@
> +/*
> + *
> + * oFono - Open Source Telephony
> + *
> + * Copyright (C) 2008-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
> +
> +#define OFONO_API_SUBJECT_TO_CHANGE
> +#include <errno.h>
> +
> +#include "gdbus/gdbus.h"
> +#include <ofono/history.h>
> +#include "plugins/history_agent.h"
> +#include "src/common.h"
> +
> +#define HISTORY_FILE_PATH "/var/cache/ofonohistory/"
> +#define HISTORY_FILE HISTORY_FILE_PATH"ofonohistorydata"
> +#define OFONO_MANAGER_PATH "/"

Please note that this is already defined in include/dbus.h

> +#define OFONO_HISTORY_INTERFACE "com.meego.TelephonyHistory"

Please don't hijack OFONO_ prefix for private enums / defines.

> +
> +struct ofono_history {
> +	struct history_agent *current_agent;
> +	int timeout;
> +} *history;
> +
> +

Please avoid double empty lines

> +static int history_plugin_probe(struct ofono_history_context *context)
> +{
> +	DBG("History Probe for modem: %p", context->modem);
> +	return 0;
> +}
> +
> +static void history_plugin_remove(struct ofono_history_context *context)
> +{
> +	DBG("History Remove for modem: %p", context->modem);
> +}
> +
> +/**
> + * history_call_ended:
> + * ofono calls this method with the call information
> + */
> +

Remove this empty line here

> +static void history_plugin_call_ended(struct ofono_history_context *context,
> +					const struct ofono_call *call,
> +					time_t start,
> +					time_t end)
> +{
> +	struct ofono_modem *modem;
> +	const char *path;
> +	struct history *v = g_try_new0(struct history, 1);

There should be an empty line after a variable declaration block.

> +	if (!v)
> +		return;
> +
> +	v->data.voice.type = VOICE;
> +
> +	strcpy(v->data.voice.lineid, "Unknown");
> +
> +	if (call->type != 0)
> +		return;
> +
> +	DBG("Voice Call, %s", call->direction ? "Incoming" : "Outgoing");
> +	v->data.voice.type = call->direction;
> +
> +	if (call->clip_validity == 0)
> +		strcpy(v->data.voice.lineid,
> +				phone_number_to_string(&call->phone_number));
> +
> +	v->data.voice.start_time = start;
> +	v->data.voice.end_time = end;
> +
> +	DBG("Call Ended on modem: %p", context->modem);
> +	modem = context->modem;
> +	path = ofono_modem_get_path(modem);
> +
> +	v->data.voice.modem_path = g_try_malloc0(strlen(path) + 1);
> +	if (v->data.voice.modem_path)
> +		strcpy(v->data.voice.modem_path, path);
> +
> +	if (!history) {
> +		g_free(v);
> +		return;
> +	}
> +
> +	history_agent_report_voicecall(v, history->current_agent,
> +					history->timeout);
> +}
> +
> +/**
> + * history_call_missed:
> + * ofono calls this method with the call information
> + */
> +

Remove the empty line here

> +static void history_plugin_call_missed(struct ofono_history_context *context,
> +					const struct ofono_call *call,
> +					time_t when)
> +{
> +	struct ofono_modem *modem;
> +	const char *modem_path;
> +

Preferred way would be to remove the empty line here

> +	struct history *v = g_try_new0(struct history, 1);

and add an empty line here

> +	if (!v)
> +		return;

Empty line here, refer to rule M1 of doc/coding-style.txt

> +	v->type = VOICE;
> +
> +	strcpy(v->data.voice.lineid, "Unknown");
> +
> +	if (call->type != 0)
> +		return;
> +
> +	v->type = MISSED;
> +
> +	if (call->clip_validity == 0)
> +		strcpy(v->data.voice.lineid,
> +				phone_number_to_string(&call->phone_number));
> +
> +	v->data.voice.start_time = when;
> +
> +	v->data.voice.end_time = when;
> +
> +	DBG("Call Missed on modem: %p", context->modem);
> +	modem = context->modem;
> +	modem_path = ofono_modem_get_path(modem);
> +
> +	v->data.voice.modem_path = g_try_malloc0(strlen(modem_path) + 1);
> +	if (v->data.voice.modem_path)
> +		strcpy(v->data.voice.modem_path, modem_path);

Again, rule M1

> +	if (!history) {
> +		g_free(v);
> +		return;
> +	}
> +
> +	history_agent_report_voicecall(v, history->current_agent,
> +					history->timeout);
> +}
> +
> +static void history_plugin_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)
> +{
> +	char buf[128];
> +	struct ofono_modem *modem;
> +	const char *modem_path;
> +
> +	struct history *thistory = g_try_new0(struct history, 1);

And empty line here

> +	if (!thistory)
> +		return;
> +
> +	thistory->data.text.type = TEXT;
> +
> +	strcpy(thistory->data.text.uid, ofono_uuid_to_str(uuid));
> +
> +	strftime(buf, 127, "%a %d %b %Y %H:%M:%S %z", local);
> +	buf[127] = '\0';
> +	DBG("Local Sent Time: %s", buf);
> +
> +	thistory->data.text.localsenttime = *local;
> +
> +	strftime(buf, 127, "%a %d %b %Y %H:%M:%S %z", remote);
> +	buf[127] = '\0';
> +	DBG("Remote Sent Time: %s", buf);
> +	thistory->data.text.remotesenttime = *remote;
> +
> +	DBG("Text: %s", text);
> +
> +	thistory->data.text.message = (char *) g_try_malloc0(strlen(text) + 1);
> +	strcpy(thistory->data.text.message, text);
> +
> +	DBG("From: %s:", from);
> +	strcpy(thistory->data.text.lineid, from);
> +
> +	thistory->data.text.type = INCOMING;
> +
> +	thistory->data.text.status = OFONO_HISTORY_SMS_STATUS_SUBMITTED;
> +
> +	DBG("Incoming SMS on modem: %p", context->modem);
> +	modem = context->modem;
> +	modem_path = ofono_modem_get_path(modem);
> +
> +	thistory->data.text.modem_path = g_try_malloc0(strlen(modem_path) + 1);

Rule M1...

> +	if (thistory->data.text.modem_path)
> +		strcpy(thistory->data.text.modem_path, modem_path);
> +
> +	history_agent_report_textmessage(thistory, history->current_agent,
> +					history->timeout);
> +}
> +
> +static void history_plugin_sms_send_status(
> +					struct ofono_history_context *context,
> +					const struct ofono_uuid *uuid,
> +					time_t when,
> +					enum ofono_history_sms_status s)
> +{
> +	char buf[128];
> +	struct ofono_modem *modem;
> +	const char *modem_path;
> +
> +	struct history *thistory = g_try_new0(struct history, 1);

An empty line here

> +	if (!thistory)
> +		return;
> +
> +	thistory->type = TEXT;
> +
> +	strcpy(thistory->data.text.uid, ofono_uuid_to_str(uuid));
> +
> +	thistory->data.text.localsenttime = *(localtime(&when));
> +	strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z",
> +			&(thistory->data.text.localsenttime));
> +	buf[127] = '\0';
> +	thistory->data.text.type = OUTGOING;
> +
> +	switch (s) {
> +	case OFONO_HISTORY_SMS_STATUS_PENDING:
> +		break;
> +	case OFONO_HISTORY_SMS_STATUS_SUBMITTED:
> +
> +		DBG("SMS %s submitted successfully", ofono_uuid_to_str(uuid));
> +		DBG("Submission Time: %s", buf);
> +
> +		thistory->data.text.status =
> +					OFONO_HISTORY_SMS_STATUS_SUBMITTED;
> +		break;
> +	case OFONO_HISTORY_SMS_STATUS_SUBMIT_FAILED:
> +
> +		DBG("SMS %s submitted successfully", ofono_uuid_to_str(uuid));
> +		DBG("Failure Time: %s", buf);
> +
> +		thistory->data.text.status =
> +					OFONO_HISTORY_SMS_STATUS_SUBMIT_FAILED;
> +		break;
> +	default:
> +		break;
> +	};
> +
> +	modem = context->modem;
> +	modem_path = ofono_modem_get_path(modem);
> +
> +	thistory->data.text.modem_path = g_try_malloc0(strlen(modem_path)
> +									+ 1);
> +	if (thistory->data.text.modem_path)
> +		strcpy(thistory->data.text.modem_path, modem_path);
> +
> +	history_agent_report_textmessage(thistory, history->current_agent,
> +					history->timeout);
> +}
> +
> +static void history_plugin_sms_send_pending(
> +					struct ofono_history_context *context,
> +					const struct ofono_uuid *uuid,
> +					const char *to, time_t when,
> +					const char *text)
> +{
> +	char buf[128];
> +	struct ofono_modem *modem;
> +	const char *modem_path;
> +
> +	struct history *thistory = g_try_new0(struct history, 1);
> +	if (!thistory)
> +		return;
> +
> +	thistory->type = TEXT;
> +
> +	DBG("To: %s:", to);
> +	strcpy(thistory->data.text.lineid, to);
> +
> +	DBG("SMS %s submitted successfully", ofono_uuid_to_str(uuid));
> +	strcpy(thistory->data.text.uid, ofono_uuid_to_str(uuid));
> +
> +	thistory->data.text.localsenttime = *(localtime(&when));
> +	strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z",
> +			&(thistory->data.text.localsenttime));
> +	buf[127] = '\0';
> +	DBG("Local Time: %s", buf);
> +
> +	thistory->data.text.type = OUTGOING;
> +
> +	DBG("Text: %s", text);
> +	thistory->data.text.message = (char *) g_try_malloc0(strlen(text)
> +									+ 1);
> +	if (thistory->data.text.message)
> +		strcpy(thistory->data.text.message, text);
> +
> +	thistory->data.text.status = OFONO_HISTORY_SMS_STATUS_PENDING;
> +
> +	DBG("Sending SMS on modem: %p", context->modem);
> +	modem = context->modem;
> +	modem_path = ofono_modem_get_path(modem);
> +
> +	thistory->data.text.modem_path = g_try_malloc0(strlen(modem_path)
> +									+ 1);
> +	if (thistory->data.text.modem_path)
> +		strcpy(thistory->data.text.modem_path, modem_path);
> +
> +	history_agent_report_textmessage(thistory, history->current_agent,
> +					history->timeout);
> +}
> +
> +static void history_notify(gpointer user_data)
> +{
> +	struct ofono_history *ohistory = user_data;
> +
> +	DBG("History Agent Removed");
> +
> +	ohistory->current_agent = NULL;
> +}
> +
> +static DBusMessage *history_register_agent(DBusConnection *conn,
> +					DBusMessage *msg, void *data)
> +{
> +	const char *agent_path;
> +	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);
> +
> +	if (!history)
> +		return __ofono_error_failed(msg);
> +
> +	history->current_agent = history_agent_new(agent_path,
> +					dbus_message_get_sender(msg),
> +					FALSE);
> +
> +	if (!history->current_agent)
> +		return __ofono_error_failed(msg);
> +
> +	DBG("History agent created");
> +
> +	history_agent_set_removed_notify(history->current_agent,
> +					history_notify, history);
> +
> +	return dbus_message_new_method_return(msg);
> +}
> +
> +static DBusMessage *history_unregister_agent(DBusConnection *conn,
> +					DBusMessage *msg, void *data)
> +{
> +	const char *agent_path;
> +
> +	const char *agent_bus = dbus_message_get_sender(msg);
> +
> +	if (dbus_message_get_args(msg, NULL,
> +					DBUS_TYPE_OBJECT_PATH, &agent_path,
> +					DBUS_TYPE_INVALID) == FALSE)
> +		return __ofono_error_invalid_args(msg);
> +
> +	if (!history->current_agent)
> +		return __ofono_error_failed(msg);
> +
> +	if (!history_agent_matches(history->current_agent, agent_path,
> +						agent_bus))
> +		return __ofono_error_failed(msg);
> +
> +	history_agent_free(history->current_agent);
> +
> +	return dbus_message_new_method_return(msg);
> +}
> +
> +static GDBusMethodTable history_methods[] = {
> +	{ "RegisterAgent",	"o",	"",	history_register_agent },
> +	{ "UnregisterAgent",	"o",	"",	history_unregister_agent },
> +	{ }
> +};
> +
> +static struct ofono_history_driver history_driver = {
> +	.name = "history plugin",
> +	.probe = history_plugin_probe,
> +	.remove = history_plugin_remove,
> +	.call_ended = history_plugin_call_ended,
> +	.call_missed = history_plugin_call_missed,
> +	.sms_received = history_plugin_sms_received,
> +	.sms_send_pending = history_plugin_sms_send_pending,
> +	.sms_send_status = history_plugin_sms_send_status
> +};
> +
> +static int history_plugin_init(void)
> +{
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +
> +	if (!g_dbus_register_interface(conn,
> +					OFONO_MANAGER_PATH,
> +					OFONO_HISTORY_INTERFACE,
> +					history_methods,
> +					NULL,
> +					NULL,	/* Properties */
> +					NULL,	/* Userdata   */
> +					NULL)) {	/* Destroy func */
> +		ofono_error("Could not create %s interface",
> +					OFONO_HISTORY_INTERFACE);
> +
> +		return -EIO;
> +	}
> +
> +	history = g_try_new0(struct ofono_history, 1);
> +
> +	if (!history)
> +		return -EIO;
> +
> +	history->timeout = 600;		/* 10 minutes */
> +	return ofono_history_driver_register(&history_driver);
> +}
> +
> +static void history_plugin_exit(void)
> +{
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +
> +	g_dbus_unregister_interface(conn, OFONO_MANAGER_PATH,
> +				OFONO_HISTORY_INTERFACE);
> +	if (history)
> +		g_free(history);
> +	ofono_history_driver_unregister(&history_driver);
> +}
> +
> +OFONO_PLUGIN_DEFINE(history, "History Plugin",
> +		OFONO_VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
> +		history_plugin_init, history_plugin_exit)
> diff --git a/plugins/history_agent.c b/plugins/history_agent.c
> new file mode 100644
> index 0000000..d4d55ec
> --- /dev/null
> +++ b/plugins/history_agent.c
> @@ -0,0 +1,453 @@
> +/*
> + *
> + * oFono - Open Source Telephony
> + *
> + * Copyright (C) 2008-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
> +
> +#define OFONO_API_SUBJECT_TO_CHANGE
> +#define MODEM_STRUCT_LEN 2
> +
> +#include "plugins/history_agent.h"
> +
> +#define OFONO_HISTORY_AGENT "com.meego.TelephonyHistoryAgent"

Again, please do not hijack OFONO_ prefix for your private defines.

> +#define ERROR_PREFIX OFONO_SERVICE ".Error"
> +#define FAILED_ERROR ERROR_PREFIX ".Failed"
> +
> +enum allowed_errors {
> +	ALLOWED_ERROR_FAILED = 0x1
> +};
> +
> +struct history_agent {
> +	char *path;
> +	char *bus;
> +	guint disconnect_watch;
> +	ofono_bool_t remove_on_terminate;
> +	ofono_destroy_func removed_cb;
> +	void *removed_data;
> +	DBusPendingCall *call;
> +	void *user_data;

So in general this data structure is fine, however do keep in mind that
it is possible to perform only a single request at a time.  If several
history events happen simultaneously, they need to be queued / buffered
by the caller.

I don't believe your current code is handling this possibility at all.
The other obvious thing that is missing is the lack of serialization /
deserialization of this queue, or the immediate submission of the events
to the agent when it is first registered.

> +};
> +
> +void history_agent_free(struct history_agent *agent)
> +{
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +
> +	if (agent->disconnect_watch) {
> +		history_agent_send_release(agent);
> +		g_dbus_remove_watch(conn, agent->disconnect_watch);
> +		agent->disconnect_watch = 0;
> +	}
> +
> +	if (agent->removed_cb)
> +		agent->removed_cb(agent->removed_data);
> +
> +	g_free(agent->path);
> +	g_free(agent->bus);
> +	g_free(agent);
> +}
> +
> +static void history_agent_disconnect_cb(DBusConnection *conn, void *user_data)
> +{
> +	DBG("Agent exited without unregister");
> +
> +	struct history_agent *agent = user_data;
> +
> +	agent->disconnect_watch = 0;
> +
> +	history_agent_free(agent);
> +}
> +
> +ofono_bool_t history_agent_matches(struct history_agent *agent,
> +					const char *path, const char *sender)
> +{
> +	return !strcmp(agent->path, path) && !strcmp(agent->bus, sender);
> +}
> +
> +struct history_agent *history_agent_new(const char *path, const char *sender,
> +					ofono_bool_t remove_on_terminate)

Please note that remove_on_terminate is not really needed and should be
TRUE by default.  This was specific to stkagent and should not be
propagated elsewhere.

> +{
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +	struct history_agent *agent = g_try_new0(struct history_agent, 1);

En empty line here

> +	if (!agent)
> +		return NULL;
> +
> +	agent->path = g_strdup(path);
> +	agent->bus = g_strdup(sender);
> +	agent->remove_on_terminate = remove_on_terminate;
> +
> +	agent->disconnect_watch = g_dbus_add_disconnect_watch(conn, sender,
> +						history_agent_disconnect_cb,
> +						agent, NULL);
> +	return agent;
> +}
> +
> +static int check_error(struct history_agent *agent, DBusMessage *reply,
> +				int allowed_errors,
> +				enum HISTORY_AGENT_RESULT *out_result)
> +{
> +	DBusError err;
> +	int result = 0;
> +
> +	dbus_error_init(&err);
> +
> +	if (dbus_set_error_from_message(&err, reply) == FALSE) {
> +		*out_result = HISTORY_AGENT_RESULT_OK;
> +		return 0;
> +	}
> +
> +	ofono_debug("HistoryAgent %s replied with error %s, %s",
> +			agent->path, err.name, err.message);
> +
> +	/* Timeout is always valid */
> +	if (g_str_equal(err.name, DBUS_ERROR_NO_REPLY)) {
> +		/* Send a Cancel() to the agent since its taking too long */
> +		*out_result = HISTORY_AGENT_RESULT_TIMEOUT;
> +		goto out;
> +	}
> +
> +	if ((allowed_errors & ALLOWED_ERROR_FAILED) &&
> +		g_str_equal(err.name, FAILED_ERROR)) {
> +		*out_result = HISTORY_AGENT_RESULT_FAILED;
> +		goto out;
> +	}
> +
> +	result = -EINVAL;
> +out:
> +	dbus_error_free(&err);
> +	return result;
> +}
> +
> +static void history_agent_send_no_reply(struct history_agent *agent,
> +					const char *method)
> +{
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +	DBusMessage *message;
> +
> +	message = dbus_message_new_method_call(agent->bus, agent->path,
> +						OFONO_HISTORY_AGENT,
> +						method);
> +
> +	if (message == NULL)
> +		return;
> +
> +	dbus_message_set_no_reply(message, TRUE);
> +
> +	g_dbus_send_message(conn, message);
> +}
> +
> +static void history_agent_data_free(void *data)
> +{
> +	struct history *history = (struct history *)data;

An empty line here.

> +	if (history->type == TEXT) {
> +		g_free(history->data.text.message);
> +		g_free(history->data.text.modem_path);
> +	} else {
> +		g_free(history->data.voice.modem_path);
> +	}

And again please see rule M1 in doc/coding-style.txt

> +	g_free(history);
> +}
> +
> +static const char *call_type_to_string(enum type tp)
> +{
> +	switch (tp) {
> +	case INCOMING:
> +		return "incoming";
> +	case OUTGOING:
> +		return "outgoing";
> +	case MISSED:
> +		return "missed";
> +	default:
> +		return "unknown";
> +	}
> +}
> +
> +static const char *status_to_string(enum ofono_history_sms_status status)
> +{
> +	switch (status) {
> +	case OFONO_HISTORY_SMS_STATUS_PENDING:
> +		return "Pending";
> +	case OFONO_HISTORY_SMS_STATUS_SUBMITTED:
> +		return "Submitted";
> +	case OFONO_HISTORY_SMS_STATUS_SUBMIT_FAILED:
> +		return "Submit Failed";
> +	case OFONO_HISTORY_SMS_STATUS_DELIVERED:
> +		return "Delivered";
> +	case OFONO_HISTORY_SMS_STATUS_DELIVER_FAILED:
> +		return "Deliver Failed";
> +	default:
> +		return "unknown";
> +	}

In general oFono APIs use lower caps and hyphens for values.  Remember,
these are not translated.  So this should be 'pending', 'submitted',
'submit-failed', 'delivered', 'delivery-failed', or something like that.

The 'unknown' state is pretty much useless.

> +}
> +
> +static void data_delivery_cb(DBusPendingCall *call, void *data)
> +{
> +	struct history_agent *agent = data;
> +	enum HISTORY_AGENT_RESULT result = -EINVAL;
> +
> +	DBusMessage *reply = dbus_pending_call_steal_reply(call);
> +
> +	if (check_error(agent, reply,
> +				 ALLOWED_ERROR_FAILED,
> +				&result) == -EINVAL) {
> +		g_print("Agent disappeared\n");
> +		/* TODO - persist  agent->user_data  */
> +		history_agent_data_free(agent->user_data);
> +	}
> +
> +	if (result == HISTORY_AGENT_RESULT_OK) {
> +		g_print("Agent reply ok\n");
> +		history_agent_data_free(agent->user_data);
> +	}
> +
> +	if (result == HISTORY_AGENT_RESULT_TIMEOUT) {
> +		g_print("Reply timedout\n");
> +		/* TODO - persist  agent->user_data*/
> +		history_agent_data_free(agent->user_data);
> +	}
> +}
> +
> +static char **get_modem_struct(const char *path)
> +{
> +	int i = 0;
> +	char **ret;
> +
> +	/* TODO - Figureout how to release this*/
> +	ret = g_try_new0(char *, 3);
> +	if (!ret)
> +		return NULL;
> +
> +	ret[i++] = g_strdup("Modem");
> +	ret[i++] = g_strdup(path);
> +
> +	return ret;
> +}
> +
> +static void append_texthistory_properties(struct text_history *h,
> +						DBusMessageIter *array)
> +{
> +	const char *localtm, *senttm;
> +	static char localsenttm[128], rsenttime[128];
> +	const char *phone;
> +	const char *mesg;
> +	const char *msgid;
> +	DBusMessageIter dict;
> +	char **modem_dict;
> +
> +	dbus_message_iter_open_container(array, DBUS_TYPE_ARRAY,
> +					OFONO_PROPERTIES_ARRAY_SIGNATURE,
> +					&dict);
> +
> +	strftime(localsenttm, 127, "%Y-%m-%dT%H:%M:%S%z",
> +				(&h->localsenttime));
> +	localsenttm[127] = '\0';
> +	localtm = localsenttm;
> +
> +	strftime(rsenttime, 127, "%Y-%m-%dT%H:%M:%S%z",
> +				(&h->remotesenttime));
> +	rsenttime[127] = '\0';
> +	senttm = rsenttime;
> +
> +	msgid = h->uid;
> +
> +	ofono_dbus_dict_append(&dict, "Uid", DBUS_TYPE_STRING, &msgid);
> +
> +	const char *type_str = call_type_to_string(h->type);
> +
> +	ofono_dbus_dict_append(&dict, "Type",
> +				DBUS_TYPE_STRING, &type_str);
> +
> +	const char *status_str = status_to_string(h->status);
> +
> +	ofono_dbus_dict_append(&dict, "Status",
> +				DBUS_TYPE_STRING, &status_str);
> +
> +	phone = h->lineid;
> +	ofono_dbus_dict_append(&dict, "LineIdentification", DBUS_TYPE_STRING,
> +				&phone);
> +
> +	ofono_dbus_dict_append(&dict, "LocalSentTime", DBUS_TYPE_STRING,
> +				&localtm);
> +
> +	ofono_dbus_dict_append(&dict, "SentTime", DBUS_TYPE_STRING,
> +				&senttm);
> +	mesg = h->message;
> +	ofono_dbus_dict_append(&dict, "Message", DBUS_TYPE_STRING,
> +				&mesg);
> +
> +	modem_dict = get_modem_struct(h->modem_path);
> +
> +	ofono_dbus_dict_append_dict(&dict, "Information", DBUS_TYPE_STRING,
> +					&modem_dict);
> +
> +	dbus_message_iter_close_container(array, &dict);
> +}
> +
> +static void append_voicehistory_properties(struct voice_history *h,
> +						DBusMessageIter *array)
> +{
> +	const char *sttime, *entime;
> +	static char starttime[128], endtime[128];
> +	struct tm starttm, endtm;
> +	const char *phone;
> +	char **modem_dict;
> +	DBusMessageIter dict;
> +
> +	dbus_message_iter_open_container(array, DBUS_TYPE_ARRAY,
> +					OFONO_PROPERTIES_ARRAY_SIGNATURE,
> +					&dict);
> +
> +	strftime(starttime, 127, "%Y-%m-%dT%H:%M:%S%z",
> +				localtime_r(&h->start_time, &starttm));
> +	starttime[127] = '\0';
> +	sttime = starttime;
> +
> +	strftime(endtime, 127, "%Y-%m-%dT%H:%M:%S%z",
> +				localtime_r(&h->end_time, &endtm));
> +	endtime[127] = '\0';
> +	entime = endtime;
> +
> +	ofono_dbus_dict_append(&dict, "Uid", DBUS_TYPE_UINT32, &h->uid);
> +
> +	const char *type_str = call_type_to_string(h->type);
> +
> +	ofono_dbus_dict_append(&dict, "Type",
> +				DBUS_TYPE_STRING, &type_str);
> +
> +	phone = h->lineid;
> +	ofono_dbus_dict_append(&dict, "LineIdentification", DBUS_TYPE_STRING,
> +				&phone);
> +
> +	ofono_dbus_dict_append(&dict, "StartTime", DBUS_TYPE_STRING,
> +				&sttime);
> +
> +	ofono_dbus_dict_append(&dict, "EndTime", DBUS_TYPE_STRING,
> +				&entime);
> +
> +	modem_dict = get_modem_struct(h->modem_path);
> +
> +	ofono_dbus_dict_append_dict(&dict, "Information", DBUS_TYPE_STRING,
> +					&modem_dict);
> +
> +	dbus_message_iter_close_container(array, &dict);
> +}
> +
> +int history_agent_report_voicecall(struct history *history,
> +				struct history_agent *agent, int timeout)
> +{
> +	if (!agent)
> +		/* TODO persist history */
> +		return -1;
> +
> +	DBusMessage *msg ;
> +	DBusMessageIter iter, array;
> +	struct voice_history *vhistory = &(history->data.voice);
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +
> +	msg = dbus_message_new_method_call(agent->bus,
> +					   agent->path,
> +						OFONO_HISTORY_AGENT,
> +						"ReportVoiceCall");
> +	if (msg == NULL)
> +		return -ENOMEM;
> +
> +	dbus_message_iter_init_append(msg, &iter);
> +
> +	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
> +					DBUS_TYPE_ARRAY_AS_STRING
> +					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
> +					DBUS_TYPE_STRING_AS_STRING
> +					DBUS_TYPE_VARIANT_AS_STRING
> +					DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
> +					&array);
> +	append_voicehistory_properties(vhistory, &array);
> +
> +	dbus_message_iter_close_container(&iter, &array);
> +
> +	agent->user_data = (void *)history;
> +
> +	if (dbus_connection_send_with_reply(conn, msg, &agent->call,
> +						timeout) == FALSE ||
> +			agent->call == NULL)
> +		return -EIO;
> +
> +	dbus_pending_call_set_notify(agent->call, data_delivery_cb,
> +							agent, NULL);
> +	return 0;
> +}
> +
> +
> +int history_agent_report_textmessage(struct history *history,
> +				struct history_agent *agent, int timeout)
> +{
> +	if (!agent)
> +		/* TODO Persist history */
> +		return -1;
> +
> +	DBusMessage *msg ;
> +	DBusMessageIter iter, array;
> +	struct text_history *text_history = &(history->data.text);
> +	DBusConnection *conn = ofono_dbus_get_connection();
> +
> +	msg = dbus_message_new_method_call(agent->bus,
> +					   agent->path,
> +						OFONO_HISTORY_AGENT,
> +						"ReportTextMessage");
> +	if (msg == NULL)
> +		return -ENOMEM;
> +
> +	dbus_message_iter_init_append(msg, &iter);
> +
> +	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
> +					DBUS_TYPE_ARRAY_AS_STRING
> +					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
> +					DBUS_TYPE_STRING_AS_STRING
> +					DBUS_TYPE_VARIANT_AS_STRING
> +					DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
> +					&array);
> +	append_texthistory_properties(text_history, &array);
> +
> +	dbus_message_iter_close_container(&iter, &array);
> +
> +	agent->user_data = (void *)history;
> +
> +	if (dbus_connection_send_with_reply(conn, msg, &agent->call,
> +						timeout) == FALSE ||
> +			agent->call == NULL)
> +		return -EIO;
> +
> +	dbus_pending_call_set_notify(agent->call, data_delivery_cb,
> +							agent, NULL);
> +	return 0;
> +}
> +
> +void history_agent_send_release(struct history_agent *agent)
> +{
> +	history_agent_send_no_reply(agent, "Release");
> +}
> +
> +void history_agent_set_removed_notify(struct history_agent *agent,
> +				ofono_destroy_func destroy,
> +				void *user_data)
> +{
> +	agent->removed_cb = destroy;
> +	agent->removed_data = user_data;
> +}
> diff --git a/plugins/history_agent.h b/plugins/history_agent.h
> new file mode 100644
> index 0000000..fe7049e
> --- /dev/null
> +++ b/plugins/history_agent.h
> @@ -0,0 +1,103 @@
> +/*
> + *
> + * oFono - Open Source Telephony
> + *
> + * Copyright (C) 2008-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
> +
> +#define OFONO_API_SUBJECT_TO_CHANGE
> +#include <errno.h>
> +#include <string.h>
> +
> +#include "gdbus/gdbus.h"
> +#include <ofono/dbus.h>
> +#include <ofono/history.h>
> +#include <ofono/log.h>
> +#include <ofono/types.h>
> +#include "src/ofono.h"
> +
> +#define PHONE_NUMBER_LENGTH 64
> +struct history_agent;
> +
> +enum history_type {
> +	VOICE = 0,
> +	TEXT
> +};
> +
> +struct voice_history {
> +	guint32 uid;
> +	guint8 type;
> +	char lineid[PHONE_NUMBER_LENGTH];
> +	time_t start_time;
> +	time_t end_time;
> +	char *modem_path;
> +};
> +
> +struct text_history {
> +	char uid[OFONO_SHA1_UUID_LEN * 2 + 1];
> +	guint8 type;
> +	guint8 status;
> +	char lineid[PHONE_NUMBER_LENGTH];
> +	struct tm localsenttime;
> +	struct tm remotesenttime;
> +	char *message;
> +	char *modem_path;
> +};
> +
> +struct history {
> +	union {
> +		struct voice_history voice;
> +		struct text_history text;
> +	} data;
> +	enum history_type type;
> +};
> +
> +enum HISTORY_AGENT_RESULT {
> +	HISTORY_AGENT_RESULT_OK,
> +	HISTORY_AGENT_RESULT_FAILED,
> +	HISTORY_AGENT_RESULT_TIMEOUT
> +};
> +
> +enum type {
> +	OUTGOING = 0,
> +	INCOMING,
> +	MISSED
> +};
> +
> +struct history_agent *history_agent_new(const char *path, const char *sender,
> +					ofono_bool_t remove_on_terminate);
> +
> +void history_agent_free(struct history_agent *agent);
> +
> +ofono_bool_t history_agent_matches(struct history_agent *agent,
> +					const char *path, const char *sender);
> +
> +int history_agent_report_voicecall(struct history *vhistory,
> +				struct history_agent *agent, int timeout);
> +
> +int history_agent_report_textmessage(struct history *history,
> +				struct history_agent *agent, int timeout);
> +
> +void history_agent_send_release(struct history_agent *agent);
> +
> +void history_agent_set_removed_notify(struct history_agent *agent,
> +					ofono_destroy_func destroy,
> +					void *user_data);

Regards,
-Denis

      reply	other threads:[~2010-11-09 17:19 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-03 23:20 Please provide your feedback on the patch attached Rajyalakshmi Bommaraju
2010-11-03 23:20 ` [PATCH] Added implementation for "ReportVoiceCall", "ReportTextMessage", "Release" methods and related code.Please take a look and give me feedback on the code quality , thinks that need to be changed. Signed-off-by: Rajyalakshmi Bommaraju <Rajyalakshmi.Bommaraju@intel.com> Rajyalakshmi Bommaraju
2010-11-09 17:19   ` Denis Kenzior [this message]

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=4CD982BC.9000102@gmail.com \
    --to=denkenz@gmail.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.