blob: c4652e4d3f67a5bb3aa20d32306001f89e125b98 [file] [edit]
/*
*
* Copyright (c) 2016 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <algorithm>
#include <boost/bind.hpp>
#include <dbus/dbus.h>
#include <syslog.h>
#include "wpan-dbus-v1.h"
#include "DBusIPCAPI_v1.h"
#include "wpan-error.h"
#include "NCPControlInterface.h"
#include "NCPMfgInterface_v1.h"
#include "assert-macros.h"
#include "DBUSHelpers.h"
#include "any-to.h"
using namespace DBUSHelpers;
using namespace nl;
using namespace nl::wpantund;
DBusIPCAPI_v1::DBusIPCAPI_v1(DBusConnection *connection)
:mConnection(connection)
{
dbus_connection_ref(mConnection);
init_callback_tables();
}
DBusIPCAPI_v1::~DBusIPCAPI_v1()
{
dbus_connection_unref(mConnection);
}
void
DBusIPCAPI_v1::init_callback_tables()
{
#define INTERFACE_CALLBACK_CONNECT(cmd_name, member_func) \
mInterfaceCallbackTable[(cmd_name)] = boost::bind( \
&DBusIPCAPI_v1::member_func, this, _1, _2)
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_RESET, interface_reset_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_STATUS, interface_status_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_JOIN, interface_join_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_FORM, interface_form_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_LEAVE, interface_leave_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ATTACH, interface_attach_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ROUTE_ADD, interface_route_add_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ROUTE_REMOVE, interface_route_remove_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_SERVICE_ADD, service_add_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_SERVICE_REMOVE, service_remove_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_DATA_POLL, interface_data_poll_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_CONFIG_GATEWAY, interface_config_gateway_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_BEGIN_LOW_POWER, interface_begin_low_power_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_HOST_DID_WAKE, interface_host_did_wake_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_NET_SCAN_STOP, interface_net_scan_stop_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_NET_SCAN_START, interface_net_scan_start_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_DISCOVER_SCAN_STOP, interface_discover_scan_stop_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_DISCOVER_SCAN_START, interface_discover_scan_start_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ENERGY_SCAN_STOP, interface_energy_scan_stop_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ENERGY_SCAN_START, interface_energy_scan_start_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_MFG, interface_mfg_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PROP_GET, interface_prop_get_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PROP_SET, interface_prop_set_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PROP_INSERT, interface_prop_insert_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PROP_REMOVE, interface_prop_remove_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PCAP_TO_FD, interface_pcap_to_fd_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PCAP_TERMINATE, interface_pcap_terminate_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_JOINER_ATTACH, interface_joiner_attach_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_JOINER_START, interface_joiner_start_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_JOINER_STOP, interface_joiner_stop_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_JOINER_COMMISSIONING, interface_joiner_commissioning_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_JOINER_ADD, interface_joiner_add_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_JOINER_REMOVE, interface_joiner_remove_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ANNOUNCE_BEGIN, interface_announce_begin_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ENERGY_SCAN_QUERY, interface_energy_scan_query_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PAN_ID_QUERY, interface_pan_id_query_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_GENERATE_PSKC, interface_generate_pskc);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PEEK, interface_peek_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_POKE, interface_poke_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_LINK_METRICS_QUERY, interface_link_metrics_query_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_LINK_METRICS_PROBE, interface_link_metrics_probe_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_LINK_METRICS_MGMT_FORWARD, interface_link_metrics_mgmt_forward_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_LINK_METRICS_MGMT_ENH_ACK, interface_link_metrics_mgmt_enh_ack_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_MLR_REQUEST, interface_mlr_request_handler);
INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_BACKBONE_ROUTER_CONFIG, interface_backbone_router_config_handler);
}
static void
ObjectPathUnregisterFunction_cb(DBusConnection *connection, void *user_data)
{
delete (std::pair<NCPControlInterface*, DBusIPCAPI_v1*> *)user_data;
}
std::string
DBusIPCAPI_v1::path_for_iface(NCPControlInterface* interface)
{
return std::string(WPANTUND_DBUS_PATH) + "/" + interface->get_name();
}
int
DBusIPCAPI_v1::add_interface(NCPControlInterface* interface)
{
static const DBusObjectPathVTable ipc_interface_vtable = {
&ObjectPathUnregisterFunction_cb,
&DBusIPCAPI_v1::dbus_message_handler,
};
std::string name = interface->get_name();
std::string path = std::string(WPANTUND_DBUS_PATH) + "/" + name;
std::pair<NCPControlInterface*, DBusIPCAPI_v1*> *cb_data =
new std::pair<NCPControlInterface*, DBusIPCAPI_v1*>(interface, this);
require(dbus_connection_register_object_path(
mConnection,
path.c_str(),
&ipc_interface_vtable,
(void*)cb_data
), bail);
interface->mOnPropertyChanged.connect(
boost::bind(
&DBusIPCAPI_v1::property_changed,
this,
interface,
_1,
_2
)
);
interface->mOnNetScanBeacon.connect(
boost::bind(
&DBusIPCAPI_v1::received_beacon,
this,
interface,
_1
)
);
interface->mOnEnergyScanResult.connect(
boost::bind(
&DBusIPCAPI_v1::received_energy_scan_result,
this,
interface,
_1
)
);
interface->mOnNetworkTimeUpdate.connect(
boost::bind(
&DBusIPCAPI_v1::received_network_time_update,
this,
interface,
_1
)
);
bail:
return 0;
}
void
DBusIPCAPI_v1::CallbackWithStatus_Helper(int ret, DBusMessage *original_message)
{
DBusMessage *reply = dbus_message_new_method_return(original_message);
syslog(LOG_DEBUG, "Sending DBus response for \"%s\" to \"%s\"", dbus_message_get_member(original_message), dbus_message_get_sender(original_message));
if(reply) {
dbus_message_append_args(
reply,
DBUS_TYPE_INT32, &ret,
DBUS_TYPE_INVALID
);
dbus_connection_send(mConnection, reply, NULL);
dbus_message_unref(reply);
}
dbus_message_unref(original_message);
}
static void
ipc_append_network_properties(
DBusMessageIter *iter, const WPAN::NetworkInstance& network
)
{
const char* network_name = network.name.c_str();
if (network_name[0]) {
append_dict_entry(
iter,
kWPANTUNDProperty_NetworkName,
DBUS_TYPE_STRING,
&network_name
);
}
if (network.get_xpanid_as_uint64() != 0) {
uint64_t xpan_id = network.get_xpanid_as_uint64();
append_dict_entry(
iter,
kWPANTUNDProperty_NetworkXPANID,
DBUS_TYPE_UINT64,
&xpan_id
);
}
{
uint16_t pan_id = network.panid;
append_dict_entry(
iter,
kWPANTUNDProperty_NetworkPANID,
DBUS_TYPE_UINT16,
&pan_id
);
}
if (network.type != 0) {
int32_t type = network.type;
append_dict_entry(
iter,
kWPANTUNDProperty_NetworkNodeType,
DBUS_TYPE_INT32,
&type
);
}
if (network.channel) {
uint16_t channel = network.channel;
append_dict_entry(
iter,
kWPANTUNDProperty_NCPChannel,
DBUS_TYPE_INT16,
&channel
);
if (network.rssi != -128) {
int8_t rssi = network.rssi;
append_dict_entry(iter, "RSSI", DBUS_TYPE_BYTE, &rssi);
}
}
if (network.get_hwaddr_as_uint64() != 0) {
append_dict_entry(
iter,
kWPANTUNDProperty_NCPHardwareAddress,
nl::Data(network.hwaddr, 8)
);
}
}
static void
ipc_append_network_dict(
DBusMessageIter *iter, const WPAN::NetworkInstance& network
)
{
DBusMessageIter dict;
dbus_message_iter_open_container(
iter,
DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
&dict
);
ipc_append_network_properties(&dict, network);
dbus_message_iter_close_container(iter, &dict);
}
void
DBusIPCAPI_v1::received_beacon(NCPControlInterface* interface, const WPAN::NetworkInstance& network)
{
DBusMessageIter iter;
DBusMessage* signal;
signal = dbus_message_new_signal(
path_for_iface(interface).c_str(),
WPANTUND_DBUS_APIv1_INTERFACE,
WPANTUND_IF_SIGNAL_NET_SCAN_BEACON
);
dbus_message_iter_init_append(signal, &iter);
ipc_append_network_dict(&iter, network);
dbus_connection_send(mConnection, signal, NULL);
dbus_message_unref(signal);
}
void
DBusIPCAPI_v1::received_network_time_update(
NCPControlInterface* interface, const ValueMap &network_time_update)
{
DBusMessageIter iter;
DBusMessage* signal;
signal = dbus_message_new_signal(
path_for_iface(interface).c_str(),
WPANTUND_DBUS_APIv1_INTERFACE,
WPANTUND_IF_SIGNAL_NETWORK_TIME_UPDATE
);
dbus_message_iter_init_append(signal, &iter);
append_any_to_dbus_iter(&iter, network_time_update);
dbus_connection_send(mConnection, signal, NULL);
dbus_message_unref(signal);
}
static void
ipc_append_energy_scan_result_dict(
DBusMessageIter *iter, const EnergyScanResultEntry& energy_scan_result
)
{
uint16_t channel = energy_scan_result.mChannel;
int16_t maxRssi = static_cast<int16_t>(energy_scan_result.mMaxRssi);
DBusMessageIter dict;
dbus_message_iter_open_container(
iter,
DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
&dict
);
append_dict_entry(&dict, kWPANTUNDProperty_NCPChannel, DBUS_TYPE_INT16, &channel);
append_dict_entry(&dict, "RSSI", DBUS_TYPE_BYTE, &maxRssi);
dbus_message_iter_close_container(iter, &dict);
}
void
DBusIPCAPI_v1::received_energy_scan_result(NCPControlInterface* interface,
const EnergyScanResultEntry& energy_scan_result)
{
DBusMessageIter iter;
DBusMessage* signal;
signal = dbus_message_new_signal(
path_for_iface(interface).c_str(),
WPANTUND_DBUS_APIv1_INTERFACE,
WPANTUND_IF_SIGNAL_ENERGY_SCAN_RESULT
);
dbus_message_iter_init_append(signal, &iter);
ipc_append_energy_scan_result_dict(&iter, energy_scan_result);
dbus_connection_send(mConnection, signal, NULL);
dbus_message_unref(signal);
}
void
DBusIPCAPI_v1::property_changed(NCPControlInterface* interface,const std::string& key, const boost::any& value)
{
DBusMessageIter iter;
DBusMessage* signal;
std::string key_as_path;
std::string path;
// Transform the key into a DBus-compatible path
for (std::string::const_iterator i = key.begin();
i != key.end();
++i
) {
const char c = *i;
if (isalnum(c) || (c == '_')) {
key_as_path += c;
} else if (c == ':') {
key_as_path += '/';
} else if (c == '.') {
key_as_path += '_';
}
}
path = path_for_iface(interface) + "/Property/" + key_as_path;
syslog(LOG_DEBUG, "DBusAPIv1:PropChanged: %s - value: %s", path.c_str(), any_to_string(value).c_str());
signal = dbus_message_new_signal(
path.c_str(),
WPANTUND_DBUS_APIv1_INTERFACE,
WPANTUND_IF_SIGNAL_PROP_CHANGED
);
if (signal) {
dbus_message_iter_init_append(signal, &iter);
append_any_to_dbus_iter(&iter, key);
append_any_to_dbus_iter(&iter, value);
dbus_connection_send(mConnection, signal, NULL);
dbus_message_unref(signal);
}
}
void
DBusIPCAPI_v1::status_response_helper(
int ret, NCPControlInterface* interface, DBusMessage *message
)
{
DBusMessage *reply = dbus_message_new_method_return(message);
if (reply) {
DBusMessageIter iter;
dbus_message_iter_init_append(reply, &iter);
DBusMessageIter dict;
boost::any value;
NCPState ncp_state = UNINITIALIZED;
std::string ncp_state_string;
const char* ncp_state_cstr = kWPANTUNDStateUninitialized;
dbus_message_iter_open_container(
&iter,
DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
&dict
);
value = interface->property_get_value(kWPANTUNDProperty_NCPState);
if (!value.empty()) {
ncp_state_string = any_to_string(value);
ncp_state = string_to_ncp_state(ncp_state_string);
ncp_state_cstr = ncp_state_string.c_str();
}
append_dict_entry(&dict,
kWPANTUNDProperty_NCPState,
DBUS_TYPE_STRING,
&ncp_state_cstr);
value = interface->property_get_value(kWPANTUNDProperty_DaemonEnabled);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_DaemonEnabled, value);
}
value = interface->property_get_value(kWPANTUNDProperty_NCPVersion);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_NCPVersion, value);
}
value = interface->property_get_value(kWPANTUNDProperty_POSIXAppRCPVersionCached);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_POSIXAppRCPVersion, value);
}
value = interface->property_get_value(kWPANTUNDProperty_DaemonVersion);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_DaemonVersion, value);
}
value = interface->property_get_value(kWPANTUNDProperty_ConfigNCPDriverName);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_ConfigNCPDriverName, value);
}
value = interface->property_get_value(kWPANTUNDProperty_NCPHardwareAddress);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_NCPHardwareAddress, value);
}
if (ncp_state_is_commissioned(ncp_state))
{
value = interface->property_get_value(kWPANTUNDProperty_NCPChannel);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_NCPChannel, value);
}
value = interface->property_get_value(kWPANTUNDProperty_NetworkNodeType);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_NetworkNodeType, value);
}
value = interface->property_get_value(kWPANTUNDProperty_NetworkName);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_NetworkName, value);
}
value = interface->property_get_value(kWPANTUNDProperty_NetworkXPANID);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_NetworkXPANID, value);
}
value = interface->property_get_value(kWPANTUNDProperty_NetworkPANID);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_NetworkPANID, value);
}
value = interface->property_get_value(kWPANTUNDProperty_IPv6LinkLocalAddress);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_IPv6LinkLocalAddress, value);
}
value = interface->property_get_value(kWPANTUNDProperty_IPv6MeshLocalAddress);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_IPv6MeshLocalAddress, value);
}
value = interface->property_get_value(kWPANTUNDProperty_IPv6MeshLocalPrefix);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_IPv6MeshLocalPrefix, value);
}
value = interface->property_get_value(kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress, value);
}
value = interface->property_get_value(kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix);
if (!value.empty()) {
append_dict_entry(&dict, kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix, value);
}
}
dbus_message_iter_close_container(&iter, &dict);
dbus_connection_send(mConnection, reply, NULL);
dbus_message_unref(reply);
}
dbus_message_unref(message);
}
void
DBusIPCAPI_v1::CallbackWithStatusArg1_Helper(
int status, const boost::any& value, DBusMessage *message
)
{
DBusMessage *reply = dbus_message_new_method_return(message);
DBusMessageIter iter;
dbus_message_iter_init_append(reply, &iter);
if (!status && value.empty()) {
status = kWPANTUNDStatus_PropertyEmpty;
}
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &status);
if (value.empty()) {
append_any_to_dbus_iter(&iter, std::string("<empty>"));
} else {
append_any_to_dbus_iter(&iter, value);
}
dbus_connection_send(mConnection, reply, NULL);
dbus_message_unref(message);
dbus_message_unref(reply);
}
DBusHandlerResult
DBusIPCAPI_v1::interface_reset_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->reset(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_status_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
NCPState ncp_state = UNINITIALIZED;
boost::any value(interface->property_get_value(kWPANTUNDProperty_NCPState));
if (!value.empty()) {
ncp_state = string_to_ncp_state(any_to_string(value));
}
if (ncp_state_is_sleeping(ncp_state)
|| ncp_state_is_detached_from_ncp(ncp_state)
|| (ncp_state == UNINITIALIZED)
) {
status_response_helper(0, interface, message);
} else {
interface->refresh_state(boost::bind(&DBusIPCAPI_v1::
status_response_helper, this, _1, interface, message));
}
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_join_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
ValueMap options;
DBusMessageIter iter;
dbus_message_iter_init(message, &iter);
options = value_map_from_dbus_iter(&iter);
dbus_message_ref(message);
interface->join(
options,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_form_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
ValueMap options;
DBusMessageIter iter;
dbus_message_iter_init(message, &iter);
options = value_map_from_dbus_iter(&iter);
dbus_message_ref(message);
interface->form(
options,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_leave_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->leave(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_attach_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->attach(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_begin_low_power_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->begin_low_power(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_host_did_wake_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->host_did_wake(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_net_scan_stop_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->netscan_stop(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_discover_scan_stop_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->netscan_stop(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_energy_scan_stop_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->energyscan_stop(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_mfg_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
NCPMfgInterface_v1* mfg_interface(dynamic_cast<NCPMfgInterface_v1*>(interface));
const char *mfg_command_cstr = "";
std::string mfg_command;
dbus_message_get_args(
message, NULL,
DBUS_TYPE_STRING, &mfg_command_cstr,
DBUS_TYPE_INVALID
);
mfg_command = mfg_command_cstr;
dbus_message_ref(message);
mfg_interface->mfg(
mfg_command,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatusArg1_Helper,
this,
_1,
_2,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_prop_get_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
const char* property_key_cstr = "";
std::string property_key;
dbus_message_get_args(
message, NULL,
DBUS_TYPE_STRING, &property_key_cstr,
DBUS_TYPE_INVALID
);
property_key = property_key_cstr;
if (interface->translate_deprecated_property(property_key)) {
syslog(LOG_WARNING, "PropGet: Property \"%s\" is deprecated. Please use \"%s\" instead.", property_key_cstr, property_key.c_str());
}
dbus_message_ref(message);
interface->property_get_value(
property_key,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatusArg1_Helper,
this,
_1,
_2,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_prop_set_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
DBusMessageIter iter;
const char* property_key_cstr = "";
std::string property_key;
boost::any property_value;
dbus_message_iter_init(message, &iter);
require (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING, bail);
dbus_message_iter_get_basic(&iter, &property_key_cstr);
dbus_message_iter_next(&iter);
property_value = any_from_dbus_iter(&iter);
property_key = property_key_cstr;
if (interface->translate_deprecated_property(property_key, property_value)) {
syslog(LOG_WARNING, "PropSet: Property \"%s\" is deprecated. Please use \"%s\" instead.", property_key_cstr, property_key.c_str());
}
dbus_message_ref(message);
interface->property_set_value(
property_key,
property_value,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_prop_insert_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
DBusMessageIter iter;
const char* property_key_cstr = "";
std::string property_key;
boost::any property_value;
dbus_message_iter_init(message, &iter);
require (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING, bail);
dbus_message_iter_get_basic(&iter, &property_key_cstr);
dbus_message_iter_next(&iter);
property_value = any_from_dbus_iter(&iter);
property_key = property_key_cstr;
if (interface->translate_deprecated_property(property_key, property_value)) {
syslog(LOG_WARNING, "PropeInsert: Property \"%s\" is deprecated. Please use \"%s\" instead.", property_key_cstr, property_key.c_str());
}
dbus_message_ref(message);
interface->property_insert_value(
property_key,
property_value,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_prop_remove_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
DBusMessageIter iter;
const char* property_key_cstr = "";
std::string property_key;
boost::any property_value;
dbus_message_iter_init(message, &iter);
require (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING, bail);
dbus_message_iter_get_basic(&iter, &property_key_cstr);
dbus_message_iter_next(&iter);
property_value = any_from_dbus_iter(&iter);
property_key = property_key_cstr;
if (interface->translate_deprecated_property(property_key, property_value)) {
syslog(LOG_WARNING, "PropRemove: Property \"%s\" is deprecated. Please use \"%s\" instead.", property_key_cstr, property_key.c_str());
}
dbus_message_ref(message);
interface->property_remove_value(
property_key,
property_value,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_net_scan_start_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
ValueMap options;
NCPControlInterface::ChannelMask channel_mask = 0;
dbus_message_ref(message);
dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &channel_mask,
DBUS_TYPE_INVALID
);
if (channel_mask) {
options[kWPANTUNDValueMapKey_Scan_ChannelMask] = channel_mask;
}
interface->netscan_start(
options,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_discover_scan_start_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
ValueMap options;
NCPControlInterface::ChannelMask channel_mask = 0;
dbus_bool_t joiner_flag = FALSE;
dbus_bool_t enable_filtering = FALSE;
uint16_t pan_id_filter = 0xffff;
dbus_message_ref(message);
dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &channel_mask,
DBUS_TYPE_BOOLEAN, &joiner_flag,
DBUS_TYPE_BOOLEAN, &enable_filtering,
DBUS_TYPE_UINT16, &pan_id_filter,
DBUS_TYPE_INVALID
);
options[kWPANTUNDValueMapKey_Scan_Discover] = true;
if (channel_mask) {
options[kWPANTUNDValueMapKey_Scan_ChannelMask] = channel_mask;
}
options[kWPANTUNDValueMapKey_Scan_JoinerFalg] = joiner_flag ? true : false;
options[kWPANTUNDValueMapKey_Scan_EnableFiltering] = enable_filtering ? true : false;
options[kWPANTUNDValueMapKey_Scan_PANIDFilter] = pan_id_filter;
interface->netscan_start(
options,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_energy_scan_start_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
ValueMap options;
NCPControlInterface::ChannelMask channel_mask = 0;
dbus_message_ref(message);
dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &channel_mask,
DBUS_TYPE_INVALID
);
if (channel_mask) {
options[kWPANTUNDProperty_NCPChannelMask] = channel_mask;
}
interface->energyscan_start(
options,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_pcap_to_fd_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
int fd = -1;
dbus_message_ref(message);
dbus_message_get_args(
message, NULL,
DBUS_TYPE_UNIX_FD, &fd,
DBUS_TYPE_INVALID
);
interface->pcap_to_fd(
fd,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_pcap_terminate_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->pcap_terminate(
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_data_poll_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_message_ref(message);
interface->data_poll(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_config_gateway_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_bool_t default_route = FALSE;
dbus_bool_t preferred = TRUE;
dbus_bool_t slaac = TRUE;
dbus_bool_t on_mesh = TRUE;
dbus_bool_t dhcp = FALSE;
dbus_bool_t configure = FALSE;
dbus_bool_t stable = TRUE;
dbus_bool_t nd_dns = FALSE;
dbus_bool_t domain_prefix = FALSE;
uint32_t preferred_lifetime = 0;
uint32_t valid_lifetime = 0;
uint8_t *prefix(NULL);
int prefix_len_in_bytes(0);
struct in6_addr address = {};
bool did_succeed(false);
int16_t priority_raw(0);
NCPControlInterface::OnMeshPrefixPriority priority(NCPControlInterface::PREFIX_MEDIUM_PREFERENCE);
NCPControlInterface::OnMeshPrefixFlags flags;
uint16_t prefix_len_in_bits = 0;
const uint16_t max_prefix_len_in_bits = 64;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_BOOLEAN, &default_route,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &prefix, &prefix_len_in_bytes,
DBUS_TYPE_UINT32, &preferred_lifetime,
DBUS_TYPE_UINT32, &valid_lifetime,
DBUS_TYPE_BOOLEAN, &preferred,
DBUS_TYPE_BOOLEAN, &slaac,
DBUS_TYPE_BOOLEAN, &on_mesh,
DBUS_TYPE_INT16, &priority_raw,
DBUS_TYPE_BOOLEAN, &dhcp,
DBUS_TYPE_BOOLEAN, &configure,
DBUS_TYPE_BOOLEAN, &stable,
DBUS_TYPE_UINT16, &prefix_len_in_bits,
DBUS_TYPE_BOOLEAN, &nd_dns,
DBUS_TYPE_BOOLEAN, &domain_prefix,
DBUS_TYPE_INVALID
);
if (!did_succeed) {
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_BOOLEAN, &default_route,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &prefix, &prefix_len_in_bytes,
DBUS_TYPE_UINT32, &preferred_lifetime,
DBUS_TYPE_UINT32, &valid_lifetime,
DBUS_TYPE_BOOLEAN, &preferred,
DBUS_TYPE_BOOLEAN, &slaac,
DBUS_TYPE_BOOLEAN, &on_mesh,
DBUS_TYPE_INT16, &priority_raw,
DBUS_TYPE_BOOLEAN, &dhcp,
DBUS_TYPE_BOOLEAN, &configure,
DBUS_TYPE_BOOLEAN, &stable,
DBUS_TYPE_UINT16, &prefix_len_in_bits,
DBUS_TYPE_INVALID
);
}
if (!did_succeed) {
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_BOOLEAN, &default_route,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &prefix, &prefix_len_in_bytes,
DBUS_TYPE_UINT32, &preferred_lifetime,
DBUS_TYPE_UINT32, &valid_lifetime,
DBUS_TYPE_BOOLEAN, &preferred,
DBUS_TYPE_BOOLEAN, &slaac,
DBUS_TYPE_BOOLEAN, &on_mesh,
DBUS_TYPE_INT16, &priority_raw,
DBUS_TYPE_INVALID
);
prefix_len_in_bits = static_cast<uint16_t>(IPV6_PREFIX_BYTES_TO_BITS(prefix_len_in_bytes));
if (prefix_len_in_bits > max_prefix_len_in_bits) {
prefix_len_in_bits = max_prefix_len_in_bits;
}
}
if (!did_succeed) {
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_BOOLEAN, &default_route,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &prefix, &prefix_len_in_bytes,
DBUS_TYPE_UINT32, &preferred_lifetime,
DBUS_TYPE_UINT32, &valid_lifetime,
DBUS_TYPE_INVALID
);
prefix_len_in_bits = static_cast<uint16_t>(IPV6_PREFIX_BYTES_TO_BITS(prefix_len_in_bytes));
if (prefix_len_in_bits > max_prefix_len_in_bits) {
prefix_len_in_bits = max_prefix_len_in_bits;
}
}
require(did_succeed, bail);
require(prefix_len_in_bytes <= sizeof(address), bail);
require(prefix_len_in_bytes >= 0, bail);
require(prefix_len_in_bits <= max_prefix_len_in_bits, bail);
require(prefix_len_in_bits > 0, bail);
require(prefix_len_in_bits <= IPV6_PREFIX_BYTES_TO_BITS(prefix_len_in_bytes), bail);
memcpy(address.s6_addr, prefix, prefix_len_in_bytes);
if (priority_raw > 0) {
priority = NCPControlInterface::PREFIX_HIGH_PREFERENCE;
} else if (priority_raw < 0) {
priority = NCPControlInterface::PREFIX_LOW_PREFRENCE;
}
if (default_route) {
flags.insert(NCPControlInterface::PREFIX_FLAG_DEFAULT_ROUTE);
}
if (preferred) {
flags.insert(NCPControlInterface::PREFIX_FLAG_PREFERRED);
}
if (slaac) {
flags.insert(NCPControlInterface::PREFIX_FLAG_SLAAC);
}
if (on_mesh) {
flags.insert(NCPControlInterface::PREFIX_FLAG_ON_MESH);
}
if (dhcp) {
flags.insert(NCPControlInterface::PREFIX_FLAG_DHCP);
}
if (configure) {
flags.insert(NCPControlInterface::PREFIX_FLAG_CONFIGURE);
}
if (nd_dns) {
flags.insert(NCPControlInterface::PREFIX_FLAG_ND_DNS);
}
if (domain_prefix) {
flags.insert(NCPControlInterface::PREFIX_FLAG_DOMAIN_PREFIX);
}
dbus_message_ref(message);
if (valid_lifetime == 0) {
interface->remove_on_mesh_prefix(
address,
static_cast<uint8_t>(prefix_len_in_bits),
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,this, _1, message)
);
} else {
interface->add_on_mesh_prefix(
address,
static_cast<uint8_t>(prefix_len_in_bits),
flags,
priority,
stable,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,this, _1, message)
);
}
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::service_add_handler(
NCPControlInterface *interface,
DBusMessage *message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
bool did_succeed;
uint32_t enterprise_number;
uint8_t *service_data;
int service_data_len;
dbus_bool_t stable;
uint8_t *server_data;
int server_data_len;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &enterprise_number,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &service_data, &service_data_len,
DBUS_TYPE_BOOLEAN, &stable,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &server_data, &server_data_len,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
dbus_message_ref(message);
interface->add_service(
enterprise_number,
Data(service_data, service_data_len),
stable,
Data(server_data, server_data_len),
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::service_remove_handler(
NCPControlInterface *interface,
DBusMessage *message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
bool did_succeed;
uint32_t enterprise_number;
uint8_t *service_data;
int service_data_len;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &enterprise_number,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &service_data, &service_data_len,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
dbus_message_ref(message);
interface->remove_service(
enterprise_number,
Data(service_data, service_data_len),
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message));
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_route_add_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
uint8_t *route_prefix(NULL);
int prefix_len_in_bytes(0);
uint16_t domain_id(0);
int16_t priority_raw(0);
NCPControlInterface::ExternalRoutePriority priority(NCPControlInterface::ROUTE_MEDIUM_PREFERENCE);
dbus_bool_t stable(TRUE);
uint8_t prefix_len_in_bits(0);
struct in6_addr address = {};
bool did_succeed(false);
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &route_prefix, &prefix_len_in_bytes,
DBUS_TYPE_UINT16, &domain_id,
DBUS_TYPE_INT16, &priority_raw,
DBUS_TYPE_BYTE, &prefix_len_in_bits,
DBUS_TYPE_BOOLEAN, &stable,
DBUS_TYPE_INVALID
);
if (!did_succeed) {
// Check the syntax without the `stable` argument
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &route_prefix, &prefix_len_in_bytes,
DBUS_TYPE_UINT16, &domain_id,
DBUS_TYPE_INT16, &priority_raw,
DBUS_TYPE_BYTE, &prefix_len_in_bits,
DBUS_TYPE_INVALID
);
}
if (!did_succeed) {
// Likely using the old syntax that doesn't include the prefix length in bits
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &route_prefix, &prefix_len_in_bytes,
DBUS_TYPE_UINT16, &domain_id,
DBUS_TYPE_INT16, &priority_raw,
DBUS_TYPE_INVALID
);
prefix_len_in_bits = IPV6_PREFIX_BYTES_TO_BITS(prefix_len_in_bytes);
}
require(did_succeed, bail);
require(prefix_len_in_bytes <= sizeof(address), bail);
require(prefix_len_in_bytes >= 0, bail);
memcpy(address.s6_addr, route_prefix, prefix_len_in_bytes);
if (priority_raw > 0) {
priority = NCPControlInterface::ROUTE_HIGH_PREFERENCE;
} else if (priority_raw < 0) {
priority = NCPControlInterface::ROUTE_LOW_PREFRENCE;
}
dbus_message_ref(message);
interface->add_external_route(
&address,
prefix_len_in_bits,
domain_id,
priority,
stable,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_route_remove_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
uint8_t *route_prefix = NULL;
int prefix_len_in_bytes(0);
uint8_t prefix_len_in_bits(0);
uint16_t domain_id = 0;
struct in6_addr address = {};
bool did_succeed(false);
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &route_prefix, &prefix_len_in_bytes,
DBUS_TYPE_UINT16, &domain_id,
DBUS_TYPE_BYTE, &prefix_len_in_bits,
DBUS_TYPE_INVALID
);
if (!did_succeed) {
// Likely using the old syntax that doesn't include the prefix length in bits
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &route_prefix, &prefix_len_in_bytes,
DBUS_TYPE_UINT16, &domain_id,
DBUS_TYPE_INVALID
);
prefix_len_in_bits = IPV6_PREFIX_BYTES_TO_BITS(prefix_len_in_bytes);
}
require(did_succeed, bail);
require(prefix_len_in_bytes <= sizeof(address), bail);
require(prefix_len_in_bytes >= 0, bail);
memcpy(address.s6_addr, route_prefix, prefix_len_in_bytes);
dbus_message_ref(message);
interface->remove_external_route(
&address,
prefix_len_in_bits,
domain_id,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_joiner_attach_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
ValueMap options;
DBusMessageIter iter;
dbus_message_iter_init(message, &iter);
options = value_map_from_dbus_iter(&iter);
dbus_message_ref(message);
interface->joiner_attach(
options,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
return DBUS_HANDLER_RESULT_HANDLED;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_joiner_start_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
ValueMap options;
DBusMessageIter iter;
dbus_message_iter_init(message, &iter);
options = value_map_from_dbus_iter(&iter);
dbus_message_ref(message);
interface->joiner_commissioning(
true, // start
options,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
return DBUS_HANDLER_RESULT_HANDLED;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_joiner_stop_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
ValueMap options;
dbus_message_ref(message);
interface->joiner_commissioning(
false, // stop
options,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
return DBUS_HANDLER_RESULT_HANDLED;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_joiner_commissioning_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
// The "JoinerCommissioning" DBus command is being deprecated.
// Please use the "JoinerStart" and "JoinerStop" DBus commands
// instead
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
dbus_bool_t action = FALSE;
const char* psk = NULL;
const char* provisioning_url = NULL;
int psk_len = 0;
int provisioning_url_len = 0;
bool did_succeed = false;
ValueMap options;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_BOOLEAN, &action,
DBUS_TYPE_STRING, &psk,
DBUS_TYPE_STRING, &provisioning_url,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
// psk must be specified if joiner starts commissioning
require(action == FALSE || psk != NULL, bail);
if (psk) {
options[kWPANTUNDValueMapKey_Joiner_PSKd] = std::string(psk);
}
if (provisioning_url) {
options[kWPANTUNDValueMapKey_Joiner_ProvisioningUrl] = std::string(provisioning_url);
}
dbus_message_ref(message);
interface->joiner_commissioning(
action,
options,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_joiner_add_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
NCPControlInterface::JoinerInfo joiner;
const uint8_t* ext_addr = NULL;
int ext_addr_len = 0;
const char* psk = NULL;
uint32_t timeout = 0;
uint8_t discerner_len = 0;
uint64_t discerner_value = 0;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_STRING, &psk,
DBUS_TYPE_UINT32, &timeout,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &ext_addr, &ext_addr_len,
DBUS_TYPE_BYTE, &joiner.mDiscerner.mBitLength,
DBUS_TYPE_UINT64, &joiner.mDiscerner.mValue,
DBUS_TYPE_INVALID
);
joiner.mType = NCPControlInterface::JoinerInfo::kDiscerner;
if (!did_succeed) {
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_STRING, &psk,
DBUS_TYPE_UINT32, &timeout,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &ext_addr, &ext_addr_len,
DBUS_TYPE_INVALID
);
if (did_succeed) {
joiner.mType = NCPControlInterface::JoinerInfo::kEui64;
require(ext_addr_len == NCP_EUI64_SIZE, bail);
memcpy(&joiner.mEui64, ext_addr, NCP_EUI64_SIZE);
}
}
if (!did_succeed) {
// No extended address specified
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_STRING, &psk,
DBUS_TYPE_UINT32, &timeout,
DBUS_TYPE_INVALID
);
joiner.mType = NCPControlInterface::JoinerInfo::kAny;
}
require(did_succeed, bail);
require(psk != NULL, bail);
dbus_message_ref(message);
interface->commissioner_add_joiner(
joiner,
timeout,
psk,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_joiner_remove_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
NCPControlInterface::JoinerInfo joiner;
const uint8_t* ext_addr = NULL;
int ext_addr_len = 0;
uint32_t joiner_timeout = 0;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &joiner_timeout,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &ext_addr, &ext_addr_len,
DBUS_TYPE_BYTE, &joiner.mDiscerner.mBitLength,
DBUS_TYPE_UINT64, &joiner.mDiscerner.mValue,
DBUS_TYPE_INVALID
);
joiner.mType = NCPControlInterface::JoinerInfo::kDiscerner;
if (!did_succeed) {
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &joiner_timeout,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &ext_addr, &ext_addr_len,
DBUS_TYPE_INVALID
);
if (did_succeed) {
joiner.mType = NCPControlInterface::JoinerInfo::kEui64;
require(ext_addr_len == NCP_EUI64_SIZE, bail);
memcpy(&joiner.mEui64, ext_addr, NCP_EUI64_SIZE);
}
}
if (!did_succeed) {
// No extended address specified
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &joiner_timeout,
DBUS_TYPE_INVALID
);
joiner.mType = NCPControlInterface::JoinerInfo::kAny;
}
require(did_succeed, bail);
dbus_message_ref(message);
interface->commissioner_remove_joiner(
joiner,
joiner_timeout,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_announce_begin_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
uint32_t channel_mask;
uint8_t count;
uint16_t period;
const uint8_t *dest_addr = NULL;
int dest_addr_len;
struct in6_addr dest;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &channel_mask,
DBUS_TYPE_BYTE, &count,
DBUS_TYPE_UINT16, &period,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &dest_addr, &dest_addr_len,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
require(dest_addr_len == sizeof(dest), bail);
dbus_message_ref(message);
memcpy(dest.s6_addr, dest_addr, sizeof(dest));
interface->commissioner_send_announce_begin(
channel_mask,
count,
period,
dest,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_energy_scan_query_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
uint32_t channel_mask;
uint8_t count;
uint16_t period;
uint16_t scan_duration;
const uint8_t *dest_addr = NULL;
int dest_addr_len;
struct in6_addr dest;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &channel_mask,
DBUS_TYPE_BYTE, &count,
DBUS_TYPE_UINT16, &period,
DBUS_TYPE_UINT16, &scan_duration,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &dest_addr, &dest_addr_len,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
require(dest_addr_len == sizeof(dest), bail);
dbus_message_ref(message);
memcpy(dest.s6_addr, dest_addr, sizeof(dest));
interface->commissioner_send_energy_scan_query(
channel_mask,
count,
period,
scan_duration,
dest,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_pan_id_query_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
uint16_t pan_id;
uint32_t channel_mask;
const uint8_t *dest_addr = NULL;
int dest_addr_len;
struct in6_addr dest;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT16, &pan_id,
DBUS_TYPE_UINT32, &channel_mask,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &dest_addr, &dest_addr_len,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
require(dest_addr_len == sizeof(dest), bail);
dbus_message_ref(message);
memcpy(dest.s6_addr, dest_addr, sizeof(dest));
interface->commissioner_send_pan_id_query(
pan_id,
channel_mask,
dest,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_generate_pskc(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
const char *pass_phrase = "";
const char *network_name = "";
const uint8_t *xpan_id_ptr = NULL;
int xpan_id_len;
NCPControlInterface::XPANId xpan_id;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_STRING, &pass_phrase,
DBUS_TYPE_STRING, &network_name,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &xpan_id_ptr, &xpan_id_len,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
require(xpan_id_len == sizeof(xpan_id), bail);
dbus_message_ref(message);
memcpy(xpan_id.m8, xpan_id_ptr, sizeof(xpan_id));
interface->commissioner_generate_pskc(
pass_phrase,
network_name,
xpan_id,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatusArg1_Helper, this, _1, _2, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_peek_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
uint32_t address;
uint16_t count;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &address,
DBUS_TYPE_UINT16, &count,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
dbus_message_ref(message);
interface->peek(
address,
count,
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatusArg1_Helper,
this,
_1,
_2,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_poke_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
uint32_t address;
int count = 0;
uint8_t *bytes = NULL;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT32, &address,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &bytes, &count,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
dbus_message_ref(message);
interface->poke(
address,
Data(bytes, count),
boost::bind(
&DBusIPCAPI_v1::CallbackWithStatus_Helper,
this,
_1,
message
)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_link_metrics_query_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
const uint8_t *dest_addr = NULL;
int dest_addr_len;
struct in6_addr dest;
uint8_t series;
uint8_t metrics = 0;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &dest_addr, &dest_addr_len,
DBUS_TYPE_BYTE, &series,
DBUS_TYPE_BYTE, &metrics,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
require(dest_addr_len == sizeof(dest), bail);
dbus_message_ref(message);
memcpy(dest.s6_addr, dest_addr, sizeof(dest));
interface->link_metrics_query(
dest,
series,
metrics,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_link_metrics_probe_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
const uint8_t *dest_addr = NULL;
int dest_addr_len;
struct in6_addr dest;
uint8_t series;
uint8_t length;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &dest_addr, &dest_addr_len,
DBUS_TYPE_BYTE, &series,
DBUS_TYPE_BYTE, &length,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
require(dest_addr_len == sizeof(dest), bail);
dbus_message_ref(message);
memcpy(dest.s6_addr, dest_addr, sizeof(dest));
interface->link_metrics_probe(
dest,
series,
length,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_link_metrics_mgmt_forward_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
const uint8_t *dest_addr = NULL;
int dest_addr_len;
struct in6_addr dest;
uint8_t series_id = 0;
uint8_t metrics = 0;
uint8_t frame_types = 0;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &dest_addr, &dest_addr_len,
DBUS_TYPE_BYTE, &series_id,
DBUS_TYPE_BYTE, &frame_types,
DBUS_TYPE_BYTE, &metrics,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
require(dest_addr_len == sizeof(dest), bail);
dbus_message_ref(message);
memcpy(dest.s6_addr, dest_addr, sizeof(dest));
interface->link_metrics_mgmt_forward(
dest,
series_id,
frame_types,
metrics,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_link_metrics_mgmt_enh_ack_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
const uint8_t *dest_addr = NULL;
int dest_addr_len;
struct in6_addr dest;
uint8_t metrics = 0;
uint8_t flags = 0;
bool did_succeed = false;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &dest_addr, &dest_addr_len,
DBUS_TYPE_BYTE, &flags,
DBUS_TYPE_BYTE, &metrics,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
require(dest_addr_len == sizeof(dest), bail);
dbus_message_ref(message);
memcpy(dest.s6_addr, dest_addr, sizeof(dest));
interface->link_metrics_mgmt_enh_ack(
dest,
flags,
metrics,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_mlr_request_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
bool did_succeed = true;
std::vector<struct in6_addr> addresses;
dbus_bool_t mlr_timeout_present;
uint32_t mlr_timeout;
DBusMessageIter iter;
did_succeed = dbus_message_iter_init(message, &iter);
require(did_succeed, bail);
did_succeed = (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY);
require(did_succeed, bail);
DBusMessageIter sub_iter;
dbus_message_iter_recurse(&iter, &sub_iter);
do {
addresses.push_back(any_to_ipv6(any_from_dbus_iter(&sub_iter)));
} while (dbus_message_iter_next(&sub_iter));
dbus_message_iter_next(&iter);
did_succeed = (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_BOOLEAN);
require(did_succeed, bail);
dbus_message_iter_get_basic(&iter, &mlr_timeout_present);
dbus_message_iter_next(&iter);
did_succeed = (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT32);
require(did_succeed, bail);
dbus_message_iter_get_basic(&iter, &mlr_timeout);
dbus_message_ref(message);
interface->mlr_request(
addresses,
mlr_timeout_present,
mlr_timeout,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::interface_backbone_router_config_handler(
NCPControlInterface* interface,
DBusMessage * message
) {
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
bool did_succeed = true;
uint16_t delay = 0;
uint32_t timeout = 0;
uint8_t seqno = 0;
did_succeed = dbus_message_get_args(
message, NULL,
DBUS_TYPE_UINT16, &delay,
DBUS_TYPE_UINT32, &timeout,
DBUS_TYPE_BYTE, &seqno,
DBUS_TYPE_INVALID
);
require(did_succeed, bail);
dbus_message_ref(message);
interface->backbone_router_config(
delay,
timeout,
seqno,
boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
);
ret = DBUS_HANDLER_RESULT_HANDLED;
bail:
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::message_handler(
NCPControlInterface* interface,
DBusConnection * connection,
DBusMessage * message
)
{
DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if ((dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
&& (dbus_message_has_interface(message, WPANTUND_DBUS_APIv1_INTERFACE)
|| dbus_message_has_interface(message, WPANTUND_DBUS_NLAPIv1_INTERFACE))
&& mInterfaceCallbackTable.count(dbus_message_get_member(message))
) {
try {
ret = mInterfaceCallbackTable.at(dbus_message_get_member(message))(
interface,
message
);
} catch (std::invalid_argument x) {
DBusIPCAPI_v1::CallbackWithStatus_Helper(kWPANTUNDStatus_InvalidArgument,message);
ret = DBUS_HANDLER_RESULT_HANDLED;
}
}
return ret;
}
DBusHandlerResult
DBusIPCAPI_v1::dbus_message_handler(
DBusConnection *connection,
DBusMessage * message,
void * user_data
) {
if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL) {
syslog(LOG_INFO, "Inbound DBus message for INTERFACE \"%s\" from \"%s\"", dbus_message_get_member(message), dbus_message_get_sender(message));
}
std::pair<NCPControlInterface*,
DBusIPCAPI_v1*> *cb_data =
(std::pair<NCPControlInterface*, DBusIPCAPI_v1*> *)user_data;
return cb_data->second->message_handler(cb_data->first,
connection,
message);
}