All of lore.kernel.org
 help / color / mirror / Atom feed
From: Antara Borwankar <antara.borwankar@intel.com>
To: ofono@ofono.org
Subject: [PATCH 2/2] coex: coex agent implementation
Date: Tue, 23 Oct 2018 14:26:46 +0530	[thread overview]
Message-ID: <1540285006-8430-1-git-send-email-antara.borwankar@intel.com> (raw)

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

From: Antara <antara.borwankar@intel.com>

Added implementation for coex agent
---
 src/coexagent.c | 385 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/coexagent.h |  77 ++++++++++++
 src/ofono.conf  |   1 +
 3 files changed, 463 insertions(+)
 create mode 100644 src/coexagent.c
 create mode 100644 src/coexagent.h

diff --git a/src/coexagent.c b/src/coexagent.c
new file mode 100644
index 0000000..d2d6eac
--- /dev/null
+++ b/src/coexagent.c
@@ -0,0 +1,385 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2008-2011  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 <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <gdbus.h>
+
+#include "ofono.h"
+
+#include "common.h"
+#include "coexagent.h"
+
+#define OFONO_COEX_AGENT_INTERFACE OFONO_SERVICE ".LTECoexAgent"
+#define OFONO_COEX_INTERFACE OFONO_SERVICE ".LTECoex"
+
+struct coex_agent {
+	char *path;
+	char *bus;
+	guint disconnect_watch;
+	ofono_bool_t remove_on_terminate;
+	ofono_destroy_func removed_cb;
+	void *removed_data;
+	DBusMessage *msg;
+	DBusPendingCall *call;
+	void *user_data;
+	int min_length;
+	int max_length;
+	ofono_bool_t hidden_entry;
+	ofono_destroy_func user_destroy;
+};
+
+#define CALLBACK_END()						\
+done:								\
+	if (result == COEX_AGENT_RESULT_TERMINATE &&		\
+			agent->remove_on_terminate)		\
+		remove_agent = TRUE;				\
+	else							\
+		remove_agent = FALSE;				\
+								\
+error:								\
+	coex_agent_request_end(agent);				\
+	dbus_message_unref(reply);				\
+								\
+	if (remove_agent)					\
+		coex_agent_free(agent)				\
+
+ofono_bool_t coex_agent_matches(struct coex_agent *agent,
+			const char *path, const char *sender)
+{
+	return !strcmp(agent->path, path) && !strcmp(agent->bus, sender);
+}
+
+static int check_error(struct coex_agent *agent, DBusMessage *reply,
+		enum coex_agent_result *out_result)
+{
+	DBusError err;
+	int result = 0;
+
+	dbus_error_init(&err);
+
+	if (dbus_set_error_from_message(&err, reply) == FALSE) {
+		*out_result = COEX_AGENT_RESULT_OK;
+		return 0;
+	}
+
+	ofono_debug("CoexAgent %s replied with error %s, %s",
+			agent->path, err.name, err.message);
+
+	result = -EINVAL;
+
+	dbus_error_free(&err);
+	return result;
+}
+
+void coex_agent_set_removed_notify(struct coex_agent *agent,
+					ofono_destroy_func destroy,
+					void *user_data)
+{
+	agent->removed_cb = destroy;
+	agent->removed_data = user_data;
+}
+
+static void coex_agent_send_noreply(struct coex_agent *agent, const char *method)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	DBusMessage *message;
+
+	message = dbus_message_new_method_call(agent->bus, agent->path,
+					OFONO_COEX_INTERFACE,
+					method);
+	if (message == NULL)
+		return;
+
+	dbus_message_set_no_reply(message, TRUE);
+
+	g_dbus_send_message(conn, message);
+}
+
+void coex_agent_send_release(struct coex_agent *agent)
+{
+	coex_agent_send_noreply(agent, "Release");
+}
+
+static void coex_agent_request_end(struct coex_agent *agent)
+{
+	if (agent->msg) {
+		dbus_message_unref(agent->msg);
+		agent->msg = NULL;
+	}
+
+	if (agent->call) {
+		dbus_pending_call_unref(agent->call);
+		agent->call = NULL;
+	}
+
+	if (agent->user_destroy)
+		agent->user_destroy(agent->user_data);
+
+	agent->user_destroy = NULL;
+	agent->user_data = NULL;
+}
+
+void coex_agent_free(struct coex_agent *agent)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+
+	if (agent->disconnect_watch) {
+		coex_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 coex_agent_disconnect_cb(DBusConnection *conn, void *user_data)
+{
+	struct coex_agent *agent = user_data;
+
+	ofono_debug("Agent exited without calling Unregister");
+
+	agent->disconnect_watch = 0;
+
+	coex_agent_free(agent);
+}
+
+struct coex_agent* coex_agent_new(const char *path, const char *sender,
+				ofono_bool_t remove_on_terminate)
+{
+	struct coex_agent* agent = g_try_new0(struct coex_agent, 1);
+	DBusConnection *conn = ofono_dbus_get_connection();
+
+	DBG("");
+	if (agent == NULL)
+		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,
+							coex_agent_disconnect_cb,
+							agent, NULL);
+
+	return agent;
+}
+
+static void coex_agent_coex_wlan_notify_cb(DBusPendingCall *call, void *data)
+{
+	struct coex_agent *agent = data;
+	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	enum coex_agent_result result;
+	gboolean remove_agent;
+
+	DBG("");
+	if (check_error(agent, reply, &result) == -EINVAL) {
+		remove_agent = TRUE;
+		goto error;
+	}
+
+	if (result != COEX_AGENT_RESULT_OK) {
+		goto done;
+	}
+
+	if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
+		ofono_error("Can't parse the reply to DisplayText()");
+		remove_agent = TRUE;
+		goto error;
+	}
+
+	CALLBACK_END();
+}
+
+int coex_agent_coex_wlan_notify(struct coex_agent *agent,
+			const struct wl_coex_info wlan_info,
+			ofono_bool_t urgent,
+			void *user_data, ofono_destroy_func destroy)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	DBusMessageIter wl_args, wl_dict, wl_array;
+	const dbus_int32_t *pwl_array = wlan_info.safe_vector;
+	dbus_int32_t value;
+
+	agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
+						OFONO_COEX_AGENT_INTERFACE,
+						"ReceiveWiFiNotification");
+	if (agent->msg == NULL)
+		return -ENOMEM;
+
+	dbus_message_iter_init_append(agent->msg, &wl_args);
+
+	dbus_message_iter_open_container(&wl_args, DBUS_TYPE_ARRAY,
+				DBUS_TYPE_INT32_AS_STRING, &wl_array);
+	dbus_message_iter_append_fixed_array(&wl_array, DBUS_TYPE_INT32,
+					&pwl_array, MAX_WL_SAFE_VECTOR);
+
+	dbus_message_iter_close_container(&wl_args, &wl_array);
+
+	dbus_message_iter_open_container(&wl_args, DBUS_TYPE_ARRAY,
+							"{sv}", &wl_dict);
+
+	value = wlan_info.safe_tx_min;
+	ofono_dbus_dict_append(&wl_dict, "SafeTxMin",
+			 DBUS_TYPE_UINT32, &value);
+	value = wlan_info.safe_tx_max;
+	ofono_dbus_dict_append(&wl_dict, "SafeTxMax",
+			 DBUS_TYPE_UINT32, &value);
+	value = wlan_info.safe_rx_min;
+	ofono_dbus_dict_append(&wl_dict, "SafeRxMin",
+			 DBUS_TYPE_UINT32, &value);
+	value = wlan_info.safe_rx_max;
+	ofono_dbus_dict_append(&wl_dict, "SafeRxMax",
+			 DBUS_TYPE_UINT32, &value);
+	value = wlan_info.num_safe_vector;
+	ofono_dbus_dict_append(&wl_dict, "NumSafeVector",
+			 DBUS_TYPE_UINT32, &value);
+
+	dbus_message_iter_close_container(&wl_args, &wl_dict);
+
+	if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
+						-1) == FALSE ||
+						agent->call == NULL)
+		return -EIO;
+
+	agent->user_data = user_data;
+	agent->user_destroy = destroy;
+
+	dbus_pending_call_set_notify(agent->call, coex_agent_coex_wlan_notify_cb,
+					agent, NULL);
+
+	return 0;
+}
+
+static void coex_agent_coex_bt_notify_cb(DBusPendingCall *call, void *data)
+{
+	struct coex_agent *agent = data;
+	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	enum coex_agent_result result;
+	gboolean remove_agent;
+
+	DBG("");
+	if (check_error(agent, reply,&result) == -EINVAL) {
+		remove_agent = TRUE;
+		goto error;
+	}
+
+	if (result != COEX_AGENT_RESULT_OK) {
+		goto done;
+	}
+
+	if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
+		ofono_error("Can't parse the reply to DisplayText()");
+		remove_agent = TRUE;
+		goto error;
+	}
+
+	CALLBACK_END();
+}
+
+int coex_agent_coex_bt_notify(struct coex_agent *agent,
+			const struct bt_coex_info bt_info,
+			ofono_bool_t urgent,
+			void *user_data, ofono_destroy_func destroy)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	DBusMessageIter bt_args, bt_dict, bt_array;
+	const dbus_int32_t *pbt_array = bt_info.safe_vector;
+	int len = MAX_BT_SAFE_VECTOR;
+	dbus_int32_t value;
+
+	agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
+						OFONO_COEX_AGENT_INTERFACE,
+						"ReceiveBTNotification");
+
+	if (agent->msg == NULL)
+		return -ENOMEM;
+
+	pbt_array = bt_info.safe_vector;
+
+	for(len = 0 ; len < MAX_BT_SAFE_VECTOR; len++)
+		DBG("pbt_array[%d] = %d", len, pbt_array[len]);
+
+	dbus_message_iter_init_append(agent->msg, &bt_args);
+
+	dbus_message_iter_open_container(&bt_args, DBUS_TYPE_ARRAY,
+					DBUS_TYPE_INT32_AS_STRING, &bt_array);
+
+	dbus_message_iter_append_fixed_array(&bt_array, DBUS_TYPE_INT32,
+					&pbt_array, len);
+
+	dbus_message_iter_close_container(&bt_args, &bt_array);
+
+	dbus_message_iter_open_container(&bt_args,
+					DBUS_TYPE_ARRAY, "{sv}", &bt_dict);
+
+	value = bt_info.safe_tx_min;
+	DBG("value = %d", value);
+	ofono_dbus_dict_append(&bt_dict, "SafeTxMin",
+			DBUS_TYPE_UINT32, &value);
+	value = bt_info.safe_tx_max;
+	DBG("value = %d", value);
+	ofono_dbus_dict_append(&bt_dict, "SafeTxMax",
+			DBUS_TYPE_UINT32, &value);
+	value = bt_info.safe_rx_min;
+	DBG("value = %d", value);
+	ofono_dbus_dict_append(&bt_dict, "SafeRxMin",
+			DBUS_TYPE_UINT32, &value);
+	value = bt_info.safe_rx_max;
+	DBG("value = %d", value);
+	ofono_dbus_dict_append(&bt_dict, "SafeRxMax",
+			DBUS_TYPE_UINT32, &value);
+	value = bt_info.num_safe_vector;
+	DBG("value = %d", value);
+	ofono_dbus_dict_append(&bt_dict, "NumSafeVector",
+			DBUS_TYPE_UINT32, &value);
+
+	dbus_message_iter_close_container(&bt_args, &bt_dict);
+
+	if ((dbus_connection_send_with_reply(conn, agent->msg,
+					&agent->call, -1) == FALSE) ||
+					agent->call == NULL) {
+		return -EIO;
+	}
+
+	agent->user_data = user_data;
+	agent->user_destroy = destroy;
+
+	dbus_pending_call_set_notify(agent->call, coex_agent_coex_bt_notify_cb,
+				agent, NULL);
+
+	return 0;
+}
diff --git a/src/coexagent.h b/src/coexagent.h
new file mode 100644
index 0000000..2ba80ba
--- /dev/null
+++ b/src/coexagent.h
@@ -0,0 +1,77 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2008-2011  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 COEXAGENT_H
+#define COEXAGENT_H
+struct coex_agent;
+
+#define MAX_BT_SAFE_VECTOR 15
+#define MAX_WL_SAFE_VECTOR 13
+
+enum coex_agent_result {
+	COEX_AGENT_RESULT_OK,
+	COEX_AGENT_RESULT_BACK,
+	COEX_AGENT_RESULT_TERMINATE,
+	COEX_AGENT_RESULT_TIMEOUT,
+	COEX_AGENT_RESULT_BUSY,
+};
+
+struct bt_coex_info {
+	int safe_tx_min;
+	int safe_tx_max;
+	int safe_rx_min;
+	int safe_rx_max;
+	int safe_vector[MAX_BT_SAFE_VECTOR];
+	int num_safe_vector;
+};
+
+struct wl_coex_info {
+	int safe_tx_min;
+	int safe_tx_max;
+	int safe_rx_min;
+	int safe_rx_max;
+	int safe_vector[MAX_BT_SAFE_VECTOR];
+	int num_safe_vector;
+};
+
+struct coex_agent* coex_agent_new(const char *path, const char *sender,
+				ofono_bool_t remove_on_terminate);
+
+void coex_agent_set_removed_notify(struct coex_agent *agent,
+				ofono_destroy_func destroy, void *user_data);
+
+ofono_bool_t coex_agent_matches(struct coex_agent *agent,
+			const char *path, const char *sender);
+
+int coex_agent_coex_bt_notify(struct coex_agent *agent,
+			const struct bt_coex_info bt_info,
+			ofono_bool_t urgent,
+			void *user_data, ofono_destroy_func destroy);
+
+int coex_agent_coex_wlan_notify(struct coex_agent *agent,
+			const struct wl_coex_info wlan_info,
+			ofono_bool_t urgent,
+			void *user_data, ofono_destroy_func destroy);
+
+void coex_agent_send_release(struct coex_agent *agent);
+
+void coex_agent_free(struct coex_agent *agent);
+
+#endif
diff --git a/src/ofono.conf b/src/ofono.conf
index 61e0bde..5a3afaa 100644
--- a/src/ofono.conf
+++ b/src/ofono.conf
@@ -16,6 +16,7 @@
     <allow send_interface="org.ofono.PositioningRequestAgent"/>
     <allow send_interface="org.ofono.HandsfreeAudioAgent"/>
     <allow send_interface="org.ofono.NetworkMonitorAgent"/>
+    <allow send_interface="org.ofono.LTECoexAgent"/>
   </policy>
 
   <policy at_console="true">
-- 
1.9.1


             reply	other threads:[~2018-10-23  8:56 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-23  8:56 Antara Borwankar [this message]
2018-10-23  9:04 ` [PATCH 2/2] coex: coex agent implementation Giacinto Cifelli

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=1540285006-8430-1-git-send-email-antara.borwankar@intel.com \
    --to=antara.borwankar@intel.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.