Hi Antara, I don't understand the reason to split your vendor-specific atom between the plugin and the src. Couldn't be self contained? (for example, like the plugins/gemalto.c -> cinterion.hardwareMonitor atom). Regards. Giacinto On Tue, Oct 23, 2018 at 10:53 AM Antara Borwankar wrote: > > From: Antara > > 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 > +#endif > + > +#define _GNU_SOURCE > +#include > +#include > +#include > + > +#include > +#include > + > +#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 @@ > > > > + > > > > -- > 1.9.1 > > _______________________________________________ > ofono mailing list > ofono(a)ofono.org > https://lists.ofono.org/mailman/listinfo/ofono