コード例 #1
0
ファイル: battery.c プロジェクト: alhazred/onarm
gboolean
battery_update(LibHalContext *ctx, const char *udi, int fd)
{
	acpi_bst_t bst;
	DBusError error;

	HAL_DEBUG(("battery_update() enter"));
	dbus_error_init(&error);
	libhal_device_set_property_string(ctx, udi, "info.product",
	    "Battery Bay", &error);
	my_dbus_error_free(&error);
	libhal_device_set_property_string(ctx, udi, "info.category", "battery",
	    &error);

	bzero(&bst, sizeof (bst));
	if (ioctl(fd, BATT_IOC_STATUS, &bst) < 0) {
		if (errno == ENXIO) {
			my_dbus_error_free(&error);
			libhal_device_set_property_bool(ctx, udi,
			    "battery.present", FALSE, &error);
		} else {
			my_dbus_error_free(&error);
			return (FALSE);
		}
	} else {
		my_dbus_error_free(&error);
		libhal_device_set_property_bool(ctx, udi, "battery.present",
		    TRUE, &error);
	}

	my_dbus_error_free(&error);
	if (!libhal_device_get_property_bool(ctx, udi, "battery.present",
	    &error)) {
		HAL_DEBUG(("battery_update(): battery is NOT present"));
		battery_remove(ctx, udi);
	} else {
		HAL_DEBUG(("battery_update(): battery is present"));
		my_dbus_error_free(&error);
		libhal_device_set_property_string(ctx, udi, "battery.type",
		    "primary", &error);
		my_dbus_error_free(&error);
		libhal_device_add_capability(ctx, udi, "battery", &error);
		my_dbus_error_free(&error);
		if (libhal_device_get_property_type(ctx, udi, "battery.vendor",
		    &error) == LIBHAL_PROPERTY_TYPE_INVALID) {
			battery_static_update(ctx, udi, fd);
		}
		battery_dynamic_update(ctx, udi, fd);
	}
	my_dbus_error_free(&error);
	HAL_DEBUG(("battery_update() exit"));
	return (TRUE);
}
コード例 #2
0
ファイル: hal-backend.c プロジェクト: Babl0lka/libgpod
static gboolean
hal_backend_set_is_unknown (ItdbBackend *itdb_backend, gboolean unknown)
{
	HalBackend *backend = (HalBackend *)itdb_backend;
	libhal_device_set_property_bool (backend->ctx, backend->udi,
					 LIBGPOD_HAL_NS"ipod.is_unknown", 
					 TRUE, NULL);
	return TRUE;
}
コード例 #3
0
ファイル: hal-backend.c プロジェクト: Babl0lka/libgpod
static gboolean hal_backend_set_artwork_type_supported (ItdbBackend *itdb_backend,
							enum ArtworkType type,
							gboolean supported)
{
	HalBackend *backend = (HalBackend *)itdb_backend;
    	char *propname;
	switch (type) {
	    case ALBUM:
		propname = LIBGPOD_HAL_NS"ipod.images.album_art_supported";
		break;
	    case PHOTO:
		propname = LIBGPOD_HAL_NS"ipod.images.photos_supported";
		break;
	    case CHAPTER:
		propname = LIBGPOD_HAL_NS"ipod.images.chapter_images_supported";
		break;
	    default:
		g_return_val_if_reached (FALSE);
	}
        libhal_device_set_property_bool (backend->ctx, backend->udi,
                                         propname, supported, NULL);
	return TRUE;
}
コード例 #4
0
ファイル: probe-volume.c プロジェクト: alhazred/onarm
int 
main (int argc, char *argv[])
{
	int fd, rfd;
	int ret;
	char *udi;
	char *device_file, *raw_device_file;
	char *devpath, *rdevpath;
	boolean_t is_dos;
	int dos_num;
	LibHalContext *ctx = NULL;
	DBusError error;
	DBusConnection *conn;
	char *parent_udi;
	char *storage_device;
	char *is_disc_str;
	int fdc;
	dbus_bool_t is_disc = FALSE;
	dbus_bool_t is_floppy = FALSE;
	unsigned int block_size;
	dbus_uint64_t vol_size;
	dbus_bool_t has_data = TRUE;	/* probe for fs by default */
	dbus_bool_t has_audio = FALSE;
	char *partition_scheme = NULL;
	dbus_uint64_t partition_start = 0;
	int partition_number = 0;
	struct vtoc vtoc;
	dk_gpt_t *gpt;
	struct dk_minfo mi;
	int i, dos_cnt;
	fstyp_handle_t fstyp_handle;
	int systid, relsect, numsect;
	off_t probe_offset = 0;
	int num_volumes;
	char **volumes;
	dbus_uint64_t v_start;
	const char *fstype;
	nvlist_t *fsattr;

	fd = rfd = -1;

	ret = 1;

	if ((udi = getenv ("UDI")) == NULL) {
		goto out;
	}
	if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL) {
		goto out;
	}
	if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL) {
		goto out;
	}
	if (!dos_to_dev(device_file, &rdevpath, &dos_num)) {
		rdevpath = raw_device_file;
	}
	if (!(is_dos = dos_to_dev(device_file, &devpath, &dos_num))) {
		devpath = device_file;
	}
	if ((parent_udi = getenv ("HAL_PROP_INFO_PARENT")) == NULL) {
		goto out;
	}
	if ((storage_device = getenv ("HAL_PROP_BLOCK_STORAGE_DEVICE")) == NULL) {
		goto out;
	}

	is_disc_str = getenv ("HAL_PROP_VOLUME_IS_DISC");
	if (is_disc_str != NULL && strcmp (is_disc_str, "true") == 0) {
		is_disc = TRUE;
	} else {
		is_disc = FALSE;
	}

	drop_privileges ();

	setup_logger ();

	dbus_error_init (&error);
	if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
		goto out;

	HAL_DEBUG (("Doing probe-volume for %s\n", device_file));

	fd = open (devpath, O_RDONLY | O_NONBLOCK);
	if (fd < 0) {
		goto out;
	}
	rfd = open (rdevpath, O_RDONLY | O_NONBLOCK);
	if (rfd < 0) {
		goto out;
	}

	/* if it's a floppy with no media, bail out */
	if (ioctl(rfd, FDGETCHANGE, &fdc) == 0) {
		is_floppy = TRUE;
		if (fdc & FDGC_CURRENT) {
			goto out;
		}
	}

	/* block size and total size */
	if (ioctl(rfd, DKIOCGMEDIAINFO, &mi) != -1) {
		block_size = mi.dki_lbsize;
		vol_size = mi.dki_capacity * block_size;
	} else if (errno == ENXIO) {
		/* driver supports ioctl, but media is not available */
		goto out;
	} else {
		/* driver does not support ioctl, e.g. lofi */
		block_size = 512;
		vol_size = 0;
	}
	libhal_device_set_property_int (ctx, udi, "volume.block_size", block_size, &error);
	my_dbus_error_free (&error);
	libhal_device_set_property_uint64 (ctx, udi, "volume.size", vol_size, &error);
	my_dbus_error_free (&error);

	if (is_disc) {
		if (!probe_disc (rfd, ctx, udi, &has_data, &has_audio)) {
			HAL_DEBUG (("probe_disc failed, skipping fstyp"));
			goto out;
		}
		/* with audio present, create volume even if fs probing fails */
		if (has_audio) {
			ret = 0;
		}
	}

	if (!has_data) {
		goto skip_fs;
	}

	/* don't support partitioned floppy */
	if (is_floppy) {
		goto skip_part;
	}

	/*
	 * first get partitioning info
	 */
	if (is_dos) {
		/* for a dos drive find partition offset */
		if (!find_dos_drive(fd, dos_num, &relsect, &numsect, &systid)) {
			goto out;
		}
		partition_scheme = "mbr";
		partition_start = (dbus_uint64_t)relsect * 512;
		partition_number = dos_num;
		probe_offset = (off_t)relsect * 512;
	} else {
		if ((partition_number = read_vtoc(rfd, &vtoc)) >= 0) {
			if (!vtoc_one_slice_entire_disk(&vtoc)) {
				partition_scheme = "smi";
				if (partition_number < vtoc.v_nparts) {
					if (vtoc.v_part[partition_number].p_size == 0) {
						HAL_DEBUG (("zero size partition"));
					}
					partition_start = vtoc.v_part[partition_number].p_start * block_size;
				}
			}
		} else if ((partition_number = efi_alloc_and_read(rfd, &gpt)) >= 0) {
			partition_scheme = "gpt";
			if (partition_number < gpt->efi_nparts) {
				if (gpt->efi_parts[partition_number].p_size == 0) {
					HAL_DEBUG (("zero size partition"));
				}
				partition_start = gpt->efi_parts[partition_number].p_start * block_size;
			}
			efi_free(gpt);
		}
		probe_offset = 0;
	}

	if (partition_scheme != NULL) {
		libhal_device_set_property_string (ctx, udi, "volume.partition.scheme", partition_scheme, &error);
		my_dbus_error_free (&error);
		libhal_device_set_property_int (ctx, udi, "volume.partition.number", partition_number, &error);
		my_dbus_error_free (&error);
		libhal_device_set_property_uint64 (ctx, udi, "volume.partition.start", partition_start, &error);
		my_dbus_error_free (&error);
		libhal_device_set_property_bool (ctx, udi, "volume.is_partition", TRUE, &error);
		my_dbus_error_free (&error);
	} else {
		libhal_device_set_property_bool (ctx, udi, "volume.is_partition", FALSE, &error);
		my_dbus_error_free (&error);
	}

	/*
	 * ignore duplicate partitions
	 */
	if ((volumes = libhal_manager_find_device_string_match (
	    ctx, "block.storage_device", storage_device, &num_volumes, &error)) != NULL) {
		my_dbus_error_free (&error);
		for (i = 0; i < num_volumes; i++) {
			if (strcmp (udi, volumes[i]) == 0) {
				continue; /* skip self */
			}
			v_start = libhal_device_get_property_uint64 (ctx, volumes[i], "volume.partition.start", &error);
			if (dbus_error_is_set(&error)) {
				dbus_error_free(&error);
				continue;
			}
			if (v_start == partition_start) {
				HAL_DEBUG (("duplicate partition"));
				goto out;
			}
		}
		libhal_free_string_array (volumes);
	}

skip_part:

	/*
	 * now determine fs type
	 *
	 * XXX We could get better performance from block device,
	 * but for now we use raw device because:
	 *
	 * - fstyp_udfs has a bug that it only works on raw
	 *
	 * - sd has a bug that causes extremely slow reads
	 *   and incorrect probing of hybrid audio/data media
	 */
	if (fstyp_init(rfd, probe_offset, NULL, &fstyp_handle) != 0) {
		HAL_DEBUG (("fstyp_init failed"));
		goto out;
	}
	if ((fstyp_ident(fstyp_handle, NULL, &fstype) != 0) ||
	    (fstyp_get_attr(fstyp_handle, &fsattr) != 0)) {
		HAL_DEBUG (("fstyp ident or get_attr failed"));
		fstyp_fini(fstyp_handle);
		goto out;
	}
	set_fstyp_properties (ctx, udi, fstype, fsattr);

	if (strcmp (fstype, "hsfs") == 0) {
		hsfs_contents (fd, probe_offset, ctx, udi);
	}

	fstyp_fini(fstyp_handle);

skip_fs:

	ret = 0;

out:
	if (fd >= 0)
		close (fd);
	if (rfd >= 0)
		close (rfd);

	if (ctx != NULL) {
		my_dbus_error_free (&error);
		libhal_ctx_shutdown (ctx, &error);
		libhal_ctx_free (ctx);
	}

	return ret;

}
コード例 #5
0
ファイル: probe-volume.c プロジェクト: alhazred/onarm
/*
 * hsfs/iso9660 contents detection: Video DVD, Video CD, etc.
 */
static void
hsfs_contents(int fd, off_t probe_offset, LibHalContext *ctx, const char *udi)
{
	size_t	secsz = ISO_SECTOR_SIZE;
	uchar_t	buf[ISO_SECTOR_SIZE];
	int	ptbl_lbn, ptbl_size;
	int	off, reloff, readoff;
	uchar_t	*p;
	char	*name;
	int	name_len;
	int	ipe_len;
	DBusError error;

	/*
	 * find 1st Primary Volume Descriptor
	 */
	readoff = probe_offset + ISO_VOLDESC_SEC * secsz;
	if (pread (fd, buf, secsz, readoff) != secsz) {
		return;
	}
	while (ISO_DESC_TYPE (buf) != ISO_VD_PVD) {
		if (ISO_DESC_TYPE (buf) == ISO_VD_EOV) {
			return;
		}
		readoff += secsz;
		if (pread (fd, buf, secsz, readoff) != secsz) {
			return;
		}
	}

	/*
	 * PVD contains size and offset of the LSB/MSB path table
	 */
	ptbl_size = ISO_PTBL_SIZE (buf);
#if defined(_LITTLE_ENDIAN)
        ptbl_lbn = ISO_PTBL_MAN_LS (buf);
#else
        ptbl_lbn = ISO_PTBL_MAN_MS (buf);
#endif

	/*
	 * Look through path table entries
	 */
	readoff = probe_offset + ptbl_lbn * secsz;
	if (pread (fd, buf, secsz, readoff) != secsz) {
		return;
	}
	dbus_error_init (&error);

	for (off = reloff = 0;
	    off < ptbl_size;
	    off += ipe_len, reloff += ipe_len) {

		/* load sectors on demand */
		if (reloff >= secsz) {
			readoff += secsz;
			if (pread (fd, buf, secsz, readoff) != secsz) {
				break;
			}
			reloff -= secsz;
		}

		p = buf + reloff;
		name_len = IPE_NAME_LEN(p);
		ipe_len = IPE_FPESIZE + name_len + (name_len % 2);

		/* only interested in root directories */
		if (IPE_PARENT_NO (p) != 1) {
			continue;
		}
		if ((name_len < 2) || (name_len > IDE_MAX_NAME_LEN)) {
			continue;
		}

		name = (char *)IPE_NAME (p);
		if (strncasecmp (name, "VIDEO_TS", min (8, name_len)) == 0) {
			libhal_device_set_property_bool (ctx, udi,
			    "volume.disc.is_videodvd", TRUE, &error);
		} else if (strncasecmp (name, "VCD", min (3, name_len)) == 0) {
			libhal_device_set_property_bool (ctx, udi,
			    "volume.disc.is_vcd", TRUE, &error);
		} else if (strncasecmp (name, "SVCD", min (4, name_len)) == 0) {
			libhal_device_set_property_bool (ctx, udi,
			    "volume.disc.is_svcd", TRUE, &error);
		}
	}

	my_dbus_error_free (&error);
}
コード例 #6
0
ファイル: addon-storage.c プロジェクト: alhazred/onarm
int 
main (int argc, char *argv[])
{
	char *udi;
	char *device_file, *raw_device_file;
	LibHalContext *ctx = NULL;
	DBusError error;
	char *bus;
	char *drive_type;
	int state, last_state;
	char *support_media_changed_str;
	int support_media_changed;
	int fd = -1;

	if ((udi = getenv ("UDI")) == NULL)
		goto out;
	if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL)
		goto out;
	if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL)
		goto out;
	if ((bus = getenv ("HAL_PROP_STORAGE_BUS")) == NULL)
		goto out;
	if ((drive_type = getenv ("HAL_PROP_STORAGE_DRIVE_TYPE")) == NULL)
		goto out;

	drop_privileges ();

	setup_logger ();

	support_media_changed_str = getenv ("HAL_PROP_STORAGE_CDROM_SUPPORT_MEDIA_CHANGED");
	if (support_media_changed_str != NULL && strcmp (support_media_changed_str, "true") == 0)
		support_media_changed = TRUE;
	else
		support_media_changed = FALSE;

	dbus_error_init (&error);

	if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
		goto out;
	}
	my_dbus_error_free (&error);

	if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
		goto out;
	}
	my_dbus_error_free (&error);

	printf ("Doing addon-storage for %s (bus %s) (drive_type %s) (udi %s)\n", device_file, bus, drive_type, udi);

	last_state = state = DKIO_NONE;

	/* Linux version of this addon attempts to re-open the device O_EXCL
	 * every 2 seconds, trying to figure out if some other app,
	 * like a cd burner, is using the device. Aside from questionable
	 * value of this (apps should use HAL's locked property or/and
	 * Solaris in_use facility), but also frequent opens/closes
	 * keeps media constantly spun up. All this needs more thought.
	 */
	for (;;) {
		if (is_mounted (device_file)) {
			close_device (&fd);
			sleep (SLEEP_PERIOD);
		} else if ((fd < 0) && ((fd = open (raw_device_file, O_RDONLY | O_NONBLOCK)) < 0)) {
			HAL_DEBUG (("open failed for %s: %s", raw_device_file, strerror (errno)));
			sleep (SLEEP_PERIOD);
		} else {
			/* Check if a disc is in the drive */
			/* XXX initial call always returns inserted
			 * causing unnecessary rescan - optimize?
			 */
			if (ioctl (fd, DKIOCSTATE, &state) == 0) {
				if (state == last_state) {
					HAL_DEBUG (("state has not changed %d %s", state, device_file));
					continue;
				} else {
					HAL_DEBUG (("new state %d %s", state, device_file));
				}

				switch (state) {
				case DKIO_EJECTED:
					HAL_DEBUG (("Media removal detected on %s", device_file));
					last_state = state;

					libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error);
					my_dbus_error_free (&error);

					/* attempt to unmount all childs */
					unmount_childs (ctx, udi);

					/* could have a fs on the main block device; do a rescan to remove it */
					libhal_device_rescan (ctx, udi, &error);
					my_dbus_error_free (&error);
					break;

				case DKIO_INSERTED:
					HAL_DEBUG (("Media insertion detected on %s", device_file));
					last_state = state;

					libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error);
					my_dbus_error_free (&error);

					/* could have a fs on the main block device; do a rescan to add it */
					libhal_device_rescan (ctx, udi, &error);
					my_dbus_error_free (&error);
					break;

				case DKIO_DEV_GONE:
					HAL_DEBUG (("Device gone detected on %s", device_file));
					last_state = state;

					unmount_childs (ctx, udi);
					close_device (&fd);
					goto out;

				case DKIO_NONE:
				default:
					break;
				}
			} else {
				HAL_DEBUG (("DKIOCSTATE failed: %s\n", strerror(errno)));
				sleep (SLEEP_PERIOD);
			}
		}
	}

out:
	if (ctx != NULL) {
		my_dbus_error_free (&error);
		libhal_ctx_shutdown (ctx, &error);
		libhal_ctx_free (ctx);
	}

	return 0;
}
コード例 #7
0
ファイル: probe-volume.c プロジェクト: bbidulock/hal
int
main (int argc, char **argv)
{
  char *device_file;
  char *parent_udi;
  char *grandparent_udi;
  char *parent_drive_type;
  int fd = -1;
  struct volume_id *vid = NULL;
  int ret = 1;
  gboolean has_children;
  gboolean is_swap;
  gboolean is_cdrom;
  gboolean is_partition = FALSE;
  gboolean has_audio = FALSE;
  gboolean has_data = FALSE;
  gboolean is_blank = FALSE;
  const char *usage;
  char *label;
  unsigned int sector_size = 0;
  off_t media_size = 0;

  if (! hfp_init(argc, argv))
    goto end;

  device_file = getenv("HAL_PROP_BLOCK_DEVICE");
  if (! device_file)
    goto end;

  parent_udi = getenv("HAL_PROP_INFO_PARENT");
  if (! parent_udi)
    goto end;

  /* give a meaningful process title for ps(1) */
  setproctitle("%s", device_file);

  has_children = hfp_getenv_bool("HF_HAS_CHILDREN");
  is_swap = hfp_getenv_bool("HF_IS_SWAP");

  fd = open(device_file, O_RDONLY);
  if (fd < 0)
    goto end;

  parent_drive_type = libhal_device_get_property_string(hfp_ctx, parent_udi, "storage.drive_type", &hfp_error);
  dbus_error_free(&hfp_error);

  grandparent_udi = libhal_device_get_property_string(hfp_ctx, parent_udi, "info.parent", &hfp_error);
  dbus_error_free(&hfp_error);

  is_cdrom = parent_drive_type && ! strcmp(parent_drive_type, "cdrom");
  g_free(parent_drive_type);

  if (is_cdrom)
    {
      hf_probe_volume_get_disc_info(fd, &has_audio, &has_data);
      is_blank = (! has_audio && ! has_data);
    }

  ioctl(fd, DIOCGMEDIASIZE, &media_size);

  /*
   * We only check for filesystems if the volume has no children,
   * otherwise volume_id might find a filesystem in what is actually
   * the first child partition of the volume.
   *
   * If hald (which has looked at the partition type) reports that it
   * is a swap partition, we probe it nevertheless in case the
   * partition type is incorrect.
   */
  if (! has_children && ! (is_cdrom && ! has_data))
    {
      vid = volume_id_open_fd(fd);
      if (vid)
	{
	  if (volume_id_probe_all(vid, 0, media_size) == 0)
	    has_data = TRUE;
	  else
	    {
	      volume_id_close(vid);
	      vid = NULL;
	    }
	}
    }

  if (! has_children && ! is_swap && ! has_audio && ! has_data && ! is_blank)
    goto end;

  libhal_device_add_capability(hfp_ctx, hfp_udi, "volume", &hfp_error);
  if (is_cdrom)
    {
      HFPCDROM *cdrom;
      int type;
      guint64 capacity;

      libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "volume.disc", &hfp_error);
      libhal_device_add_capability(hfp_ctx, hfp_udi, "volume.disc", &hfp_error);

      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.has_audio", has_audio, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.has_data", has_data, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_vcd", FALSE, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_svcd", FALSE, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_videodvd", FALSE, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_appendable", FALSE, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_blank", is_blank, &hfp_error);
      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", FALSE, &hfp_error);
      libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "unknown", &hfp_error);

      /* the following code was adapted from linux's probe-volume.c */

      cdrom = hfp_cdrom_new_from_fd(fd, device_file, grandparent_udi);
      if (cdrom)
	{
	  type = get_disc_type(cdrom);
	  if (type != -1)
	    switch (type)
	      {
	      case 0x08: /* CD-ROM */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_rom", &hfp_error);
		break;
	      case 0x09: /* CD-R */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_r", &hfp_error);
		break;
	      case 0x0a: /* CD-RW */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x10: /* DVD-ROM */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rom", &hfp_error);
		break;
	      case 0x11: /* DVD-R Sequential */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_r", &hfp_error);
		break;
	      case 0x12: /* DVD-RAM */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_ram", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x13: /* DVD-RW Restricted Overwrite */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x14: /* DVD-RW Sequential */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x1A: /* DVD+RW */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x1B: /* DVD+R */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_r", &hfp_error);
		break;
	      case 0x2B: /* DVD+R Double Layer */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_r_dl", &hfp_error);
		break;
	      case 0x40: /* BD-ROM  */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_rom", &hfp_error);
		break;
	      case 0x41: /* BD-R Sequential */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_r", &hfp_error);
		break;
	      case 0x42: /* BD-R Random */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_r", &hfp_error);
		break;
	      case 0x43: /* BD-RE */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_re", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      case 0x50: /* HD DVD-ROM */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_rom", &hfp_error);
		break;
	      case 0x51: /* HD DVD-R */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_r", &hfp_error);
		break;
	      case 0x52: /* HD DVD-Rewritable */
		libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_rw", &hfp_error);
		libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
		break;
	      }

	  if (get_disc_capacity_for_type(cdrom, type, &capacity) == 0)
	    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.disc.capacity", capacity, &hfp_error);

	  /*
	   * linux's probe-volume.c: "on some hardware the get_disc_type
	   * call fails, so we use this as a backup".
	   */
	  if (disc_is_rewritable(cdrom))
	    libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error);
	  if (disc_is_appendable(cdrom))
	    libhal_device_set_property_bool (hfp_ctx, hfp_udi, "volume.disc.is_appendable", TRUE, &hfp_error);

	  hfp_cdrom_free(cdrom);
	}

      if (has_data && vid && (! strcmp(vid->type, "iso9660") ||
          ! strcmp(vid->type, "udf")))
        hf_probe_volume_advanced_disc_detect(fd);
    }
  else
    {
      libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "volume", &hfp_error);

      if (libhal_device_query_capability(hfp_ctx, parent_udi, "storage", &hfp_error))
	{
	  char *geom_class;
	  char *type;
	  char *scheme;
	  int number;
	  guint64 mediasize;
	  guint64 offset;

	  geom_class = getenv("HF_VOLUME_GEOM_CLASS");

	  if (geom_class)
            {
              if (hf_probe_volume_get_partition_info(geom_class, device_file, &number, &type, &scheme, &mediasize, &offset))
                {
                  is_partition = TRUE;

		  libhal_device_set_property_int(hfp_ctx, hfp_udi, "volume.partition.number", number, &hfp_error);
		  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.scheme", scheme, &hfp_error);
		  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.type", type, &hfp_error);

		  /* FIXME We need to fill in the supported partition flags. */

		  libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.partition.media_size", mediasize, &hfp_error);
		  libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.partition.start", offset, &hfp_error);

		  if (! strcmp(scheme, "gpt"))
                    libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.uuid", type, &hfp_error);

		  if (! strcmp(scheme, "gpt") || ! strcmp(scheme, "apm"))
                    libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.label", "", &hfp_error);

		  g_free(type);
		  g_free(scheme);
		}
	    }
	}
      else
	dbus_error_free(&hfp_error);
    }

  libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.is_disc", is_cdrom, &hfp_error);
  libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.is_partition", is_partition, &hfp_error);

  libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", has_children || is_swap, &hfp_error);

#ifdef HAVE_LIBUFS
  if (vid && ! strcmp (vid->type, "ufs"))
    {
      struct uufsd ufsdisk;

      if (ufs_disk_fillout(&ufsdisk, device_file) == 0)
        {
	  char ufsid[64];
	  char **ufs_devs = NULL;
	  int num_udis;
	  int i;

	  snprintf(ufsid, sizeof(ufsid), "%08x%08x", ufsdisk.d_fs.fs_id[0], ufsdisk.d_fs.fs_id[1]);
	  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.freebsd.ufsid", ufsid, &hfp_error);
	  dbus_error_free(&hfp_error);
	  ufs_devs = libhal_manager_find_device_string_match(hfp_ctx,
			  				     "volume.freebsd.ufsid",
							     ufsid,
							     &num_udis,
							     &hfp_error);
	  dbus_error_free(&hfp_error);
	  for (i = 0; i < num_udis; i++)
            {
              if (ufs_devs[i] != NULL && strcmp(ufs_devs[i], hfp_udi))
                {
                  gboolean mounted;

		  mounted = libhal_device_get_property_bool(hfp_ctx, ufs_devs[i], "volume.is_mounted", &hfp_error);
	          dbus_error_free(&hfp_error);
		  if (mounted)
	            {
                      libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", TRUE, &hfp_error);
		      dbus_error_free(&hfp_error);
		      break;
		    }
		}
	    }
	  if (ufs_devs)
	    libhal_free_string_array(ufs_devs);
	  ufs_disk_close(&ufsdisk);
	}
    }
#endif /* HAVE_LIBUFS */

  if (has_children)
    usage = "partitiontable";
  else if (is_swap)
    usage = "other";
  else
    switch (vid ? vid->usage_id : (enum volume_id_usage) -1)
      {
      case VOLUME_ID_FILESYSTEM:	usage = "filesystem"; break;
      case VOLUME_ID_DISKLABEL:		usage = "disklabel"; break;
      case VOLUME_ID_OTHER:		usage = "other"; break;
      case VOLUME_ID_RAID:		usage = "raid"; break;
      case VOLUME_ID_CRYPTO:		usage = "crypto"; break;
      case VOLUME_ID_UNUSED:		usage = "unused"; break;
      default:				usage = "unknown"; break;
      }

  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fsusage", usage, &hfp_error);
  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fstype", vid ? vid->type: "", &hfp_error);
  if (vid && *vid->type_version)
    libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fsversion", vid->type_version, &hfp_error);

  label = hf_probe_volume_get_label(vid);
  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.label", label ? label : "", &hfp_error);
  g_free(label);

  libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.uuid", vid ? vid->uuid : "", &hfp_error);

  ioctl(fd, DIOCGSECTORSIZE, &sector_size);

  if (sector_size != 0)
    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.block_size", sector_size, &hfp_error);
  if (media_size != 0)
    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.size", media_size, &hfp_error);
  if (sector_size != 0 && media_size != 0)
    libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.num_blocks", media_size / sector_size, &hfp_error);

  ret = 0;			/* is a volume */

 end:
  return ret;
}
コード例 #8
0
ファイル: probe-volume.c プロジェクト: bbidulock/hal
static void
hf_probe_volume_advanced_disc_detect (int fd)
{
  size_t secsz = ISO_DEFAULT_BLOCK_SIZE;
  int readoff;
  struct iso_primary_descriptor desc;
  u_char *ptbl;
  int ptbl_size, ptbl_bsize;
  int ptbl_lbn;
  struct iso_path_table_entry *pte;
  int pte_len;
  int name_len;
  int off;

  readoff = ISO_VOLDESC_SEC * secsz;
  do
    {
      if (pread(fd, &desc, sizeof desc, readoff) != sizeof desc)
        {
          hfp_warning("volume descriptor read error");
	  return;
	}
      if (isonum_711(desc.type) == ISO_VD_END)
        return;
      readoff += secsz;
    }
  while (isonum_711(desc.type) != ISO_VD_PRIMARY);

  ptbl_size = isonum_733(desc.path_table_size);
#if BYTE_ORDER == LITTLE_ENDIAN
  ptbl_lbn = isonum_731(desc.type_l_path_table);
#else
  ptbl_lbn = isonum_732(desc.type_m_path_table);
#endif
  ptbl_bsize = (ptbl_size + secsz - 1) / secsz * secsz;
  ptbl = g_malloc(ptbl_bsize);
  if (ptbl == NULL)
    {
      hfp_warning("path table allocation failure");
      return;
    }
  readoff = ptbl_lbn * secsz;
  if (pread(fd, ptbl, ptbl_bsize, readoff) != ptbl_bsize)
    {
      g_free(ptbl);
      hfp_warning("path table read error");
    }
  for (off = 0; off < ptbl_size; off += pte_len)
    {
      pte = (struct iso_path_table_entry *)(ptbl + off);
      name_len = *pte->name_len;
      pte_len = ISO_PATH_TABLE_ENTRY_SIZE + name_len + (name_len % 2);
      if (*(short *)pte->parent_no != 1)
        continue;
      if (name_len == 8 && strncmp(pte->name, "VIDEO_TS", 8) == 0)
        {
          libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_videodvd", TRUE, &hfp_error);
	  break;
	}
      else if (name_len == 3 && strncmp(pte->name, "VCD", 8) == 0)
        {
          libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_vcd", TRUE, &hfp_error);
	  break;
	}
      else if (name_len == 4 && strncmp(pte->name, "SVCD", 4) == 0)
        {
          libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_svcd", TRUE, &hfp_error);
	  break;
	}
    }
  g_free(ptbl);
}
コード例 #9
0
/* returns: whether the state changed */
static gboolean
poll_for_media_force (void)
{
        int fd;
        int got_media;
        int old_media_status;

	got_media = FALSE;

        old_media_status = media_status;
	if (is_cdrom) {
		int drive;
		
		fd = open (device_file, O_RDONLY | O_NONBLOCK | O_EXCL);
		
		if (fd < 0 && errno == EBUSY) {
			/* this means the disc is mounted or some other app,
			 * like a cd burner, has already opened O_EXCL */
			
			/* HOWEVER, when starting hald, a disc may be
			 * mounted; so check /etc/mtab to see if it
			 * actually is mounted. If it is we retry to open
			 * without O_EXCL
			 */
			if (!is_mounted (device_file)) {
                                if (!is_locked_via_o_excl) {
                                        is_locked_via_o_excl = TRUE;
                                        update_proc_title ();
                                } else {
                                        is_locked_via_o_excl = TRUE;
                                }
				goto skip_check;
                        }
			
			fd = open (device_file, O_RDONLY | O_NONBLOCK);
		}
		
		if (fd < 0) {
			HAL_ERROR (("open failed for %s: %s", device_file, strerror (errno))); 
			goto skip_check;
		}

                if (is_locked_via_o_excl) {
                        is_locked_via_o_excl = FALSE;
                        update_proc_title ();
                }
		
		
		/* Check if a disc is in the drive
		 *
		 * @todo Use MMC-2 API if applicable
		 */
		drive = ioctl (fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
		switch (drive) {
		case CDS_NO_INFO:
		case CDS_NO_DISC:
		case CDS_TRAY_OPEN:
		case CDS_DRIVE_NOT_READY:
			break;
			
		case CDS_DISC_OK:
			/* some CD-ROMs report CDS_DISK_OK even with an open
			 * tray; if media check has the same value two times in
			 * a row then this seems to be the case and we must not
			 * report that there is a media in it. */
			if (support_media_changed &&
			    ioctl (fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT) && 
			    ioctl (fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT)) {
			} else {
				got_media = TRUE;
			}
			break;
			
		case -1:
			HAL_ERROR (("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno)));
			break;
			
		default:
			break;
		}
		
		/* check if eject button was pressed */
		if (got_media) {
			unsigned char cdb[10] = { 0x4a, 1, 0, 0, 16, 0, 0, 0, 8, 0};
			unsigned char buffer[8];
			struct sg_io_hdr sg_h;
			int retval;
			
			memset(buffer, 0, sizeof(buffer));
			memset(&sg_h, 0, sizeof(struct sg_io_hdr));
			sg_h.interface_id = 'S';
			sg_h.cmd_len = sizeof(cdb);
			sg_h.dxfer_direction = SG_DXFER_FROM_DEV;
			sg_h.dxfer_len = sizeof(buffer);
			sg_h.dxferp = buffer;
			sg_h.cmdp = cdb;
			sg_h.timeout = 5000;
			retval = ioctl(fd, SG_IO, &sg_h);
			if (retval == 0 && sg_h.status == 0 && (buffer[4] & 0x0f) == 0x01) {
				DBusError error;
				
				/* emit signal from drive device object */
				dbus_error_init (&error);
				libhal_device_emit_condition (ctx, udi, "EjectPressed", "", &error);
				LIBHAL_FREE_DBUS_ERROR (&error);
			}
		}
		close (fd);
	} else {
		fd = open (device_file, O_RDONLY);
		if (fd < 0 && errno == ENOMEDIUM) {
			got_media = FALSE;
		} else if (fd >= 0) {
			got_media = TRUE;
			close (fd);
		} else {
			HAL_ERROR (("open failed for %s: %s", device_file, strerror (errno))); 
			goto skip_check;
		}
	}
	
	/* set correct state on startup, this avoid endless loops if there was a media in the device on startup */
	if (media_status == MEDIA_STATUS_UNKNOWN) {
		if (got_media) 
			media_status = MEDIA_STATUS_NO_MEDIA;
		else 
			media_status = MEDIA_STATUS_GOT_MEDIA;	
	}

	switch (media_status) {
	case MEDIA_STATUS_GOT_MEDIA:
		if (!got_media) {
			DBusError error;
			
			HAL_DEBUG (("Media removal detected on %s", device_file));
			libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, NULL);
			libhal_device_set_property_string (ctx, udi, "storage.partitioning_scheme", "", NULL);
			
			
			/* attempt to unmount all childs */
			unmount_childs (ctx, udi);
			
			/* could have a fs on the main block device; do a rescan to remove it */
			dbus_error_init (&error);
			libhal_device_rescan (ctx, udi, &error);
			LIBHAL_FREE_DBUS_ERROR (&error);
			
			/* have to this to trigger appropriate hotplug events */
			fd = open (device_file, O_RDONLY | O_NONBLOCK);
			if (fd >= 0) {
				ioctl (fd, BLKRRPART);
				close (fd);
			}
		}
		break;
		
	case MEDIA_STATUS_NO_MEDIA:
		if (got_media) {
			DBusError error;
			
			HAL_DEBUG (("Media insertion detected on %s", device_file));
			
			/* our probe will trigger the appropriate hotplug events */
			libhal_device_set_property_bool (
				ctx, udi, "storage.removable.media_available", TRUE, NULL);
			
			/* could have a fs on the main block device; do a rescan to add it */
			dbus_error_init (&error);
			libhal_device_rescan (ctx, udi, &error);
			LIBHAL_FREE_DBUS_ERROR (&error);
		}
		break;
		
	case MEDIA_STATUS_UNKNOWN:
	default:
		break;
	}
	
	/* update our current status */
	if (got_media)
		media_status = MEDIA_STATUS_GOT_MEDIA;
	else
		media_status = MEDIA_STATUS_NO_MEDIA;
	
	/*HAL_DEBUG (("polling %s; got media=%d", device_file, got_media));*/
	
skip_check:
	return old_media_status != media_status;
}
コード例 #10
0
ファイル: hal_set_property.c プロジェクト: bbidulock/hal
/** 
 *  main:
 *  @argc:                Number of arguments given to program
 *  @argv:                Arguments given to program
 *
 *  Returns:              Return code
 *
 *  Main entry point 
 */
int
main (int argc, char *argv[])
{
	dbus_bool_t rc = 0;
	char *udi = NULL;
	char *key = NULL;
	char *str_value = NULL;
	dbus_int32_t int_value = 0;
	dbus_uint64_t uint64_value = 0;
	double double_value = 0.0f;
	dbus_bool_t bool_value = TRUE;
	dbus_bool_t remove = FALSE;
	dbus_bool_t is_version = FALSE;
	int type = PROP_INVALID;
	DBusError error;
	dbus_bool_t direct = FALSE;

	if (argc <= 1) {
		usage (argc, argv);
		return 1;
	}

	while (1) {
		int c;
		int option_index = 0;
		const char *opt;
		static struct option long_options[] = {
			{"udi", 1, NULL, 0},
			{"key", 1, NULL, 0},
			{"int", 1, NULL, 0},
			{"uint64", 1, NULL, 0},
			{"string", 1, NULL, 0},
			{"double", 1, NULL, 0},
			{"bool", 1, NULL, 0},
			{"strlist-pre", 1, NULL, 0},
			{"strlist-post", 1, NULL, 0},
			{"strlist-rem", 1, NULL, 0},
			{"direct", 0, NULL, 0},
			{"remove", 0, NULL, 0},
			{"version", 0, NULL, 0},
			{"help", 0, NULL, 0},
			{NULL, 0, NULL, 0}
		};
		
		c = getopt_long (argc, argv, "",
				 long_options, &option_index);
		if (c == -1)
			break;

		switch (c) {
		case 0:
			opt = long_options[option_index].name;

			if (strcmp (opt, "help") == 0) {
				usage (argc, argv);
				return 0;
			} else if (strcmp (opt, "key") == 0) {
				key = strdup (optarg);
			} else if (strcmp (opt, "string") == 0) {
				str_value = strdup (optarg);
				type = PROP_STRING;
			} else if (strcmp (opt, "int") == 0) {
				int_value = strtol (optarg, NULL, 0);
				type = PROP_INT;
			} else if (strcmp (opt, "uint64") == 0) {
				uint64_value = strtoull (optarg, NULL, 0);
				type = PROP_UINT64;
			} else if (strcmp (opt, "double") == 0) {
				double_value = (double) atof (optarg);
				type = PROP_DOUBLE;
			} else if (strcmp (opt, "bool") == 0) {
				if (strcmp (optarg, "true") == 0)
					bool_value = TRUE;
				else if (strcmp (optarg, "false") == 0)
					bool_value = FALSE;
				else {
					usage (argc, argv);
					return 1;
				}
				type = PROP_BOOL;
			} else if (strcmp (opt, "strlist-pre") == 0) {
				str_value = strdup (optarg);
				type = PROP_STRLIST_PRE;
			} else if (strcmp (opt, "strlist-post") == 0) {
				str_value = strdup (optarg);
				type = PROP_STRLIST_POST;
			} else if (strcmp (opt, "strlist-rem") == 0) {
				str_value = strdup (optarg);
				type = PROP_STRLIST_REM;
			} else if (strcmp (opt, "remove") == 0) {
				remove = TRUE;
			} else if (strcmp (opt, "direct") == 0) {
				direct = TRUE;
			} else if (strcmp (opt, "udi") == 0) {
				udi = strdup (optarg);
			} else if (strcmp (opt, "version") == 0) {
				is_version = TRUE;
			}
			break;

		default:
			usage (argc, argv);
			return 1;
			break;
		}
	}

	if (is_version) {
		printf ("hal-set-property " PACKAGE_VERSION "\n");
		return 0;
	}

	/* must have at least one, but not neither or both */
	if ((remove && type != PROP_INVALID) || ((!remove) && type == PROP_INVALID)) {
		usage (argc, argv);
		return 1;
	}
	
	fprintf (stderr, "\n");
	
	dbus_error_init (&error);
	if (direct) {
		if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
			fprintf (stderr, "error: libhal_ctx_init_direct\n");
			LIBHAL_FREE_DBUS_ERROR (&error);
			return 1;
		}
	} else {
		if ((hal_ctx = libhal_ctx_new ()) == NULL) {
			fprintf (stderr, "error: libhal_ctx_new\n");
			return 1;
		}
		if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
			fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message);
			LIBHAL_FREE_DBUS_ERROR (&error);
			return 1;
		}
		if (!libhal_ctx_init (hal_ctx, &error)) {
			if (dbus_error_is_set(&error)) {
				fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message);
				dbus_error_free (&error);
			}
			fprintf (stderr, "Could not initialise connection to hald.\n"
					"Normally this means the HAL daemon (hald) is not running or not ready.\n");
			return 1;
		}
	}

	if (remove) {
		rc = libhal_device_remove_property (hal_ctx, udi, key, &error);
		if (!rc) {
			fprintf (stderr, "error: libhal_device_remove_property: %s: %s\n", error.name, error.message);
			LIBHAL_FREE_DBUS_ERROR (&error);
			return 1;
		}
	} else {
		switch (type) {
		case PROP_STRING:
			rc = libhal_device_set_property_string (hal_ctx, udi, key, str_value, &error);
			break;
		case PROP_INT:
			rc = libhal_device_set_property_int (hal_ctx, udi, key, int_value, &error);
			break;
		case PROP_UINT64:
			rc = libhal_device_set_property_uint64 (hal_ctx, udi, key, uint64_value, &error);
			break;
		case PROP_DOUBLE:
			rc = libhal_device_set_property_double (hal_ctx, udi, key, double_value, &error);
			break;
		case PROP_BOOL:
			rc = libhal_device_set_property_bool (hal_ctx, udi, key, bool_value, &error);
			break;
		case PROP_STRLIST_PRE:
			rc = libhal_device_property_strlist_prepend (hal_ctx, udi, key, str_value, &error);
			break;
		case PROP_STRLIST_POST:
			rc = libhal_device_property_strlist_append (hal_ctx, udi, key, str_value, &error);
			break;
		case PROP_STRLIST_REM:
			rc = libhal_device_property_strlist_remove (hal_ctx, udi, key, str_value, &error);
			break;
		}
		if (!rc) {
			fprintf (stderr, "error: libhal_device_set_property: %s: %s\n", error.name, error.message);
			dbus_error_free (&error);
			return 1;
		}
	}
	    
	return rc ? 0 : 1;
}
コード例 #11
0
int
main (int argc, char *argv[])
{
	DBusError err;
	int retval = 0;

	hal_set_proc_title_init (argc, argv);

	setup_logger ();	

	device_udi = getenv ("UDI");

	HAL_DEBUG (("device:[%s]", device_udi));
	if (device_udi == NULL) {
		HAL_ERROR (("No device specified"));
		return -2;
	}

	dbus_error_init (&err);
	if ((halctx = libhal_ctx_init_direct (&err)) == NULL) {
		HAL_ERROR (("Cannot connect to hald"));
		retval = -3;
		goto out;
	}


	/* update_properties */
	libhal_device_set_property_bool (halctx, device_udi, 
			"battery.present", TRUE, &err);

	LIBHAL_FREE_DBUS_ERROR (&err);
	if (!libhal_device_property_exists (halctx, device_udi, 
			"battery.is_rechargeable", &err)) {
		LIBHAL_FREE_DBUS_ERROR (&err);
		libhal_device_set_property_bool (halctx, device_udi, 
			"battery.is_rechargeable", FALSE, &err);
	}

	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_set_property_int (halctx, device_udi, 
			"battery.charge_level.design", 7, &err);
	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_set_property_int (halctx, device_udi, 
			"battery.charge_level.last_full", 7, &err);
	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_set_property_string (halctx, device_udi, 
			"info.category", "battery", &err);
	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_set_property_string (halctx, device_udi, 
			"battery.command_interface", "csr", &err);

	/* monitor change */
	libhal_ctx_set_device_property_modified (halctx, property_modified);

	/* Initial fillup */
	dev_props = property_cache_item_get (device_udi);
	HAL_ERROR (("** Initial fillup done"));

	/* init usb */
	usb_init ();
	
	/* do coldplug */
	check_all_batteries (NULL);

	/* only add capability when initial charge_level key has been set */
	LIBHAL_FREE_DBUS_ERROR (&err);
	libhal_device_add_capability (halctx, device_udi, "battery", &err);

	LIBHAL_FREE_DBUS_ERROR (&err);
	if (!libhal_device_addon_is_ready (halctx, device_udi, &err)) {
		retval = -4;
		goto out;
	}

	hal_set_proc_title ("hald-addon-usb-csr: listening on '%s'", 
			    libhal_device_get_property_string(halctx, device_udi,
							      "info.product", &err));

	main_loop = g_main_loop_new (NULL, FALSE);
#ifdef HAVE_GLIB_2_14
	g_timeout_add_seconds (TIMEOUT, check_all_batteries, NULL);
#else
	g_timeout_add (1000L * TIMEOUT, check_all_batteries, NULL);
#endif
	g_main_loop_run (main_loop);
	return 0;

out:
        HAL_DEBUG (("An error occured, exiting cleanly"));

        LIBHAL_FREE_DBUS_ERROR (&err);

        if (halctx != NULL) {
                libhal_ctx_shutdown (halctx, &err);
                LIBHAL_FREE_DBUS_ERROR (&err);
                libhal_ctx_free (halctx);
        }

        return retval;
}
コード例 #12
0
ファイル: battery.c プロジェクト: alhazred/onarm
static void
battery_dynamic_update(LibHalContext *ctx, const char *udi, int fd)
{
	int reporting_rate;
	int reporting_current;
	int reporting_lastfull;
	int design_voltage;
	int present_voltage;
	char *reporting_unit;
	int remaining_time;
	int remaining_percentage;
	gboolean charging;
	gboolean discharging;
	acpi_bst_t bst;
	LibHalChangeSet *cs;
	DBusError error;
	static int counter = 0;

	HAL_DEBUG(("battery_dynamic_update() enter"));
	bzero(&bst, sizeof (bst));
	if (ioctl(fd, BATT_IOC_STATUS, &bst) < 0) {
		return;
	}

	charging = bst.bst_state & BATT_BST_CHARGING ? TRUE : FALSE;
	discharging = bst.bst_state & BATT_BST_DISCHARGING ? TRUE : FALSE;
	/* No need to continue if battery is essentially idle. */
	if (counter && !charging && !discharging) {
		return;
	}
	dbus_error_init(&error);
	libhal_device_set_property_bool(ctx, udi, "battery.is_rechargeable",
	    TRUE, &error);
	my_dbus_error_free(&error);
	if (libhal_device_property_exists(ctx, udi,
	    "battery.charge_level.percentage", &error)) {
		remaining_percentage = libhal_device_get_property_int(ctx, udi,
		    "battery.charge_level.percentage", &error);
		if ((remaining_percentage == 100) && charging) {
			charging = FALSE;
		}
	}
	libhal_device_set_property_bool(ctx, udi,
	    "battery.rechargeable.is_charging", charging, &error);
	my_dbus_error_free(&error);
	libhal_device_set_property_bool(ctx, udi,
	    "battery.rechargeable.is_discharging", discharging, &error);
	my_dbus_error_free(&error);
	reporting_current = bst.bst_rem_cap;
	libhal_device_set_property_int(ctx, udi, "battery.reporting.current",
	    bst.bst_rem_cap, &error);
	my_dbus_error_free(&error);
	reporting_rate = bst.bst_rate;
	libhal_device_set_property_int(ctx, udi, "battery.reporting.rate",
	    bst.bst_rate, &error);
	my_dbus_error_free(&error);
	present_voltage = bst.bst_voltage;
	libhal_device_set_property_int(ctx, udi, "battery.voltage.present",
	    bst.bst_voltage, &error);
	/* get all the data we know */
	my_dbus_error_free(&error);
	reporting_unit = libhal_device_get_property_string(ctx, udi,
	    "battery.reporting.unit", &error);
	my_dbus_error_free(&error);
	reporting_lastfull = libhal_device_get_property_int(ctx, udi,
	    "battery.reporting.last_full", &error);

	/*
	 * Convert mAh to mWh since util_compute_time_remaining() works
	 * for mWh.
	 */
	if (reporting_unit && strcmp(reporting_unit, "mAh") == 0) {
		my_dbus_error_free(&error);
		design_voltage = libhal_device_get_property_int(ctx, udi,
		    "battery.voltage.design", &error);
		/*
		 * If the present_voltage is inaccurate, set it to the
		 * design_voltage.
		 */
		if (((present_voltage * 10) < design_voltage) ||
		    (present_voltage <= 0) ||
		    (present_voltage > design_voltage)) {
			present_voltage = design_voltage;
		}
		reporting_rate = (reporting_rate * present_voltage) / 1000;
		reporting_lastfull = (reporting_lastfull * present_voltage) /
		    1000;
		reporting_current = (reporting_current * present_voltage) /
		    1000;
	}

	/* Make sure the current charge does not exceed the full charge */
	if (reporting_current > reporting_lastfull) {
		reporting_current = reporting_lastfull;
	}
	if (!charging && !discharging) {
		counter++;
		reporting_rate = 0;
	}

	if ((cs = libhal_device_new_changeset(udi)) == NULL) {
		HAL_DEBUG(("Cannot allocate changeset"));
		libhal_free_string(reporting_unit);
		my_dbus_error_free(&error);
		return;
	}

	libhal_changeset_set_property_int(cs, "battery.charge_level.rate",
	    reporting_rate);
	libhal_changeset_set_property_int(cs,
	    "battery.charge_level.last_full", reporting_lastfull);
	libhal_changeset_set_property_int(cs,
	    "battery.charge_level.current", reporting_current);

	remaining_percentage = util_compute_percentage_charge(udi,
	    reporting_current, reporting_lastfull);
	remaining_time = util_compute_time_remaining(udi, reporting_rate,
	    reporting_current, reporting_lastfull, discharging, charging, 0);
	/*
	 * Some batteries give bad remaining_time estimates relative to
	 * the charge level.
	 */
	if (charging && ((remaining_time < 30) || ((remaining_time < 300) &&
	    (remaining_percentage < 95)) || (remaining_percentage > 97))) {
		remaining_time = util_compute_time_remaining(udi,
		    reporting_rate, reporting_current, reporting_lastfull,
		    discharging, charging, 1);
	}

	if (remaining_percentage > 0) {
		libhal_changeset_set_property_int(cs,
		    "battery.charge_level.percentage", remaining_percentage);
	} else {
		my_dbus_error_free(&error);
		libhal_device_remove_property(ctx, udi,
		    "battery.charge_level.percentage", &error);
	}
	if ((remaining_percentage == 100) && charging) {
		battery_last_full(cs, fd);
	}
	/*
	 * remaining_percentage is more accurate so we handle cases
	 * where the remaining_time cannot be correct.
	 */
	if ((!charging && !discharging) || ((remaining_percentage == 100) &&
	    !discharging)) {
		remaining_time = 0;
	}
	if (remaining_time < 0) {
		my_dbus_error_free(&error);
		libhal_device_remove_property(ctx, udi,
		    "battery.remaining_time", &error);
	} else if (remaining_time >= 0) {
		libhal_changeset_set_property_int(cs,
		    "battery.remaining_time", remaining_time);
	}

	my_dbus_error_free(&error);
	libhal_device_commit_changeset(ctx, cs, &error);
	libhal_device_free_changeset(cs);
	libhal_free_string(reporting_unit);
	my_dbus_error_free(&error);
	HAL_DEBUG(("battery_dynamic_update() exit"));
}
コード例 #13
0
ファイル: hal-device.c プロジェクト: AlainODea/illumos-gate
int add_properties(LibHalContext *hal_ctx, new_dev_t *nd, lh_prop_t *prop)
{
	DBusError error;
	lh_prop_t *p;
	char *udi2 = NULL, *udi3 = NULL, **s;
	LibHalPropertyType old_type;

	dbus_error_init(&error);

	for(p = prop; p; p = p->next) {
		if (!strcmp(p->key, "udi") && p->type == LIBHAL_PROPERTY_TYPE_STRING) {
			udi2 = p->v.str_value;
			continue;
		}

		old_type = libhal_device_get_property_type(hal_ctx, nd->real_udi, p->key, &error);
		dbus_error_init(&error);

		if (old_type != LIBHAL_PROPERTY_TYPE_INVALID &&
		    ( p->type != old_type || p->type == LIBHAL_PROPERTY_TYPE_STRLIST)) {
			if (!libhal_device_remove_property(hal_ctx, nd->real_udi, p->key, &error)) {
				fprintf(stderr, "%s: %s\n", error.name, error.message);
				LIBHAL_FREE_DBUS_ERROR (&error);
				return 41;
			}
		}

		switch (p->type) {
			case LIBHAL_PROPERTY_TYPE_INVALID:
				break;
			case LIBHAL_PROPERTY_TYPE_BOOLEAN:
				if (!libhal_device_set_property_bool(hal_ctx, nd->real_udi, p->key, p->v.bool_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_INT32:
				if (!libhal_device_set_property_int(hal_ctx, nd->real_udi, p->key, p->v.int_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_UINT64:
				if (!libhal_device_set_property_uint64(hal_ctx, nd->real_udi, p->key, p->v.uint64_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_DOUBLE:
				if (!libhal_device_set_property_double(hal_ctx, nd->real_udi, p->key, p->v.double_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_STRING:
				if (!strcmp(p->key, "info.udi")) udi3 = p->v.str_value;
				if (!libhal_device_set_property_string(hal_ctx, nd->real_udi, p->key, p->v.str_value, &error)) {
					fprintf(stderr, "%s: %s\n", error.name, error.message);
					LIBHAL_FREE_DBUS_ERROR (&error);
					return 42;
				}
				break;
			case LIBHAL_PROPERTY_TYPE_STRLIST:
				for(s = p->v.strlist_value; *s; s++) {
					if (!libhal_device_property_strlist_append(hal_ctx, nd->real_udi, p->key, *s, &error)) {
						fprintf(stderr, "%s: %s\n", error.name, error.message);
						LIBHAL_FREE_DBUS_ERROR (&error);
						return 42;
					}
				}
				break;
		}
	}

	if (udi2) udi3 = NULL;
	if (udi3) udi2 = udi3;

	if (udi2 && !nd->udi)
		nd->udi = strdup(udi2);

	return 0;
}