From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [PATCH_v6 5/5] connman: add plugin in oFono to request/release private network
Date: Wed, 01 Jun 2011 21:53:38 -0500 [thread overview]
Message-ID: <4DE6FB32.90502@gmail.com> (raw)
In-Reply-To: <1305799112-14289-6-git-send-email-guillaume.zajac@linux.intel.com>
[-- Attachment #1: Type: text/plain, Size: 9909 bytes --]
Hi Guillaume,
On 05/19/2011 04:58 AM, Guillaume Zajac wrote:
> ---
> Makefile.am | 3 +
> plugins/connman.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 302 insertions(+), 0 deletions(-)
> create mode 100644 plugins/connman.c
>
> diff --git a/Makefile.am b/Makefile.am
> index e1eaf15..ffb85ae 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -339,6 +339,9 @@ builtin_sources += plugins/hfp_ag.c plugins/bluetooth.h
> builtin_modules += dun_gw
> builtin_sources += plugins/dun_gw.c plugins/bluetooth.h
>
> +builtin_modules += connman
> +builtin_sources += plugins/connman.c
> +
> builtin_sources += $(btio_sources)
> builtin_cflags += @BLUEZ_CFLAGS@
> builtin_libadd += @BLUEZ_LIBS@
> diff --git a/plugins/connman.c b/plugins/connman.c
> new file mode 100644
> index 0000000..5f0ad8a
> --- /dev/null
> +++ b/plugins/connman.c
> @@ -0,0 +1,299 @@
> +/*
> + *
> + * 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
> +
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +
> +#include <gdbus.h>
> +#include <string.h>
> +
> +#include <ofono.h>
> +#include <private-network.h>
> +
> +#define CONNMAN_SERVICE "net.connman"
> +#define CONNMAN_PATH "/net/connman"
> +
> +#define CONNMAN_DEBUG_INTERFACE CONNMAN_SERVICE ".Debug"
> +#define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error"
> +#define CONNMAN_AGENT_INTERFACE CONNMAN_SERVICE ".Agent"
> +#define CONNMAN_COUNTER_INTERFACE CONNMAN_SERVICE ".Counter"
> +
> +#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
> +#define CONNMAN_MANAGER_PATH "/"
> +
> +#define CONNMAN_TASK_INTERFACE CONNMAN_SERVICE ".Task"
> +#define CONNMAN_PROFILE_INTERFACE CONNMAN_SERVICE ".Profile"
> +#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
> +#define CONNMAN_PROVIDER_INTERFACE CONNMAN_SERVICE ".Provider"
> +#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
> +#define CONNMAN_SESSION_INTERFACE CONNMAN_SERVICE ".Session"
> +#define CONNMAN_NOTIFICATION_INTERFACE CONNMAN_SERVICE ".Notification"
> +
Why do you bother defining all these interfaces when you only ever use
the MANAGER one? Please remove the ones you don't need.
> +static DBusConnection *connection;
> +static GHashTable *requests;
> +static unsigned int id;
> +
> +struct pns_req {
> + int uid;
> + DBusPendingCall *pending;
> + ofono_private_network_cb_t *cb;
> + void *data;
> + gboolean redundant;
> + gboolean error;
> +};
> +
> +static void request_reply(DBusPendingCall *call, void *user_data)
> +{
> + struct pns_req *req = user_data;
> + struct ofono_private_network_settings pns;
> + DBusMessageIter array, dict, entry;
> + DBusMessage *reply;
> +
> + DBG("");
> +
> + pns.fd = -1;
> + pns.server_ip = NULL;
> + pns.peer_ip = NULL;
> + pns.primary_dns = NULL;
> + pns.secondary_dns = NULL;
> +
> + /* request is no more pending */
> + req->pending = NULL;
> +
> + reply = dbus_pending_call_steal_reply(call);
> + if (!reply)
> + goto error;
> +
> + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
> + goto error;
> +
> + if (dbus_message_iter_init(reply, &array) == FALSE)
> + goto error;
> +
> + if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_UNIX_FD)
> + goto error;
> +
> + dbus_message_iter_get_basic(&array, &pns.fd);
> + DBG("Fildescriptor = %d\n", pns.fd);
> +
> + dbus_message_iter_next(&array);
> +
> + if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
> + goto error;
> +
> + dbus_message_iter_recurse(&array, &dict);
> +
> + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
> + DBusMessageIter iter;
> + const char *key;
> + int type;
> +
> + dbus_message_iter_recurse(&dict, &entry);
> +
> + dbus_message_iter_get_basic(&entry, &key);
> +
> + dbus_message_iter_next(&entry);
> + dbus_message_iter_recurse(&entry, &iter);
> +
> + type = dbus_message_iter_get_arg_type(&iter);
> + if (type != DBUS_TYPE_STRING)
> + break;
> +
> + if (g_str_equal(key, "ServerIPv4")
> + && type == DBUS_TYPE_STRING)
> + dbus_message_iter_get_basic(&iter, &pns.server_ip);
> + else if (g_str_equal(key, "PeerIPv4")
> + && type == DBUS_TYPE_STRING)
> + dbus_message_iter_get_basic(&iter, &pns.peer_ip);
> + else if (g_str_equal(key, "PrimaryDNS")
> + && type == DBUS_TYPE_STRING)
> + dbus_message_iter_get_basic(&iter, &pns.primary_dns);
> + else if (g_str_equal(key, "SecondaryDNS")
> + && type == DBUS_TYPE_STRING)
> + dbus_message_iter_get_basic(&iter, &pns.secondary_dns);
> +
> + dbus_message_iter_next(&dict);
> + }
> +
> + if (req->redundant == TRUE)
> + goto done;
We should be checking this much earlier, before doing all the work of
parsing the returned arguments. You should also be sending a
ReleasePrivateNetwork call to ConnMan in this case.
> +
> + if (pns.server_ip == NULL || pns.peer_ip == NULL ||
> + pns.primary_dns == NULL || pns.secondary_dns == NULL ||
> + pns.fd < 0) {
> + ofono_error("Error while reading dictionnary...\n");
> + goto done;
> + }
> +
> + req->cb(req->data, &pns);
> +
> + dbus_message_unref(reply);
> + dbus_pending_call_unref(call);
> +
> + return;
> +
> +error:
> + req->error = TRUE;
> +done:
Calling this label 'done' is a bit misleading.
> + if (pns.fd >= 0)
> + close(pns.fd);
> +
> + req->cb(req->data, NULL);
> +
> + if (reply)
> + dbus_message_unref(reply);
> +
> + dbus_pending_call_unref(call);
> +}
> +
> +static int pns_request(ofono_private_network_cb_t cb, void *data)
> +{
> + DBusMessage *message;
> + DBusPendingCall *call;
> + struct pns_req *req;
> +
> + DBG("");
> +
> + req = g_try_new(struct pns_req, 1);
> +
> + if (req == NULL)
> + return -ENOMEM;
> +
> + message = dbus_message_new_method_call(CONNMAN_SERVICE,
> + CONNMAN_MANAGER_PATH,
> + CONNMAN_MANAGER_INTERFACE,
> + "RequestPrivateNetwork");
Mixing tabs and spaces here, please fix this.
> +
> + if (message == NULL) {
> + g_free(req);
> + return -ENOMEM;
> + }
> +
> + if (dbus_connection_send_with_reply(connection,
> + message, &call, 5000) == FALSE) {
> + g_free(req);
> + dbus_message_unref(message);
> + return -EIO;
> + }
> +
> + id++;
> + req->pending = call;
> + req->cb = cb;
> + req->data = data;
> + req->uid = id;
> + req->redundant = FALSE;
> + req->error = FALSE;
> +
> + dbus_pending_call_set_notify(call, request_reply,
> + req, NULL);
> + g_hash_table_insert(requests, &req->uid, req);
> + dbus_message_unref(message);
> +
> + return req->uid;
> +}
> +
> +static void pns_release(int uid)
> +{
> + DBusMessage *message = NULL;
> + struct pns_req *req;
> +
> + DBG("");
> +
> + req = g_hash_table_lookup(requests, &uid);
> + if (!req)
> + return;
> +
> + if (req->pending) {
> + if (dbus_pending_call_get_completed(req->pending) == FALSE) {
> + /*
> + * We want to cancel the request but we have to wait
> + * the response of ConnMan. So we mark request as
> + * redundant until we get the response, then we remove
> + * it from hash table.
> + */
> + req->redundant = TRUE;
> + return;
> + }
> + }
> +
> + /*
> + * There was an error while reading response or transmitted by response
> + * so we don't need to call release DBus method.
> + */
> + if (req->error)
> + goto error;
Actually I don't think you need this. We should not call release in
case Request() returned an error. I fixed this in commit 9ff1b9f.
> +
> + message = dbus_message_new_method_call(CONNMAN_SERVICE,
> + CONNMAN_MANAGER_PATH,
> + CONNMAN_MANAGER_INTERFACE,
> + "ReleasePrivateNetwork");
Mixing tabs and spaces here, please fix this
> +
> + if (message == NULL)
> + goto error;
> +
> + dbus_message_set_no_reply(message, TRUE);
> + dbus_connection_send(connection, message, NULL);
> +
> +error:
> + if (message)
> + dbus_message_unref(message);
> +
> + g_hash_table_remove(requests, &req->uid);
> +}
> +
> +static struct ofono_private_network_driver pn_driver = {
> + .name = "ConnMan Private Network",
> + .request = pns_request,
> + .release = pns_release,
> +};
> +
> +static void remove_requests(gpointer user_data)
> +{
> + struct pns_req *req = user_data;
> +
> + g_free(req);
> +}
> +
> +static int connman_init(void)
> +{
> + DBG("");
> +
> + id = 0;
> + connection = ofono_dbus_get_connection();
> + requests = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
> + remove_requests);
> +
> + return ofono_private_network_driver_register(&pn_driver);
> +}
> +
> +static void connman_exit(void)
> +{
> + g_hash_table_destroy(requests);
> + ofono_private_network_driver_unregister(&pn_driver);
> +}
> +
> +OFONO_PLUGIN_DEFINE(connman, "ConnMan plugin", VERSION,
> + OFONO_PLUGIN_PRIORITY_DEFAULT, connman_init, connman_exit)
Regards,
-Denis
next prev parent reply other threads:[~2011-06-02 2:53 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-19 9:58 [PATCH_v6 0/5] Private network request to ConnMan Guillaume Zajac
2011-05-19 9:58 ` [PATCH_v6 1/5] gatppp: Add new contructor to use external fd Guillaume Zajac
2011-05-25 10:36 ` Denis Kenzior
2011-05-19 9:58 ` [PATCH_v6 2/5] private-network: add header into include and Makefile.am Guillaume Zajac
2011-05-25 10:38 ` Denis Kenzior
2011-05-19 9:58 ` [PATCH_v6 3/5] private-network: add request/release functions and new feature to Makefile.am Guillaume Zajac
2011-05-25 10:38 ` Denis Kenzior
2011-05-19 9:58 ` [PATCH_v6 4/5] emulator: add request/release private network calls Guillaume Zajac
2011-05-25 10:46 ` Denis Kenzior
2011-05-30 13:25 ` Guillaume Zajac
2011-05-19 9:58 ` [PATCH_v6 5/5] connman: add plugin in oFono to request/release private network Guillaume Zajac
2011-06-02 2:53 ` Denis Kenzior [this message]
-- strict thread matches above, loose matches on Subject: below --
2011-05-19 9:55 [PATCH_v6 0/5] *** SUBJECT HERE *** Guillaume Zajac
2011-05-19 9:55 ` [PATCH_v6 5/5] connman: add plugin in oFono to request/release private network Guillaume Zajac
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=4DE6FB32.90502@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox