4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs/*
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * Use is subject to license terms.
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs *
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * Licensed under the Academic Free License version 2.1
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#pragma ident "%Z%%M% %I% %E% SMI"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <stdio.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <stdlib.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <unistd.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <string.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <libhal.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <logger.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <glib.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include "network-discovery.h"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs/*
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * The interfaces in this file comprise a means of keeping track of devices
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * that we have already seen and those that have gone missing. This allows
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * us to quickly determine if we need to probe the device and quickly search
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * for devices that are no longer available.
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobstypedef struct {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs LibHalContext *ctx;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs time_t timestamp;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs} removal_args_t;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic GHashTable *seen = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic gboolean
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsdevice_remove_if_stale(gpointer key, gpointer value, gpointer user_data)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs gboolean result = FALSE;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs removal_args_t *args = user_data;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *name = key;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs time_t *val = value;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("test stale: %s (%d > %d)", name, args->timestamp, *val));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (args->timestamp > *val) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBusError error;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char **udi = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int num = 0;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_error_init(&error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs udi = libhal_manager_find_device_string_match(args->ctx,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "network_device.address", name,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs &num, &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (udi != NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int i;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs for (i = 0; i < num; i++) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_remove_device(args->ctx, udi[i], &error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("remove: %s (%s)", name, udi[i]));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs libhal_free_string_array(udi);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs result = TRUE;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (dbus_error_is_set(&error))
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_error_free(&error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (result);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsvoid
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsscan_for_stale_devices(LibHalContext *ctx, time_t timestamp)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (seen != NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs removal_args_t args[1];
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs args->ctx = ctx;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs args->timestamp = timestamp;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs g_hash_table_foreach_remove(seen, device_remove_if_stale, args);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsgboolean
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsdevice_seen(char *name)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs gboolean result;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *key;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs time_t *val;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (seen == NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs seen = g_hash_table_new_full(g_str_hash, g_str_equal,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free, free);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs result = g_hash_table_lookup_extended(seen, name,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (gpointer)&key, (gpointer)&val);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((result == FALSE) && ((val = calloc(1, sizeof (*val))) != NULL)) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs g_hash_table_insert(seen, strdup(name), val);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (void) time(val);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("seen: %s (%d)", name, *val));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (result);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}