static void handle_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { SensorData *data = user_data; DriverType driver_type; GHashTable *ht; guint watch_id; if (g_strcmp0 (method_name, "ClaimAccelerometer") == 0 || g_strcmp0 (method_name, "ReleaseAccelerometer") == 0) driver_type = DRIVER_TYPE_ACCEL; else if (g_strcmp0 (method_name, "ClaimLight") == 0 || g_strcmp0 (method_name, "ClaimAccelerometer") == 0) driver_type = DRIVER_TYPE_LIGHT; else { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method '%s' does not exist", method_name); return; } ht = data->clients[driver_type]; if (g_str_has_prefix (method_name, "Claim")) { watch_id = GPOINTER_TO_UINT (g_hash_table_lookup (ht, sender)); if (watch_id > 0) { g_dbus_method_invocation_return_value (invocation, NULL); return; } /* No other clients for this sensor? Start it */ if (driver_type_exists (data, driver_type) && g_hash_table_size (ht) == 0) driver_set_polling (DRIVER_FOR_TYPE(driver_type), TRUE); watch_id = g_bus_watch_name_on_connection (data->connection, sender, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, client_vanished_cb, data, NULL); g_hash_table_insert (ht, g_strdup (sender), GUINT_TO_POINTER (watch_id)); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_str_has_prefix (method_name, "Release")) { client_release (data, sender, driver_type); g_dbus_method_invocation_return_value (invocation, NULL); } }
static void handle_generic_method_call (SensorData *data, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, DriverType driver_type) { GHashTable *ht; guint watch_id; g_debug ("Handling driver refcounting method '%s' for %s device", method_name, driver_type_to_str (driver_type)); ht = data->clients[driver_type]; if (g_str_has_prefix (method_name, "Claim")) { watch_id = GPOINTER_TO_UINT (g_hash_table_lookup (ht, sender)); if (watch_id > 0) { g_dbus_method_invocation_return_value (invocation, NULL); return; } /* No other clients for this sensor? Start it */ if (driver_type_exists (data, driver_type) && g_hash_table_size (ht) == 0) driver_set_polling (DRIVER_FOR_TYPE(driver_type), TRUE); watch_id = g_bus_watch_name_on_connection (data->connection, sender, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, client_vanished_cb, data, NULL); g_hash_table_insert (ht, g_strdup (sender), GUINT_TO_POINTER (watch_id)); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_str_has_prefix (method_name, "Release")) { client_release (data, sender, driver_type); g_dbus_method_invocation_return_value (invocation, NULL); } }
static void client_release (SensorData *data, const char *sender, DriverType driver_type) { GHashTable *ht; guint watch_id; ht = data->clients[driver_type]; watch_id = GPOINTER_TO_UINT (g_hash_table_lookup (ht, sender)); if (watch_id == 0) return; g_hash_table_remove (ht, sender); if (g_hash_table_size (ht) == 0) driver_set_polling (DRIVER_FOR_TYPE(driver_type), FALSE); }
static void sensor_changes (GUdevClient *client, gchar *action, GUdevDevice *device, SensorData *data) { guint i; if (g_strcmp0 (action, "remove") == 0) { for (i = 0; i < NUM_SENSOR_TYPES; i++) { GUdevDevice *dev = DEVICE_FOR_TYPE(i); if (!dev) continue; if (g_strcmp0 (g_udev_device_get_sysfs_path (device), g_udev_device_get_sysfs_path (dev)) == 0) { g_debug ("Sensor type %s got removed (%s)", driver_type_to_str (i), g_udev_device_get_sysfs_path (dev)); g_clear_object (&DEVICE_FOR_TYPE(i)); DRIVER_FOR_TYPE(i) = NULL; g_clear_pointer (&data->clients[i], g_hash_table_unref); data->clients[i] = create_clients_hash_table (); send_driver_changed_dbus_event (data, i); } } if (!any_sensors_left (data)) g_main_loop_quit (data->loop); } else if (g_strcmp0 (action, "add") == 0) { guint i; for (i = 0; i < G_N_ELEMENTS(drivers); i++) { SensorDriver *driver = (SensorDriver *) drivers[i]; if (!driver_type_exists (data, driver->type) && driver_discover (driver, device)) { g_debug ("Found hotplugged device %s of type %s at %s", g_udev_device_get_sysfs_path (device), driver_type_to_str (driver->type), driver->name); if (driver_open (driver, device, driver_type_to_callback_func (driver->type), data)) { GHashTable *ht; DEVICE_FOR_TYPE(driver->type) = g_object_ref (device); DRIVER_FOR_TYPE(driver->type) = (SensorDriver *) driver; send_driver_changed_dbus_event (data, driver->type); ht = data->clients[driver->type]; if (g_hash_table_size (ht) > 0) driver_set_polling (DRIVER_FOR_TYPE(driver->type), TRUE); } break; } } } }