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