2014-05-02 16:23:00 +04:00
/*
* Industrial I / O utilities - lsiio . c
*
* Copyright ( c ) 2010 Manuel Stahl < manuel . stahl @ iis . fraunhofer . de >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation .
*/
# include <string.h>
# include <dirent.h>
# include <stdio.h>
# include <errno.h>
# include <stdint.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/dir.h>
# include "iio_utils.h"
static enum verbosity {
VERBLEVEL_DEFAULT , /* 0 gives lspci behaviour */
VERBLEVEL_SENSORS , /* 1 lists sensors */
} verblevel = VERBLEVEL_DEFAULT ;
const char * type_device = " iio:device " ;
const char * type_trigger = " trigger " ;
static inline int check_prefix ( const char * str , const char * prefix )
{
return strlen ( str ) > strlen ( prefix ) & &
2015-06-10 22:51:20 +03:00
strncmp ( str , prefix , strlen ( prefix ) ) = = 0 ;
2014-05-02 16:23:00 +04:00
}
static inline int check_postfix ( const char * str , const char * postfix )
{
return strlen ( str ) > strlen ( postfix ) & &
2015-06-10 22:51:20 +03:00
strcmp ( str + strlen ( str ) - strlen ( postfix ) , postfix ) = = 0 ;
2014-05-02 16:23:00 +04:00
}
static int dump_channels ( const char * dev_dir_name )
{
DIR * dp ;
const struct dirent * ent ;
2014-10-06 15:33:31 +04:00
2014-05-02 16:23:00 +04:00
dp = opendir ( dev_dir_name ) ;
2015-07-13 16:15:56 +03:00
if ( ! dp )
2014-05-02 16:23:00 +04:00
return - errno ;
2015-06-10 22:51:20 +03:00
2015-07-13 16:15:56 +03:00
while ( ent = readdir ( dp ) , ent )
2014-05-02 16:23:00 +04:00
if ( check_prefix ( ent - > d_name , " in_ " ) & &
2015-06-10 22:51:20 +03:00
check_postfix ( ent - > d_name , " _raw " ) )
2014-05-02 16:23:00 +04:00
printf ( " %-10s \n " , ent - > d_name ) ;
2015-05-31 15:39:47 +03:00
return ( closedir ( dp ) = = - 1 ) ? - errno : 0 ;
2014-05-02 16:23:00 +04:00
}
static int dump_one_device ( const char * dev_dir_name )
{
char name [ IIO_MAX_NAME_LENGTH ] ;
int dev_idx ;
2015-06-10 22:51:21 +03:00
int ret ;
2014-05-02 16:23:00 +04:00
2015-06-10 22:51:21 +03:00
ret = sscanf ( dev_dir_name + strlen ( iio_dir ) + strlen ( type_device ) , " %i " ,
& dev_idx ) ;
if ( ret ! = 1 )
2014-10-06 15:34:43 +04:00
return - EINVAL ;
2015-06-10 22:51:20 +03:00
2015-06-10 22:51:21 +03:00
ret = read_sysfs_string ( " name " , dev_dir_name , name ) ;
2015-08-04 17:21:49 +03:00
if ( ret < 0 )
2015-06-10 22:51:21 +03:00
return ret ;
2015-05-31 15:40:15 +03:00
2014-05-02 16:23:00 +04:00
printf ( " Device %03d: %s \n " , dev_idx , name ) ;
2014-10-06 15:34:10 +04:00
if ( verblevel > = VERBLEVEL_SENSORS )
return dump_channels ( dev_dir_name ) ;
2015-06-10 22:51:20 +03:00
2014-05-02 16:23:00 +04:00
return 0 ;
}
static int dump_one_trigger ( const char * dev_dir_name )
{
char name [ IIO_MAX_NAME_LENGTH ] ;
int dev_idx ;
2015-06-10 22:51:21 +03:00
int ret ;
2014-05-02 16:23:00 +04:00
2015-06-10 22:51:21 +03:00
ret = sscanf ( dev_dir_name + strlen ( iio_dir ) + strlen ( type_trigger ) ,
" %i " , & dev_idx ) ;
if ( ret ! = 1 )
2014-10-06 15:34:43 +04:00
return - EINVAL ;
2015-06-10 22:51:20 +03:00
2015-06-10 22:51:21 +03:00
ret = read_sysfs_string ( " name " , dev_dir_name , name ) ;
2015-08-04 17:21:49 +03:00
if ( ret < 0 )
2015-06-10 22:51:21 +03:00
return ret ;
2015-05-31 15:40:15 +03:00
2014-05-02 16:23:00 +04:00
printf ( " Trigger %03d: %s \n " , dev_idx , name ) ;
2015-06-10 22:51:20 +03:00
2014-05-02 16:23:00 +04:00
return 0 ;
}
2015-05-31 15:40:15 +03:00
static int dump_devices ( void )
2014-05-02 16:23:00 +04:00
{
const struct dirent * ent ;
2015-05-31 15:40:15 +03:00
int ret ;
2014-05-02 16:23:00 +04:00
DIR * dp ;
dp = opendir ( iio_dir ) ;
2015-07-13 16:15:56 +03:00
if ( ! dp ) {
2015-07-17 18:43:42 +03:00
fprintf ( stderr , " No industrial I/O devices available \n " ) ;
2015-05-31 15:40:15 +03:00
return - ENODEV ;
2014-05-02 16:23:00 +04:00
}
2015-07-13 16:15:56 +03:00
while ( ent = readdir ( dp ) , ent ) {
2014-05-02 16:23:00 +04:00
if ( check_prefix ( ent - > d_name , type_device ) ) {
char * dev_dir_name ;
2014-10-06 15:33:31 +04:00
2015-05-31 15:40:02 +03:00
if ( asprintf ( & dev_dir_name , " %s%s " , iio_dir ,
ent - > d_name ) < 0 ) {
2015-05-31 15:40:15 +03:00
ret = - ENOMEM ;
goto error_close_dir ;
}
ret = dump_one_device ( dev_dir_name ) ;
if ( ret ) {
free ( dev_dir_name ) ;
2015-05-31 15:40:02 +03:00
goto error_close_dir ;
}
2014-05-02 16:23:00 +04:00
free ( dev_dir_name ) ;
if ( verblevel > = VERBLEVEL_SENSORS )
printf ( " \n " ) ;
}
}
rewinddir ( dp ) ;
2015-07-13 16:15:56 +03:00
while ( ent = readdir ( dp ) , ent ) {
2014-05-02 16:23:00 +04:00
if ( check_prefix ( ent - > d_name , type_trigger ) ) {
char * dev_dir_name ;
2014-10-06 15:33:31 +04:00
2015-05-31 15:40:02 +03:00
if ( asprintf ( & dev_dir_name , " %s%s " , iio_dir ,
ent - > d_name ) < 0 ) {
2015-05-31 15:40:15 +03:00
ret = - ENOMEM ;
goto error_close_dir ;
}
ret = dump_one_trigger ( dev_dir_name ) ;
if ( ret ) {
free ( dev_dir_name ) ;
2015-05-31 15:40:02 +03:00
goto error_close_dir ;
}
2014-05-02 16:23:00 +04:00
free ( dev_dir_name ) ;
}
}
2015-06-10 22:51:20 +03:00
2015-05-31 15:40:15 +03:00
return ( closedir ( dp ) = = - 1 ) ? - errno : 0 ;
2015-05-31 15:40:02 +03:00
error_close_dir :
2015-05-31 15:40:15 +03:00
if ( closedir ( dp ) = = - 1 )
perror ( " dump_devices(): Failed to close directory " ) ;
return ret ;
2014-05-02 16:23:00 +04:00
}
int main ( int argc , char * * argv )
{
int c , err = 0 ;
2015-05-31 15:40:22 +03:00
while ( ( c = getopt ( argc , argv , " v " ) ) ! = EOF ) {
2014-05-02 16:23:00 +04:00
switch ( c ) {
case ' v ' :
verblevel + + ;
break ;
case ' ? ' :
default :
err + + ;
break ;
}
}
if ( err | | argc > optind ) {
fprintf ( stderr , " Usage: lsiio [options]... \n "
" List industrial I/O devices \n "
2015-05-31 15:40:22 +03:00
" -v Increase verbosity (may be given multiple times) \n " ) ;
2014-05-02 16:23:00 +04:00
exit ( 1 ) ;
}
2015-05-31 15:40:15 +03:00
return dump_devices ( ) ;
2014-05-02 16:23:00 +04:00
}