blob: 5e8b3923d612ab599945eba5768da8f044738f59 [file] [log] [blame]
/*
*
* Connection Manager
*
* Copyright (C) 2012 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 as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <glib.h>
#include <gdbus.h>
#include "monitor.h"
#include "services.h"
#include "technology.h"
#include "data_manager.h"
static const char *get_service_name(DBusMessage *message, char *dbus_path)
{
DBusMessageIter iter, array;
dbus_message_iter_init(message, &iter);
dbus_message_iter_recurse(&iter, &array);
while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
DBusMessageIter entry, dict;
struct service_data service;
char *path;
dbus_message_iter_recurse(&array, &entry);
dbus_message_iter_get_basic(&entry, &path);
if (g_strcmp0(path, dbus_path) == 0) {
dbus_message_iter_next(&entry);
dbus_message_iter_recurse(&entry, &dict);
extract_service_name(&dict, &service);
return service.name;
} else {
dbus_message_iter_next(&array);
}
}
return NULL;
}
static void extract_tech_signal(DBusMessage *message)
{
DBusMessageIter iter, dict;
char *path;
dbus_message_iter_init(message, &iter);
if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_OBJECT_PATH) {
dbus_message_iter_get_basic(&iter, &path);
printf(" { %s }\n", path);
}
dbus_message_iter_next(&iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
dbus_message_iter_recurse(&iter, &dict);
extract_properties(&dict);
}
}
static void extract_signal_args(DBusMessage *message)
{
DBusMessageIter iter, array, dict;
char *string, *value;
uint16_t key_int;
dbus_bool_t bvalue;
value = NULL;
key_int = 0;
dbus_message_iter_init(message, &iter);
while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
dbus_message_iter_get_basic(&iter, &string);
printf("\n[%s] = ",
string);
}
dbus_message_iter_next(&iter);
if (dbus_message_iter_get_arg_type(&iter) !=
DBUS_TYPE_INVALID) {
dbus_message_iter_recurse(&iter, &array);
if (dbus_message_iter_get_arg_type(&array) ==
DBUS_TYPE_STRING) {
dbus_message_iter_get_basic(&array, &value);
printf("%s\n", value);
continue;
} else if (dbus_message_iter_get_arg_type(&array) ==
DBUS_TYPE_BOOLEAN) {
dbus_message_iter_get_basic(&array, &bvalue);
printf("%s\n", bvalue == TRUE ?
"True" : "False");
continue;
} else if (dbus_message_iter_get_arg_type(&array) ==
DBUS_TYPE_ARRAY)
dbus_message_iter_recurse(&array, &dict);
if (dbus_message_iter_get_arg_type(&dict) ==
DBUS_TYPE_DICT_ENTRY) {
iterate_dict(&dict, value, key_int);
printf("\n");
} else {
iterate_array(&array);
printf("\n");
}
dbus_message_iter_next(&iter);
}
}
}
int monitor_connman(DBusConnection *connection, char *interface,
char *signal_name)
{
char *rule = g_strdup_printf("type='signal',interface='net.connman.%s',"
"member='%s'", interface, signal_name);
DBusError err;
dbus_error_init(&err);
g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Bus setup error:%s\n", err.message);
return -1;
}
dbus_bus_add_match(connection, rule, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Match Error: %s\n", err.message);
return -1;
}
return 0;
}
DBusHandlerResult service_property_changed(DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
DBusMessage *service_message;
struct service_data service;
if (dbus_message_is_signal(message, "net.connman.Service",
"PropertyChanged")) {
service_message = get_message(connection, "GetServices");
if (service_message == NULL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
service.name = get_service_name(service_message,
(char *) dbus_message_get_path(message));
printf("\n");
g_message("Path = %s, Interface = %s\nService = %s",
dbus_message_get_path(message),
dbus_message_get_interface(message),
service.name);
extract_signal_args(message);
dbus_message_unref(service_message);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
DBusHandlerResult tech_property_changed(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
if (dbus_message_is_signal(message, "net.connman.Technology",
"PropertyChanged")) {
printf("\n");
g_message("Path = %s, Interface = %s",
dbus_message_get_path(message),
dbus_message_get_interface(message));
extract_signal_args(message);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
DBusHandlerResult tech_added_removed(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
if (dbus_message_is_signal(message, "net.connman.Manager",
"TechnologyAdded")) {
printf("\n");
g_message("Path = %s, Interface = %s",
dbus_message_get_path(message),
dbus_message_get_interface(message));
printf("New technology added:\n");
extract_tech_signal(message);
} else if (dbus_message_is_signal(message, "net.connman.Manager",
"TechnologyRemoved")) {
printf("\n");
g_message("Path = %s, Interface = %s",
dbus_message_get_path(message),
dbus_message_get_interface(message));
printf("Technology was removed:\n");
extract_tech_signal(message);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
DBusHandlerResult manager_services_changed(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
if (dbus_message_is_signal(message, "net.connman.Manager",
"ServicesChanged")) {
printf("\n");
g_message("Path = %s, Interface = %s",
dbus_message_get_path(message),
dbus_message_get_interface(message));
printf("Services Changed, displaying updated "
"list of services:\n");
list_properties(connection, "GetServices", NULL);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
DBusHandlerResult manager_property_changed(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
if (dbus_message_is_signal(message, "net.connman.Manager",
"PropertyChanged")) {
printf("\n");
g_message("Path = %s, Interface = %s",
dbus_message_get_path(message),
dbus_message_get_interface(message));
extract_signal_args(message);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}