Esempio n. 1
0
int main( int argc, char **argv )
{
    int             show_usage;
    uint16_t        knxaddress = 0;
    uint16_t        eis;
    int             enmx_version;
    int             quiet = 0;
    int             c;
    int             len;
    unsigned char   value_char;
    int             value_integer;
    uint32_t        value_int32;
    float           value_float;
    char            *string = NULL;
    unsigned char   *data;
    unsigned char   *p_val = NULL;
    char            *user = NULL;
    char            pwd[255];
    char            *server = NULL;
    
    // get parameters
    show_usage = FALSE;
    opterr = 0;
    while( ( c = getopt( argc, argv, "qs:u:" )) != -1 ) {
        switch( c ) {
            case 's':
                server = strdup( optarg );
                break;
            case 'u':
                user = strdup( optarg );
                break;
            case 'q':
                quiet = 1;
                break;
            default:
                fprintf( stderr, "Invalid option: %c\n", c );
                Usage( argv[0] );
                exit( -1 );
        }
    }
    if( optind + 3 != argc ) {
        show_usage = TRUE;
    } else {
        // knx group address
        if( strchr( argv[optind +0], '/' ) == NULL ) {
            if( sscanf( argv[optind +0], "%d", &value_integer ) != 1 ) {
                show_usage = TRUE;
            } else {
                knxaddress = value_integer & 0xffff;
            }
        } else {
            if( (knxaddress = enmx_getaddress( argv[optind +0] )) == 0xffff ) {
                show_usage = TRUE;
            }
        }
        // eis type
        if( sscanf( argv[optind +1], "%d", &value_integer ) != 1 || value_integer < 1 || value_integer > 15 ) {
            show_usage = TRUE;
        } else {
            eis = value_integer & 0x0f;
	    //Modification DOMOVISION, Ok c'est degeux mais pour le moment ca fait l'affaire
	    if (eis == 5){
	     eis=6;
	    }
            switch( eis ) {
                case 1:
                case 2:
                case 3:
                case 4:
		//case 5:
                case 6:
                case 7:
                case 8:
                case 10:
                case 14:
                    if( sscanf( argv[optind +2], "%d", &value_integer ) != 1 ) {
                        show_usage = TRUE;
                    }
                    p_val = (unsigned char *)&value_integer;
                    break;
                case 11:
                    if( sscanf( argv[optind +2], "%d", &value_int32 ) != 1 ) {
                        show_usage = TRUE;
                    }
                    p_val = (unsigned char *)&value_int32;
                    break;
                case 5:
                case 9:
                    if( sscanf( argv[optind +2], "%f", &value_float ) != 1 ) {
                        show_usage = TRUE;
                    }
                    p_val = (unsigned char *)&value_float;
                    break;
                case 13:
                    if( sscanf( argv[optind +2], "%c", &value_char ) != 1 ) {
                        show_usage = TRUE;
                    }
                    p_val = (unsigned char *)&value_char;
                    break;
                case 15:
                    string = argv[optind +2];
                    p_val = (unsigned char *)string;
                    break;
                case 12:
                    break;
            }
        }
    }
    
    if( show_usage == TRUE ) {
        Usage( basename( argv[0] ));
        exit( -1 );
    }
    
    // write command to bus
    if( (enmx_version = enmx_init()) != ENMX_VERSION_API ) {
        fprintf( stderr, "Incompatible eibnetmux API version (%d, expected %d)\n", enmx_version, ENMX_VERSION_API );
        exit( -8 );
    }

    if( (data = malloc( enmx_EISsizeKNX[eis] )) == NULL ) {
        fprintf( stderr, "Out of memory\n" );
        exit( -4 );
    }
    if( enmx_value2eis( eis, (void *)p_val, data ) != 0 ) {
        fprintf( stderr, "Error in value conversion\n" );
        exit( -5 );
    }
    
    sock_con = enmx_open( server, "eibcommand" );
    if( sock_con < 0 ) {
        fprintf( stderr, "Connect to eibnetmux failed: %s\n", enmx_errormessage( sock_con ));
        exit( -2 );
    }
    if( quiet == 0 ) printf( "Connecting to eibnetmux server on '%s'\n", enmx_gethost( sock_con ));
    
    // authenticate
    if( user != NULL ) {
        if( getpassword( pwd ) != 0 ) {
            fprintf( stderr, "Error reading password - cannot continue\n" );
            exit( -6 );
        }
        if( enmx_auth( sock_con, user, pwd ) != 0 ) {
            fprintf( stderr, "Authentication failure\n" );
            exit( -3 );
        }
    }
    if( quiet == 0 ) printf( "Connection established\n" );
    
    len = (eis != 15) ? enmx_EISsizeKNX[eis] : strlen( string );
    if( enmx_write( sock_con, knxaddress, len, data ) != 0 ) {
        fprintf( stderr, "Unable to send command: %s\n", enmx_errormessage( sock_con ));
        exit( -7 );
    }
    
    if( quiet == 0 ) printf( "Request sent to %s\n", enmx_getgroup( knxaddress ));
    
    enmx_close( sock_con );
    
    if( quiet == 0 ) printf( "Connection closed\n" );
    
    exit( 0 );
}
int trace( int argc, char **argv )
{
    uint16_t                value_size;
    struct timeval          tv;
    struct tm               *ltime;
    uint16_t                buflen;
    unsigned char           *buf;
    CEMIFRAME               *cemiframe;
    int                     enmx_version;
    int                     c;
    int                     quiet = 0;
    int                     total = -1;
    int                     count = 0;
    int                     spaces = 1;
    char                    *user = NULL;
    char                    pwd[255];
    char                    *target;
    char                    *eis_types;
    int                     type;
    int                     seconds;
    unsigned char           value[20];
    uint32_t                *p_int = 0;
    double                  *p_real;

    opterr = 0;
    while( ( c = getopt( argc, argv, "c:u:q" )) != -1 ) {
        switch( c ) {
        case 'c':
            total = atoi( optarg );
            break;
        case 'u':
            user = strdup( optarg );
            break;
        case 'q':
            quiet = 1;
            break;
        default:
            fprintf( stderr, "Invalid option: %c\n", c );
            Usage( argv[0] );
            exit( -1 );
        }
    }
    if( optind == argc ) {
        target = NULL;
    } else if( optind + 1 == argc ) {
        target = argv[optind];
    } else {
        Usage( argv[0] );
        exit( -1 );
    }

    // catch signals for shutdown
    signal( SIGINT, Shutdown );
    signal( SIGTERM, Shutdown );

    // request monitoring connection
    enmx_version = enmx_init();
    sock_con = enmx_open( target, "eibtrace" );
    if( sock_con < 0 ) {
        fprintf( stderr, "Connect to eibnetmux failed (%d): %s\n", sock_con, enmx_errormessage( sock_con ));
        exit( -2 );
    }

    // authenticate
    if( user != NULL ) {
        if( getpassword( pwd ) != 0 ) {
            fprintf( stderr, "Error reading password - cannot continue\n" );
            exit( -6 );
        }
        if( enmx_auth( sock_con, user, pwd ) != 0 ) {
            fprintf( stderr, "Authentication failure\n" );
            exit( -3 );
        }
    }
    if( quiet == 0 ) {
        printf( "Connection to eibnetmux '%s' established\n", enmx_gethost( sock_con ));
    }

    buf = malloc( 10 );
    buflen = 10;
    if( total != -1 ) {
        spaces = floor( log10( total )) +1;
    }
    while( total == -1 || count < total ) {
        buf = enmx_monitor( sock_con, 0xffff, buf, &buflen, &value_size );
        if( buf == NULL ) {
            switch( enmx_geterror( sock_con )) {
            case ENMX_E_COMMUNICATION:
            case ENMX_E_NO_CONNECTION:
            case ENMX_E_WRONG_USAGE:
            case ENMX_E_NO_MEMORY:
                fprintf( stderr, "Error on write: %s\n", enmx_errormessage( sock_con ));
                enmx_close( sock_con );
                exit( -4 );
                break;
            case ENMX_E_INTERNAL:
                fprintf( stderr, "Bad status returned\n" );
                break;
            case ENMX_E_SERVER_ABORTED:
                fprintf( stderr, "EOF reached: %s\n", enmx_errormessage( sock_con ));
                enmx_close( sock_con );
                exit( -4 );
                break;
            case ENMX_E_TIMEOUT:
                fprintf( stderr, "No value received\n" );
                break;
            }
        } else {
            count++;
            cemiframe = (CEMIFRAME *) buf;
            gettimeofday( &tv, NULL );
            ltime = localtime( &tv.tv_sec );
            if( total != -1 ) {
                printf( "%*d: ", spaces, count );
            }
            printf( "%04d/%02d/%02d %02d:%02d:%02d:%03d - ",
                    ltime->tm_year + 1900, ltime->tm_mon +1, ltime->tm_mday,
                    ltime->tm_hour, ltime->tm_min, ltime->tm_sec, (uint32_t)tv.tv_usec / 1000 );
            printf( "%8s  ", knx_physical( cemiframe->saddr ));
            if( cemiframe->apci & A_WRITE_VALUE_REQ ) {
                printf( "W " );
            } else if( cemiframe->apci & A_RESPONSE_VALUE_REQ ) {
                printf( "A " );
            } else {
                printf( "R " );
            }
            printf( "%8s", (cemiframe->ntwrk & EIB_DAF_GROUP) ? knx_group( cemiframe->daddr ) : knx_physical( cemiframe->daddr ));
            if( cemiframe->apci & (A_WRITE_VALUE_REQ | A_RESPONSE_VALUE_REQ) ) {
                printf( " : " );
                p_int = (uint32_t *)value;
                p_real = (double *)value;
                switch( cemiframe->length ) {
                case 1:     // EIS 1, 2, 7, 8
                    type = enmx_frame2value( 1, cemiframe, value );
                    printf( "%s | ", (*p_int == 0) ? "off" : "on" );
                    type = enmx_frame2value( 2, cemiframe, value );
                    printf( "%d | ", *p_int );
                    type = enmx_frame2value( 7, cemiframe, value );
                    printf( "%d | ", *p_int );
                    type = enmx_frame2value( 8, cemiframe, value );
                    printf( "%d", *p_int );
                    eis_types = "1, 2, 7, 8";
                    break;
                case 2:     // 6, 13, 14
                    type = enmx_frame2value( 6, cemiframe, value );
                    printf( "%d%% | %d", *p_int * 100 / 255, *p_int );
                    type = enmx_frame2value( 13, cemiframe, value );
                    if( *p_int >=  0x20 && *p_int < 0x7f ) {
                        printf( " | %c", *p_int );
                        eis_types = "6, 14, 13";
                    } else {
                        eis_types = "6, 14";
                    }
                    break;
                case 3:     // 5, 10
                    type = enmx_frame2value( 5, cemiframe, value );
                    printf( "%.2f | ", *p_real );
                    type = enmx_frame2value( 10, cemiframe, value );
                    printf( "%d", *p_int );
                    eis_types = "5, 10";
                    break;
                case 4:     // 3, 4
                    type = enmx_frame2value( 3, cemiframe, value );
                    seconds = *p_int;
                    ltime->tm_hour = seconds / 3600;
                    seconds %= 3600;
                    ltime->tm_min = seconds / 60;
                    seconds %= 60;
                    ltime->tm_sec = seconds;
                    printf( "%02d:%02d:%02d | ", ltime->tm_hour, ltime->tm_min, ltime->tm_sec );
                    type = enmx_frame2value( 4, cemiframe, value );
                    ltime = localtime( (time_t *)p_int );
                    printf( "%04d/%02d/%02d", ltime->tm_year + 1900, ltime->tm_mon +1, ltime->tm_mday );
                    eis_types = "3, 4";
                    break;
                case 5:     // 9, 11, 12
                    type = enmx_frame2value( 11, cemiframe, value );
                    printf( "%d | ", *p_int );
                    type = enmx_frame2value( 9, cemiframe, value );
                    printf( "%.2f", *p_real );
                    type = enmx_frame2value( 12, cemiframe, value );
                    // printf( "12: <->" );
                    eis_types = "9, 11, 12";
                    break;
                default:    // 15
                    // printf( "%s", string );
                    eis_types = "15";
                    break;
                }
                if( cemiframe->length == 1 ) {
                    printf( " (%s", hexdump( &cemiframe->apci, 1, 1 ));
                } else {
                    printf( " (%s", hexdump( (unsigned char *)(&cemiframe->apci) +1, cemiframe->length -1, 1 ));
                }
                printf( " - eis types: %s)", eis_types );
            }
            printf( "\n" );
        }
    }
    return( 0 );
}