Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Industrial I/O utilities - lsiio.c
0004  *
0005  * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
0006  */
0007 
0008 #include <string.h>
0009 #include <dirent.h>
0010 #include <stdio.h>
0011 #include <errno.h>
0012 #include <stdint.h>
0013 #include <stdlib.h>
0014 #include <unistd.h>
0015 #include <sys/types.h>
0016 #include <sys/stat.h>
0017 #include <sys/dir.h>
0018 #include "iio_utils.h"
0019 
0020 static enum verbosity {
0021     VERBLEVEL_DEFAULT,  /* 0 gives lspci behaviour */
0022     VERBLEVEL_SENSORS,  /* 1 lists sensors */
0023 } verblevel = VERBLEVEL_DEFAULT;
0024 
0025 const char *type_device = "iio:device";
0026 const char *type_trigger = "trigger";
0027 
0028 static inline int check_prefix(const char *str, const char *prefix)
0029 {
0030     return strlen(str) > strlen(prefix) &&
0031            strncmp(str, prefix, strlen(prefix)) == 0;
0032 }
0033 
0034 static inline int check_postfix(const char *str, const char *postfix)
0035 {
0036     return strlen(str) > strlen(postfix) &&
0037            strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
0038 }
0039 
0040 static int dump_channels(const char *dev_dir_name)
0041 {
0042     DIR *dp;
0043     const struct dirent *ent;
0044 
0045     dp = opendir(dev_dir_name);
0046     if (!dp)
0047         return -errno;
0048 
0049     while (ent = readdir(dp), ent)
0050         if (check_prefix(ent->d_name, "in_") &&
0051            (check_postfix(ent->d_name, "_raw") ||
0052             check_postfix(ent->d_name, "_input")))
0053             printf("   %-10s\n", ent->d_name);
0054 
0055     return (closedir(dp) == -1) ? -errno : 0;
0056 }
0057 
0058 static int dump_one_device(const char *dev_dir_name)
0059 {
0060     char name[IIO_MAX_NAME_LENGTH];
0061     int dev_idx;
0062     int ret;
0063 
0064     ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i",
0065              &dev_idx);
0066     if (ret != 1)
0067         return -EINVAL;
0068 
0069     ret = read_sysfs_string("name", dev_dir_name, name);
0070     if (ret < 0)
0071         return ret;
0072 
0073     printf("Device %03d: %s\n", dev_idx, name);
0074 
0075     if (verblevel >= VERBLEVEL_SENSORS)
0076         return dump_channels(dev_dir_name);
0077 
0078     return 0;
0079 }
0080 
0081 static int dump_one_trigger(const char *dev_dir_name)
0082 {
0083     char name[IIO_MAX_NAME_LENGTH];
0084     int dev_idx;
0085     int ret;
0086 
0087     ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
0088              "%i", &dev_idx);
0089     if (ret != 1)
0090         return -EINVAL;
0091 
0092     ret = read_sysfs_string("name", dev_dir_name, name);
0093     if (ret < 0)
0094         return ret;
0095 
0096     printf("Trigger %03d: %s\n", dev_idx, name);
0097 
0098     return 0;
0099 }
0100 
0101 static int dump_devices(void)
0102 {
0103     const struct dirent *ent;
0104     int ret;
0105     DIR *dp;
0106 
0107     dp = opendir(iio_dir);
0108     if (!dp) {
0109         fprintf(stderr, "No industrial I/O devices available\n");
0110         return -ENODEV;
0111     }
0112 
0113     while (ent = readdir(dp), ent) {
0114         if (check_prefix(ent->d_name, type_device)) {
0115             char *dev_dir_name;
0116 
0117             if (asprintf(&dev_dir_name, "%s%s", iio_dir,
0118                      ent->d_name) < 0) {
0119                 ret = -ENOMEM;
0120                 goto error_close_dir;
0121             }
0122 
0123             ret = dump_one_device(dev_dir_name);
0124             if (ret) {
0125                 free(dev_dir_name);
0126                 goto error_close_dir;
0127             }
0128 
0129             free(dev_dir_name);
0130             if (verblevel >= VERBLEVEL_SENSORS)
0131                 printf("\n");
0132         }
0133     }
0134     rewinddir(dp);
0135     while (ent = readdir(dp), ent) {
0136         if (check_prefix(ent->d_name, type_trigger)) {
0137             char *dev_dir_name;
0138 
0139             if (asprintf(&dev_dir_name, "%s%s", iio_dir,
0140                      ent->d_name) < 0) {
0141                 ret = -ENOMEM;
0142                 goto error_close_dir;
0143             }
0144 
0145             ret = dump_one_trigger(dev_dir_name);
0146             if (ret) {
0147                 free(dev_dir_name);
0148                 goto error_close_dir;
0149             }
0150 
0151             free(dev_dir_name);
0152         }
0153     }
0154 
0155     return (closedir(dp) == -1) ? -errno : 0;
0156 
0157 error_close_dir:
0158     if (closedir(dp) == -1)
0159         perror("dump_devices(): Failed to close directory");
0160 
0161     return ret;
0162 }
0163 
0164 int main(int argc, char **argv)
0165 {
0166     int c, err = 0;
0167 
0168     while ((c = getopt(argc, argv, "v")) != EOF) {
0169         switch (c) {
0170         case 'v':
0171             verblevel++;
0172             break;
0173 
0174         case '?':
0175         default:
0176             err++;
0177             break;
0178         }
0179     }
0180     if (err || argc > optind) {
0181         fprintf(stderr, "Usage: lsiio [options]...\n"
0182             "List industrial I/O devices\n"
0183             "  -v  Increase verbosity (may be given multiple times)\n");
0184         exit(1);
0185     }
0186 
0187     return dump_devices();
0188 }