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 11 #include <string.h> 12 #include <dirent.h> 13 #include <stdio.h> 14 #include <errno.h> 15 #include <stdint.h> 16 #include <stdlib.h> 17 #include <unistd.h> 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <sys/dir.h> 21 #include "iio_utils.h" 22 23 24 static enum verbosity { 25 VERBLEVEL_DEFAULT, /* 0 gives lspci behaviour */ 26 VERBLEVEL_SENSORS, /* 1 lists sensors */ 27 } verblevel = VERBLEVEL_DEFAULT; 28 29 const char *type_device = "iio:device"; 30 const char *type_trigger = "trigger"; 31 32 33 static inline int check_prefix(const char *str, const char *prefix) 34 { 35 return strlen(str) > strlen(prefix) && 36 strncmp(str, prefix, strlen(prefix)) == 0; 37 } 38 39 static inline int check_postfix(const char *str, const char *postfix) 40 { 41 return strlen(str) > strlen(postfix) && 42 strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; 43 } 44 45 static int dump_channels(const char *dev_dir_name) 46 { 47 DIR *dp; 48 const struct dirent *ent; 49 50 dp = opendir(dev_dir_name); 51 if (dp == NULL) 52 return -errno; 53 while (ent = readdir(dp), ent != NULL) 54 if (check_prefix(ent->d_name, "in_") && 55 check_postfix(ent->d_name, "_raw")) { 56 printf(" %-10s\n", ent->d_name); 57 } 58 59 return (closedir(dp) == -1) ? -errno : 0; 60 } 61 62 static int dump_one_device(const char *dev_dir_name) 63 { 64 char name[IIO_MAX_NAME_LENGTH]; 65 int dev_idx; 66 int retval; 67 68 retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), 69 "%i", &dev_idx); 70 if (retval != 1) 71 return -EINVAL; 72 retval = read_sysfs_string("name", dev_dir_name, name); 73 if (retval) 74 return retval; 75 76 printf("Device %03d: %s\n", dev_idx, name); 77 78 if (verblevel >= VERBLEVEL_SENSORS) 79 return dump_channels(dev_dir_name); 80 return 0; 81 } 82 83 static int dump_one_trigger(const char *dev_dir_name) 84 { 85 char name[IIO_MAX_NAME_LENGTH]; 86 int dev_idx; 87 int retval; 88 89 retval = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger), 90 "%i", &dev_idx); 91 if (retval != 1) 92 return -EINVAL; 93 retval = read_sysfs_string("name", dev_dir_name, name); 94 if (retval) 95 return retval; 96 97 printf("Trigger %03d: %s\n", dev_idx, name); 98 return 0; 99 } 100 101 static int dump_devices(void) 102 { 103 const struct dirent *ent; 104 int ret; 105 DIR *dp; 106 107 dp = opendir(iio_dir); 108 if (dp == NULL) { 109 printf("No industrial I/O devices available\n"); 110 return -ENODEV; 111 } 112 113 while (ent = readdir(dp), ent != NULL) { 114 if (check_prefix(ent->d_name, type_device)) { 115 char *dev_dir_name; 116 117 if (asprintf(&dev_dir_name, "%s%s", iio_dir, 118 ent->d_name) < 0) { 119 ret = -ENOMEM; 120 goto error_close_dir; 121 } 122 123 ret = dump_one_device(dev_dir_name); 124 if (ret) { 125 free(dev_dir_name); 126 goto error_close_dir; 127 } 128 129 free(dev_dir_name); 130 if (verblevel >= VERBLEVEL_SENSORS) 131 printf("\n"); 132 } 133 } 134 rewinddir(dp); 135 while (ent = readdir(dp), ent != NULL) { 136 if (check_prefix(ent->d_name, type_trigger)) { 137 char *dev_dir_name; 138 139 if (asprintf(&dev_dir_name, "%s%s", iio_dir, 140 ent->d_name) < 0) { 141 ret = -ENOMEM; 142 goto error_close_dir; 143 } 144 145 ret = dump_one_trigger(dev_dir_name); 146 if (ret) { 147 free(dev_dir_name); 148 goto error_close_dir; 149 } 150 151 free(dev_dir_name); 152 } 153 } 154 return (closedir(dp) == -1) ? -errno : 0; 155 156 error_close_dir: 157 if (closedir(dp) == -1) 158 perror("dump_devices(): Failed to close directory"); 159 160 return ret; 161 } 162 163 int main(int argc, char **argv) 164 { 165 int c, err = 0; 166 167 while ((c = getopt(argc, argv, "v")) != EOF) { 168 switch (c) { 169 case 'v': 170 verblevel++; 171 break; 172 173 case '?': 174 default: 175 err++; 176 break; 177 } 178 } 179 if (err || argc > optind) { 180 fprintf(stderr, "Usage: lsiio [options]...\n" 181 "List industrial I/O devices\n" 182 " -v Increase verbosity (may be given multiple times)\n"); 183 exit(1); 184 } 185 186 return dump_devices(); 187 } 188