lsiio.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Industrial I/O utilities - lsiio.c
  3. *
  4. * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License version 2 as published by
  8. * the Free Software Foundation.
  9. */
  10. #include <string.h>
  11. #include <dirent.h>
  12. #include <stdio.h>
  13. #include <errno.h>
  14. #include <stdint.h>
  15. #include <stdlib.h>
  16. #include <unistd.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <sys/dir.h>
  20. #include "iio_utils.h"
  21. static enum verbosity {
  22. VERBLEVEL_DEFAULT, /* 0 gives lspci behaviour */
  23. VERBLEVEL_SENSORS, /* 1 lists sensors */
  24. } verblevel = VERBLEVEL_DEFAULT;
  25. const char *type_device = "iio:device";
  26. const char *type_trigger = "trigger";
  27. static inline int check_prefix(const char *str, const char *prefix)
  28. {
  29. return strlen(str) > strlen(prefix) &&
  30. strncmp(str, prefix, strlen(prefix)) == 0;
  31. }
  32. static inline int check_postfix(const char *str, const char *postfix)
  33. {
  34. return strlen(str) > strlen(postfix) &&
  35. strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
  36. }
  37. static int dump_channels(const char *dev_dir_name)
  38. {
  39. DIR *dp;
  40. const struct dirent *ent;
  41. dp = opendir(dev_dir_name);
  42. if (!dp)
  43. return -errno;
  44. while (ent = readdir(dp), ent)
  45. if (check_prefix(ent->d_name, "in_") &&
  46. check_postfix(ent->d_name, "_raw"))
  47. printf(" %-10s\n", ent->d_name);
  48. return (closedir(dp) == -1) ? -errno : 0;
  49. }
  50. static int dump_one_device(const char *dev_dir_name)
  51. {
  52. char name[IIO_MAX_NAME_LENGTH];
  53. int dev_idx;
  54. int ret;
  55. ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i",
  56. &dev_idx);
  57. if (ret != 1)
  58. return -EINVAL;
  59. ret = read_sysfs_string("name", dev_dir_name, name);
  60. if (ret < 0)
  61. return ret;
  62. printf("Device %03d: %s\n", dev_idx, name);
  63. if (verblevel >= VERBLEVEL_SENSORS)
  64. return dump_channels(dev_dir_name);
  65. return 0;
  66. }
  67. static int dump_one_trigger(const char *dev_dir_name)
  68. {
  69. char name[IIO_MAX_NAME_LENGTH];
  70. int dev_idx;
  71. int ret;
  72. ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
  73. "%i", &dev_idx);
  74. if (ret != 1)
  75. return -EINVAL;
  76. ret = read_sysfs_string("name", dev_dir_name, name);
  77. if (ret < 0)
  78. return ret;
  79. printf("Trigger %03d: %s\n", dev_idx, name);
  80. return 0;
  81. }
  82. static int dump_devices(void)
  83. {
  84. const struct dirent *ent;
  85. int ret;
  86. DIR *dp;
  87. dp = opendir(iio_dir);
  88. if (!dp) {
  89. fprintf(stderr, "No industrial I/O devices available\n");
  90. return -ENODEV;
  91. }
  92. while (ent = readdir(dp), ent) {
  93. if (check_prefix(ent->d_name, type_device)) {
  94. char *dev_dir_name;
  95. if (asprintf(&dev_dir_name, "%s%s", iio_dir,
  96. ent->d_name) < 0) {
  97. ret = -ENOMEM;
  98. goto error_close_dir;
  99. }
  100. ret = dump_one_device(dev_dir_name);
  101. if (ret) {
  102. free(dev_dir_name);
  103. goto error_close_dir;
  104. }
  105. free(dev_dir_name);
  106. if (verblevel >= VERBLEVEL_SENSORS)
  107. printf("\n");
  108. }
  109. }
  110. rewinddir(dp);
  111. while (ent = readdir(dp), ent) {
  112. if (check_prefix(ent->d_name, type_trigger)) {
  113. char *dev_dir_name;
  114. if (asprintf(&dev_dir_name, "%s%s", iio_dir,
  115. ent->d_name) < 0) {
  116. ret = -ENOMEM;
  117. goto error_close_dir;
  118. }
  119. ret = dump_one_trigger(dev_dir_name);
  120. if (ret) {
  121. free(dev_dir_name);
  122. goto error_close_dir;
  123. }
  124. free(dev_dir_name);
  125. }
  126. }
  127. return (closedir(dp) == -1) ? -errno : 0;
  128. error_close_dir:
  129. if (closedir(dp) == -1)
  130. perror("dump_devices(): Failed to close directory");
  131. return ret;
  132. }
  133. int main(int argc, char **argv)
  134. {
  135. int c, err = 0;
  136. while ((c = getopt(argc, argv, "v")) != EOF) {
  137. switch (c) {
  138. case 'v':
  139. verblevel++;
  140. break;
  141. case '?':
  142. default:
  143. err++;
  144. break;
  145. }
  146. }
  147. if (err || argc > optind) {
  148. fprintf(stderr, "Usage: lsiio [options]...\n"
  149. "List industrial I/O devices\n"
  150. " -v Increase verbosity (may be given multiple times)\n");
  151. exit(1);
  152. }
  153. return dump_devices();
  154. }