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