From: Antara <[email protected]>

Adding coexagent which implements coex agent interface to
provide bt and wifi data
---
 src/coexagent.c | 384 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/coexagent.h |  77 ++++++++++++
 2 files changed, 461 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..7bdbef5
--- /dev/null
+++ b/src/coexagent.c
@@ -0,0 +1,384 @@
+/*
+ *
+ *  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 COEX_MANAGER_INTERFACE "org.coex.Manager"
+
+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
-- 
1.9.1

_______________________________________________
ofono mailing list
[email protected]
https://lists.ofono.org/mailman/listinfo/ofono

Reply via email to