2014-10-07 04:50:27 +02:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Wireless daemon for Linux
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013-2014 Intel Corporation. All rights reserved.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; 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
|
|
|
|
|
2016-04-01 04:27:37 +02:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdio.h>
|
2018-07-02 18:33:49 +02:00
|
|
|
#include <errno.h>
|
2016-04-01 04:27:37 +02:00
|
|
|
|
2014-10-07 04:50:27 +02:00
|
|
|
#include <ell/ell.h>
|
2016-04-01 04:27:37 +02:00
|
|
|
#include <ell/dbus-private.h>
|
2018-08-07 23:19:20 +02:00
|
|
|
|
|
|
|
#include "linux/nl80211.h"
|
|
|
|
|
2016-05-21 03:39:35 +02:00
|
|
|
#include "src/agent.h"
|
2017-05-03 19:53:51 +02:00
|
|
|
#include "src/iwd.h"
|
2018-08-07 23:19:20 +02:00
|
|
|
#include "src/dbus.h"
|
2014-10-07 04:50:27 +02:00
|
|
|
|
|
|
|
struct l_dbus *g_dbus = 0;
|
|
|
|
|
|
|
|
static void do_debug(const char *str, void *user_data)
|
|
|
|
{
|
|
|
|
const char *prefix = user_data;
|
|
|
|
|
|
|
|
l_info("%s%s", prefix, str);
|
|
|
|
}
|
|
|
|
|
2018-08-07 23:19:20 +02:00
|
|
|
const char *dbus_iftype_to_string(uint32_t iftype)
|
|
|
|
{
|
|
|
|
switch (iftype) {
|
|
|
|
case NL80211_IFTYPE_ADHOC:
|
|
|
|
return "ad-hoc";
|
|
|
|
case NL80211_IFTYPE_STATION:
|
|
|
|
return "station";
|
|
|
|
case NL80211_IFTYPE_AP:
|
|
|
|
return "ap";
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-10-28 05:42:43 +01:00
|
|
|
struct l_dbus_message *dbus_error_busy(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".InProgress",
|
|
|
|
"Operation already in progress");
|
|
|
|
}
|
|
|
|
|
2014-10-28 05:42:59 +01:00
|
|
|
struct l_dbus_message *dbus_error_failed(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".Failed",
|
|
|
|
"Operation failed");
|
|
|
|
}
|
|
|
|
|
2015-02-13 23:12:05 +01:00
|
|
|
struct l_dbus_message *dbus_error_aborted(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".Aborted",
|
|
|
|
"Operation aborted");
|
|
|
|
}
|
|
|
|
|
|
|
|
struct l_dbus_message *dbus_error_not_available(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".NotAvailable",
|
|
|
|
"Operation not available");
|
|
|
|
}
|
|
|
|
|
2015-02-24 16:23:19 +01:00
|
|
|
struct l_dbus_message *dbus_error_invalid_args(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".InvalidArgs",
|
|
|
|
"Argument type is wrong");
|
|
|
|
}
|
|
|
|
|
2017-02-21 22:46:26 +01:00
|
|
|
struct l_dbus_message *dbus_error_invalid_format(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".InvalidFormat",
|
|
|
|
"Argument format is invalid");
|
|
|
|
}
|
|
|
|
|
2015-02-24 16:23:19 +01:00
|
|
|
struct l_dbus_message *dbus_error_already_exists(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".AlreadyExists",
|
|
|
|
"Object already exists");
|
|
|
|
}
|
|
|
|
|
|
|
|
struct l_dbus_message *dbus_error_not_found(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".NotFound",
|
|
|
|
"Object not found");
|
|
|
|
}
|
|
|
|
|
2015-02-25 06:19:16 +01:00
|
|
|
struct l_dbus_message *dbus_error_not_supported(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".NotSupported",
|
|
|
|
"Operation not supported");
|
|
|
|
}
|
|
|
|
|
2015-03-20 21:42:39 +01:00
|
|
|
struct l_dbus_message *dbus_error_no_agent(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".NoAgent",
|
|
|
|
"No Agent registered");
|
|
|
|
}
|
|
|
|
|
2015-05-01 01:41:53 +02:00
|
|
|
struct l_dbus_message *dbus_error_not_connected(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".NotConnected",
|
|
|
|
"Not connected");
|
|
|
|
}
|
|
|
|
|
2017-10-26 22:25:59 +02:00
|
|
|
struct l_dbus_message *dbus_error_not_configured(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".NotConfigured",
|
|
|
|
"Not configured");
|
|
|
|
}
|
|
|
|
|
2015-09-28 18:27:33 +02:00
|
|
|
struct l_dbus_message *dbus_error_not_implemented(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".NotImplemented",
|
|
|
|
"Not implemented");
|
|
|
|
}
|
|
|
|
|
2018-06-28 01:33:01 +02:00
|
|
|
struct l_dbus_message *dbus_error_service_set_overlap(
|
|
|
|
struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".ServiceSetOverlap",
|
|
|
|
"Service set overlap");
|
|
|
|
}
|
|
|
|
|
2018-06-29 06:02:55 +02:00
|
|
|
struct l_dbus_message *dbus_error_already_provisioned(
|
|
|
|
struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".AlreadyProvisioned",
|
|
|
|
"Already provisioned");
|
|
|
|
}
|
|
|
|
|
|
|
|
struct l_dbus_message *dbus_error_not_hidden(struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
return l_dbus_message_new_error(msg, IWD_SERVICE ".NotHidden",
|
|
|
|
"Not hidden");
|
|
|
|
}
|
|
|
|
|
2018-07-02 18:33:49 +02:00
|
|
|
struct l_dbus_message *dbus_error_from_errno(int err,
|
|
|
|
struct l_dbus_message *msg)
|
|
|
|
{
|
|
|
|
switch (err) {
|
|
|
|
case -EBUSY:
|
|
|
|
return dbus_error_busy(msg);
|
|
|
|
case -ECANCELED:
|
|
|
|
return dbus_error_aborted(msg);
|
|
|
|
case -ERFKILL:
|
|
|
|
return dbus_error_not_available(msg);
|
|
|
|
case -EINVAL:
|
|
|
|
return dbus_error_invalid_args(msg);
|
|
|
|
case -EBADMSG:
|
|
|
|
return dbus_error_invalid_format(msg);
|
|
|
|
case -EEXIST:
|
|
|
|
return dbus_error_already_exists(msg);
|
|
|
|
case -ENOENT:
|
|
|
|
return dbus_error_not_found(msg);
|
|
|
|
case -ENOTSUP:
|
|
|
|
return dbus_error_not_supported(msg);
|
|
|
|
/* TODO: no_agent */
|
|
|
|
case -ENOKEY:
|
|
|
|
return dbus_error_not_configured(msg);
|
|
|
|
case -ENOTCONN:
|
|
|
|
return dbus_error_not_connected(msg);
|
|
|
|
case -ENOSYS:
|
|
|
|
return dbus_error_not_implemented(msg);
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dbus_error_failed(msg);
|
|
|
|
}
|
|
|
|
|
2014-10-28 05:42:05 +01:00
|
|
|
void dbus_pending_reply(struct l_dbus_message **msg,
|
|
|
|
struct l_dbus_message *reply)
|
|
|
|
{
|
|
|
|
struct l_dbus *dbus = dbus_get_bus();
|
|
|
|
|
|
|
|
l_dbus_send(dbus, reply);
|
|
|
|
l_dbus_message_unref(*msg);
|
|
|
|
*msg = NULL;
|
|
|
|
}
|
|
|
|
|
2016-04-01 04:27:40 +02:00
|
|
|
static void request_name_callback(struct l_dbus *dbus, bool success,
|
|
|
|
bool queued, void *user_data)
|
2014-10-07 04:50:27 +02:00
|
|
|
{
|
2016-04-01 04:27:40 +02:00
|
|
|
if (!success)
|
|
|
|
l_error("Name request failed");
|
2014-10-07 04:50:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ready_callback(void *user_data)
|
|
|
|
{
|
2016-04-01 04:27:40 +02:00
|
|
|
l_dbus_name_acquire(g_dbus, "net.connman.iwd", false, false, true,
|
|
|
|
request_name_callback, NULL);
|
|
|
|
|
2016-05-21 03:39:34 +02:00
|
|
|
if (!l_dbus_object_manager_enable(g_dbus))
|
|
|
|
l_info("Unable to register the ObjectManager");
|
|
|
|
|
2016-05-21 03:39:35 +02:00
|
|
|
agent_init(g_dbus);
|
2014-10-07 04:50:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void disconnect_callback(void *user_data)
|
|
|
|
{
|
|
|
|
l_info("D-Bus disconnected, quitting...");
|
2017-05-03 19:53:51 +02:00
|
|
|
iwd_shutdown();
|
2014-10-07 04:50:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct l_dbus *dbus_get_bus(void)
|
|
|
|
{
|
|
|
|
return g_dbus;
|
|
|
|
}
|
|
|
|
|
2016-10-16 19:41:27 +02:00
|
|
|
bool dbus_init(bool enable_debug)
|
2014-10-07 04:50:27 +02:00
|
|
|
{
|
2016-10-16 19:41:27 +02:00
|
|
|
g_dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
|
main: don't crash if DBus is not running
dbus_init() currently does not check for the g_dbus object being
properly initialized and this leads to crashes when dbus is not yet
running.
Ensure g_dbus is properly initialized and return false otherwise.
In this case the caller can understand that something went wrong and
stop the initialization procedure.
Program received signal SIGSEGV, Segmentation fault.
0x00005555555bc089 in l_dbus_add_service_watch (dbus=0x0,
name=0x5555555e5b0a "org.ofono",
connect_func=0x5555555aa81e <ofono_found>,
disconnect_func=0x5555555aa8e6 <ofono_disappeared>,
user_data=0x0, destroy=0x0) at ell/dbus.c:1621
1621 if (!dbus->name_cache)
(gdb) bt
name=0x5555555e5b0a "org.ofono",
connect_func=0x5555555aa81e <ofono_found>,
disconnect_func=0x5555555aa8e6 <ofono_disappeared>,
user_data=0x0, destroy=0x0) at ell/dbus.c:1621
user_data=0x0) at ell/plugin.c:115
function=0x5555555b40fd <plugin_start>,
user_data=0x0) at ell/queue.c:441
version=0x0) at ell/plugin.c:201
src/plugin.c:82
src/main.c:417
2018-06-15 16:30:27 +02:00
|
|
|
if (!g_dbus)
|
|
|
|
return false;
|
2014-11-08 04:42:58 +01:00
|
|
|
|
|
|
|
if (enable_debug)
|
|
|
|
l_dbus_set_debug(g_dbus, do_debug, "[DBUS] ", NULL);
|
|
|
|
|
2014-10-07 04:50:27 +02:00
|
|
|
l_dbus_set_ready_handler(g_dbus, ready_callback, g_dbus, NULL);
|
|
|
|
l_dbus_set_disconnect_handler(g_dbus, disconnect_callback, NULL, NULL);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool dbus_exit(void)
|
|
|
|
{
|
2016-05-21 03:39:35 +02:00
|
|
|
agent_exit(g_dbus);
|
|
|
|
|
2014-10-07 04:50:27 +02:00
|
|
|
l_dbus_destroy(g_dbus);
|
|
|
|
g_dbus = NULL;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2016-05-25 01:37:19 +02:00
|
|
|
|
|
|
|
void dbus_shutdown(void)
|
|
|
|
{
|
|
|
|
/* Allow AgentManager to send a Release call before disconnecting */
|
|
|
|
agent_shutdown();
|
|
|
|
}
|