lsiio.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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 == NULL)
  43. return -errno;
  44. while (ent = readdir(dp), ent != NULL)
  45. if (check_prefix(ent->d_name, "in_") &&
  46. check_postfix(ent->d_name, "_raw")) {
  47. printf(" %-10s\n", ent->d_name);
  48. }
  49. return (closedir(dp) == -1) ? -errno : 0;
  50. }
  51. static int dump_one_device(const char *dev_dir_name)
  52. {
  53. char name[IIO_MAX_NAME_LENGTH];
  54. int dev_idx;
  55. int retval;
  56. retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device),
  57. "%i", &dev_idx);
  58. if (retval != 1)
  59. return -EINVAL;
  60. retval = read_sysfs_string("name", dev_dir_name, name);
  61. if (retval)
  62. return retval;
  63. printf("Device %03d: %s\n", dev_idx, name);
  64. if (verblevel >= VERBLEVEL_SENSORS)
  65. return dump_channels(dev_dir_name);
  66. return 0;
  67. }
  68. static int dump_one_trigger(const char *dev_dir_name)
  69. {
  70. char name[IIO_MAX_NAME_LENGTH];
  71. int dev_idx;
  72. int retval;
  73. retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
  74. "%i", &dev_idx);
  75. if (retval != 1)
  76. return -EINVAL;
  77. retval = read_sysfs_string("name", dev_dir_name, name);
  78. if (retval)
  79. return retval;
  80. printf("Trigger %03d: %s\n", dev_idx, name);
  81. return 0;
  82. }
  83. static int dump_devices(void)
  84. {
  85. const struct dirent *ent;
  86. int ret;
  87. DIR *dp;
  88. dp = opendir(iio_dir);
  89. if (dp == NULL) {
  90. printf("No industrial I/O devices available\n");
  91. return -ENODEV;
  92. }
  93. while (ent = readdir(dp), ent != NULL) {
  94. if (check_prefix(ent->d_name, type_device)) {
  95. char *dev_dir_name;
  96. if (asprintf(&dev_dir_name, "%s%s", iio_dir,
  97. ent->d_name) < 0) {
  98. ret = -ENOMEM;
  99. goto error_close_dir;
  100. }
  101. ret = dump_one_device(dev_dir_name);
  102. if (ret) {
  103. free(dev_dir_name);
  104. goto error_close_dir;
  105. }
  106. free(dev_dir_name);
  107. if (verblevel >= VERBLEVEL_SENSORS)
  108. printf("\n");
  109. }
  110. }
  111. rewinddir(dp);
  112. while (ent = readdir(dp), ent != NULL) {
  113. if (check_prefix(ent->d_name, type_trigger)) {
  114. char *dev_dir_name;
  115. if (asprintf(&dev_dir_name, "%s%s", iio_dir,
  116. ent->d_name) < 0) {
  117. ret = -ENOMEM;
  118. goto error_close_dir;
  119. }
  120. ret = dump_one_trigger(dev_dir_name);
  121. if (ret) {
  122. free(dev_dir_name);
  123. goto error_close_dir;
  124. }
  125. free(dev_dir_name);
  126. }
  127. }
  128. return (closedir(dp) == -1) ? -errno : 0;
  129. error_close_dir:
  130. if (closedir(dp) == -1)
  131. perror("dump_devices(): Failed to close directory");
  132. return ret;
  133. }
  134. int main(int argc, char **argv)
  135. {
  136. int c, err = 0;
  137. while ((c = getopt(argc, argv, "v")) != EOF) {
  138. switch (c) {
  139. case 'v':
  140. verblevel++;
  141. break;
  142. case '?':
  143. default:
  144. err++;
  145. break;
  146. }
  147. }
  148. if (err || argc > optind) {
  149. fprintf(stderr, "Usage: lsiio [options]...\n"
  150. "List industrial I/O devices\n"
  151. " -v Increase verbosity (may be given multiple times)\n");
  152. exit(1);
  153. }
  154. return dump_devices();
  155. }