Logo Search packages:      
Sourcecode: hal version File versions

static void net_class_pre_process ( ClassDeviceHandler self,
HalDevice *  d,
const char *  sysfs_path,
struct sysfs_class_device *  class_device 
) [static]

This method is called just before the device is either merged onto the sysdevice or added to the GDL (cf. merge_or_add). This is useful for extracting more information about the device through e.g. ioctl's using the device file property and also for setting info.category|capability.

Parameters:
self Pointer to class members
d The HalDevice object of the instance of this device class
sysfs_path The path in sysfs (including mount point) of the class device in sysfs
class_device Libsysfs object representing class device instance

Definition at line 526 of file net_class_device.c.

References get_last_element(), hal_device_add_capability(), HAL_INFO, parse_dec(), and parse_hex().

{
      struct sysfs_attribute *attr;
      char *address = NULL;
      int media_type = 0;
      const char *media;
      char wireless_path[SYSFS_PATH_MAX];
      char driver_path[SYSFS_PATH_MAX];
      dbus_bool_t is_80211;
      int ifindex;
      int flags;
      struct stat statbuf;
#if PCMCIA_SUPPORT_ENABLE
      pcmcia_stab_entry *entry;
#endif

      hal_device_property_set_string (d, "net.linux.sysfs_path", sysfs_path);
      hal_device_property_set_string (d, "net.interface",
                              class_device->name);

      is_80211 = FALSE;

      /* Check driver link (may be unavailable for PCMCIA devices) */
      snprintf (driver_path, SYSFS_PATH_MAX, "%s/driver", sysfs_path);
      if (stat (driver_path, &statbuf) == 0) {
            char buf[256];
            memset (buf, '\0', sizeof (buf));
            if (readlink (driver_path, buf, sizeof (buf) - 1) > 0) {
                  hal_device_property_set_string (d, "net.linux.driver", get_last_element (buf));
            }
      }

      attr = sysfs_get_classdev_attr (class_device, "address");
      if (attr != NULL) {
            address = g_strstrip (g_strdup (attr->value));
            hal_device_property_set_string (d, "net.address", address);
      }

      attr = sysfs_get_classdev_attr (class_device, "type");
      if (attr != NULL) {
            media_type = parse_dec (attr->value);
      }

      if (media_type == ARPHRD_ETHER) {
            FILE *f;
            dbus_bool_t is_wireless;


            is_wireless = FALSE;

            f = fopen ("/proc/net/wireless", "ro");
            if (f != NULL) {
                  unsigned int i;
                  unsigned int ifname_len;
                  char buf[128];

                  ifname_len = strlen (class_device->name);

                  do {
                        if (fgets (buf, sizeof (buf), f) == NULL)
                              break;

                        for (i=0; i < sizeof (buf); i++) {
                              if (isspace (buf[i]))
                                    continue;
                              else
                                    break;
                        }

                        if (strncmp (class_device->name, buf + i, ifname_len) == 0) {
                              is_wireless = TRUE;
                              break;
                        }

                  } while (TRUE);
                  fclose (f);
            }

            if (is_wireless) {
            /* Check to see if this interface supports wireless extensions */
            /*
            snprintf (wireless_path, SYSFS_PATH_MAX, "%s/wireless", sysfs_path);
            if (stat (wireless_path, &statbuf) == 0) {
            */
                  hal_device_property_set_string (d, "info.category", "net.80211");
                  hal_device_add_capability (d, "net.80211");
                  is_80211 = TRUE;
            } else {
                  hal_device_property_set_string (d, "info.category", "net.80203");
                  hal_device_add_capability (d, "net.80203");
            }
      }

      attr = sysfs_get_classdev_attr (class_device, "flags");
      if (attr != NULL) {
            flags = parse_hex (attr->value);
            hal_device_property_set_bool (d, "net.interface_up", flags & IFF_UP);
            if (!is_80211 && media_type == ARPHRD_ETHER) {
                  /* TODO: for some reason IFF_RUNNING isn't exported in flags */
                  /*hal_device_property_set_bool (d, "net.80203.link", flags & IFF_RUNNING);*/
#ifdef SYSFS_CARRIER_ENABLE
                  attr = sysfs_get_classdev_attr (class_device, "carrier");
                  if (attr != NULL) {
                        int have_link;

                        have_link = parse_dec (attr->value);
                        HAL_INFO (("According to sysfs link status is %d", have_link));
                        hal_device_property_set_bool (d, "net.80203.link", have_link != 0);
                        HAL_INFO (("Assuming link speed is 100Mbps"));
                        hal_device_property_set_uint64 (d, "net.80203.rate", 100 * 1000 * 1000);
                  }
#else /* SYSFS_CARRIER_ENABLE */
                  mii_get_link (d);
#endif /* SYSFS_CARRIER_ENABLE */
            }
      }

      attr = sysfs_get_classdev_attr (class_device, "ifindex");
      if (attr != NULL) {
            ifindex = parse_dec (attr->value);
            hal_device_property_set_int (d, "net.linux.ifindex", ifindex);
      }

      /* FIXME: Other address types for non-ethernet devices */
      if (address != NULL && media_type == ARPHRD_ETHER) {
            unsigned int a5, a4, a3, a2, a1, a0;

            if (sscanf (address, "%x:%x:%x:%x:%x:%x",
                      &a5, &a4, &a3, &a2, &a1, &a0) == 6) {
                  dbus_uint64_t mac_address;

                  mac_address = 
                        ((dbus_uint64_t)a5<<40) |
                        ((dbus_uint64_t)a4<<32) | 
                        ((dbus_uint64_t)a3<<24) | 
                        ((dbus_uint64_t)a2<<16) | 
                        ((dbus_uint64_t)a1<< 8) | 
                        ((dbus_uint64_t)a0<< 0);

                  /* TODO: comment out when 64-bit python patch is in dbus */
                  hal_device_property_set_uint64 (d, is_80211 ? "net.80211.mac_address" : "net.80203.mac_address",
                                          mac_address);
            }

      }
      g_free (address);

      if (hal_device_has_property (d, "net.80203.link") &&
          hal_device_property_get_bool (d, "net.80203.link")) {
#ifdef SYSFS_CARRIER_ENABLE
            HAL_INFO (("Assuming link speed is 100Mbps"));
            hal_device_property_set_uint64 (d, "net.80203.rate", 100 * 1000 * 1000);
#else /* SYSFS_CARRIER_ENABLE */
            mii_get_rate (d);
#endif /* SYSFS_CARRIER_ENABLE */
      }

      hal_device_property_set_int (d, "net.arp_proto_hw_id", media_type);

      media = media_type_to_string (media_type);
      hal_device_property_set_string (d, "net.media", media);

      hal_device_add_capability (d, "net");

#if PCMCIA_SUPPORT_ENABLE
      /* Add PCMCIA specific entries for PCMCIA cards */
      if ((entry = pcmcia_get_stab_entry_for_device (class_device->name))) {
            pcmcia_card_info *info = pcmcia_card_info_get (entry->socket);
            if (info && (info->socket >= 0)) {
                  const char *type;
                  HalDevice *parent;

                  hal_device_property_set_string (d, "info.bus", "pcmcia");
                  if (entry->driver)
                        hal_device_property_set_string (d, "net.linux.driver", entry->driver);

                  if (info->productid_1 && strlen (info->productid_1))
                        hal_device_property_set_string (d, "pcmcia.productid_1", info->productid_1);
                  if (info->productid_2 && strlen (info->productid_2))
                        hal_device_property_set_string (d, "pcmcia.productid_2", info->productid_2);
                  if (info->productid_3 && strlen (info->productid_3))
                        hal_device_property_set_string (d, "pcmcia.productid_3", info->productid_3);
                  if (info->productid_4 && strlen (info->productid_4))
                        hal_device_property_set_string (d, "pcmcia.productid_4", info->productid_4);

                  if ((type = pcmcia_card_type_string_from_type (info->type)))
                        hal_device_property_set_string (d, "pcmcia.function", type);

                  hal_device_property_set_int (d, "pcmcia.manfid_1", info->manfid_1);
                  hal_device_property_set_int (d, "pcmcia.manfid_2", info->manfid_2);
                  hal_device_property_set_int (d, "pcmcia.socket_number", info->socket);

                  /* Provide best-guess of vendor, goes in Vendor property; 
                   * .fdi files can override this */
                  if (info->productid_1 != NULL) {
                        hal_device_property_set_string (d, "info.vendor", info->productid_1);
                  } else {
                        char namebuf[50];
                        snprintf (namebuf, sizeof(namebuf), "Unknown (0x%04x)", info->manfid_1);
                        hal_device_property_set_string (d, "info.vendor", namebuf);
                  }

                  /* Provide best-guess of name, goes in Product property; 
                   * .fdi files can override this */
                  if (info->productid_2 != NULL) {
                        hal_device_property_set_string (d, "info.product", info->productid_2);
                  } else {
                        char namebuf[50];
                        snprintf (namebuf, sizeof(namebuf), "Unknown (0x%04x)", info->manfid_2);
                        hal_device_property_set_string (d, "info.product", namebuf);
                  }

                  /* Reparent PCMCIA devices to be under their socket */
                  parent = hal_device_store_match_key_value_int (hald_get_gdl (), 
                                                            "pcmcia_socket.number", 
                                                            info->socket);
                  if (parent)
                        hal_device_property_set_string (d, "info.parent",
                                    hal_device_property_get_string (parent, "info.udi"));

            }

            pcmcia_card_info_free (info);
            pcmcia_stab_entry_free (entry);
      }
#endif
}


Generated by  Doxygen 1.6.0   Back to index