Example #1
0
int main( int argc, char *argv[] )
{
  if ( access(ZM_CONFIG, R_OK) != 0 )
  {
    fprintf( stderr, "Can't open %s: %s\n", ZM_CONFIG, strerror(errno) );
    exit( -1 );
  }

  self = argv[0];

  srand( getpid() * time( 0 ) );

  static struct option long_options[] = {
    {"device", 2, 0, 'd'},
    {"monitor", 1, 0, 'm'},
    {"verbose", 0, 0, 'v'},
    {"image", 2, 0, 'i'},
    {"scale", 1, 0, 'S'},
    {"timestamp", 2, 0, 't'},
    {"state", 0, 0, 's'},
    {"brightness", 2, 0, 'B'},
    {"contrast", 2, 0, 'C'},
    {"hue", 2, 0, 'H'},
    {"contrast", 2, 0, 'O'},
    {"read_index", 0, 0, 'R'},
    {"write_index", 0, 0, 'W'},
    {"event", 0, 0, 'e'},
    {"fps", 0, 0, 'f'},
    {"zones", 2, 0, 'z'},
    {"alarm", 0, 0, 'a'},
    {"noalarm", 0, 0, 'n'},
    {"cancel", 0, 0, 'c'},
    {"reload", 0, 0, 'L'},
    {"enable", 0, 0, 'E'},
    {"disable", 0, 0, 'D'},
    {"suspend", 0, 0, 'u'},
    {"resume", 0, 0, 'r'},
    {"query", 0, 0, 'q'},
    {"username", 1, 0, 'U'},
    {"password", 1, 0, 'P'},
    {"auth", 1, 0, 'A'},
    {"version", 1, 0, 'V'},
    {"help", 0, 0, 'h'},
    {"list", 0, 0, 'l'},
    {0, 0, 0, 0}
  };

  const char *device = 0;
  int mon_id = 0;
  bool verbose = false;
  int function = ZMU_BOGUS;

  int image_idx = -1;
  int scale = -1;
  int brightness = -1;
  int contrast = -1;
  int hue = -1;
  int colour = -1;
  char *zoneString = 0;
  char *username = 0;
  char *password = 0;
  char *auth = 0;
#if ZM_HAS_V4L
#if ZM_HAS_V4L2
  int v4lVersion = 2;
#elif ZM_HAS_V4L1
  int v4lVersion = 1;
#endif // ZM_HAS_V4L2/1
#endif // ZM_HAS_V4L
  while (1)
  {
    int option_index = 0;

    int c = getopt_long (argc, argv, "d:m:vsEDLurwei::S:t::fz::ancqhlB::C::H::O::U:P:A:V:", long_options, &option_index);
    if (c == -1)
    {
      break;
    }

    switch (c)
    {
      case 'd':
        if ( optarg )
          device = optarg;
        break;
      case 'm':
        mon_id = atoi(optarg);
        break;
      case 'v':
        verbose = true;
        break;
      case 's':
        function |= ZMU_STATE;
        break;
      case 'i':
        function |= ZMU_IMAGE;
        if ( optarg )
          image_idx = atoi( optarg );
        break;
      case 'S':
        scale = atoi(optarg);
        break;
      case 't':
        function |= ZMU_TIME;
        if ( optarg )
          image_idx = atoi( optarg );
        break;
      case 'R':
        function |= ZMU_READ_IDX;
        break;
      case 'W':
        function |= ZMU_WRITE_IDX;
        break;
      case 'e':
        function |= ZMU_EVENT;
        break;
      case 'f':
        function |= ZMU_FPS;
        break;
      case 'z':
        function |= ZMU_ZONES;
        if ( optarg )
          zoneString = optarg;
        break;
      case 'a':
        function |= ZMU_ALARM;
        break;
      case 'n':
        function |= ZMU_NOALARM;
        break;
      case 'c':
        function |= ZMU_CANCEL;
        break;
      case 'L':
        function |= ZMU_RELOAD;
        break;
      case 'E':
        function |= ZMU_ENABLE;
        break;
      case 'D':
        function |= ZMU_DISABLE;
        break;
      case 'u':
        function |= ZMU_SUSPEND;
        break;
      case 'r':
        function |= ZMU_RESUME;
        break;
      case 'q':
        function |= ZMU_QUERY;
        break;
      case 'B':
        function |= ZMU_BRIGHTNESS;
        if ( optarg )
          brightness = atoi( optarg );
        break;
      case 'C':
        function |= ZMU_CONTRAST;
        if ( optarg )
          contrast = atoi( optarg );
        break;
      case 'H':
        function |= ZMU_HUE;
        if ( optarg )
          hue = atoi( optarg );
        break;
      case 'O':
        function |= ZMU_COLOUR;
        if ( optarg )
          colour = atoi( optarg );
        break;
      case 'U':
        username = optarg;
        break;
      case 'P':
        password = optarg;
        break;
      case 'A':
        auth = optarg;
        break;
#if ZM_HAS_V4L
      case 'V':
        v4lVersion = (atoi(optarg)==1)?1:2;
        break;
#endif // ZM_HAS_V4L
      case 'h':
        Usage( 0 );
        break;
      case 'l':
        function |= ZMU_LIST;
        break;
      case '?':
        Usage();
        break;
      default:
        //fprintf( stderr, "?? getopt returned character code 0%o ??\n", c );
        break;
    }
  }

  if (optind < argc)
  {
    fprintf( stderr, "Extraneous options, " );
    while (optind < argc)
      fprintf( stderr, "%s ", argv[optind++]);
    fprintf( stderr, "\n");
    Usage();
  }

  if ( device && !(function&ZMU_QUERY) )
  {
    fprintf( stderr, "Error, -d option cannot be used with this option\n" );
    Usage();
  }
  if ( scale != -1 && !(function&ZMU_IMAGE) )
  {
    fprintf( stderr, "Error, -S option cannot be used with this option\n" );
    Usage();
  }
  //printf( "Monitor %d, Function %d\n", mon_id, function );

  zmLoadConfig();

  logInit( "zmu" );

  zmSetDefaultTermHandler();
  zmSetDefaultDieHandler();

  User *user = 0;

  if ( config.opt_use_auth )
  {
    if ( strcmp( config.auth_relay, "none" ) == 0 )
    {
      if ( !username )
      {
        fprintf( stderr, "Error, username must be supplied\n" );
        exit( -1 );
      }

      if ( username )
      {
        user = zmLoadUser( username );
      }
    }
    else
    {
      if ( !(username && password) && !auth )
      {
        fprintf( stderr, "Error, username and password or auth string must be supplied\n" );
        exit( -1 );
      }

      //if ( strcmp( config.auth_relay, "hashed" ) == 0 )
      {
        if ( auth )
        {
          user = zmLoadAuthUser( auth, false );
        }
      }
      //else if ( strcmp( config.auth_relay, "plain" ) == 0 )
      {
        if ( username && password )
        {
          user = zmLoadUser( username, password );
        }
      }
    }
    if ( !user )
    {
      fprintf( stderr, "Error, unable to authenticate user\n" );
      exit( -1 );
    }
    ValidateAccess( user, mon_id, function );
  }
  

  if ( mon_id > 0 )
  {
    Monitor *monitor = Monitor::Load( mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY );
    if ( monitor )
    {
      if ( verbose )
      {
        printf( "Monitor %d(%s)\n", monitor->Id(), monitor->Name() );
      }
      if ( ! monitor->connect() ) {
        Error( "Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name() );
        exit( -1 );
      } 

      char separator = ' ';
      bool have_output = false;
      if ( function & ZMU_STATE )
      {
        Monitor::State state = monitor->GetState();
        if ( verbose )
          printf( "Current state: %s\n", state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle") );
        else
        {
          if ( have_output ) printf( "%c", separator );
          printf( "%d", state );
          have_output = true;
        }
      }
      if ( function & ZMU_TIME )
      {
        struct timeval timestamp = monitor->GetTimestamp( image_idx );
        if ( verbose )
        {
          char timestamp_str[64] = "None";
          if ( timestamp.tv_sec )
            strftime( timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S", localtime( &timestamp.tv_sec ) );
          if ( image_idx == -1 )
            printf( "Time of last image capture: %s.%02ld\n", timestamp_str, timestamp.tv_usec/10000 );
          else
            printf( "Time of image %d capture: %s.%02ld\n", image_idx, timestamp_str, timestamp.tv_usec/10000 );
        }
        else
        {
          if ( have_output ) printf( "%c", separator );
          printf( "%ld.%02ld", timestamp.tv_sec, timestamp.tv_usec/10000 );
          have_output = true;
        }
      }
      if ( function & ZMU_READ_IDX )
      {
        if ( verbose )
          printf( "Last read index: %d\n", monitor->GetLastReadIndex() );
        else
        {
          if ( have_output ) printf( "%c", separator );
          printf( "%d", monitor->GetLastReadIndex() );
          have_output = true;
        }
      }
      if ( function & ZMU_WRITE_IDX )
      {
        if ( verbose )
          printf( "Last write index: %d\n", monitor->GetLastWriteIndex() );
        else
        {
          if ( have_output ) printf( "%c", separator );
          printf( "%d", monitor->GetLastWriteIndex() );
          have_output = true;
        }
      }
      if ( function & ZMU_EVENT )
      {
        if ( verbose )
          printf( "Last event id: %d\n", monitor->GetLastEvent() );
        else
        {
          if ( have_output ) printf( "%c", separator );
          printf( "%d", monitor->GetLastEvent() );
          have_output = true;
        }
      }
      if ( function & ZMU_FPS )
      {
        if ( verbose )
          printf( "Current capture rate: %.2f frames per second\n", monitor->GetFPS() );
        else
        {
          if ( have_output ) printf( "%c", separator );
          printf( "%.2f", monitor->GetFPS() );
          have_output = true;
        }
      }
      if ( function & ZMU_IMAGE )
      {
        if ( verbose )
        {
          if ( image_idx == -1 )
            printf( "Dumping last image captured to Monitor%d.jpg", monitor->Id() );
          else
            printf( "Dumping buffer image %d to Monitor%d.jpg", image_idx, monitor->Id() );
          if ( scale != -1 )
            printf( ", scaling by %d%%", scale );
          printf( "\n" );
        }
        monitor->GetImage( image_idx, scale>0?scale:100 );
      }
      if ( function & ZMU_ZONES )
      {
        if ( verbose )
          printf( "Dumping zone image to Zones%d.jpg\n", monitor->Id() );
        monitor->DumpZoneImage( zoneString );
      }
      if ( function & ZMU_ALARM )
      {
        if ( verbose )
          printf( "Forcing alarm on\n" );
        monitor->ForceAlarmOn( config.forced_alarm_score, "Forced Web" );
      }
      if ( function & ZMU_NOALARM )
      {
        if ( verbose )
          printf( "Forcing alarm off\n" );
        monitor->ForceAlarmOff();
      }
      if ( function & ZMU_CANCEL )
      {
        if ( verbose )
          printf( "Cancelling forced alarm on/off\n" );
        monitor->CancelForced();
      }
      if ( function & ZMU_RELOAD )
      {
        if ( verbose )
          printf( "Reloading monitor settings\n" );
        monitor->actionReload();
      }
      if ( function & ZMU_ENABLE )
      {
        if ( verbose )
          printf( "Enabling event generation\n" );
        monitor->actionEnable();
      }
      if ( function & ZMU_DISABLE )
      {
        if ( verbose )
          printf( "Disabling event generation\n" );
        monitor->actionDisable();
      }
      if ( function & ZMU_SUSPEND )
      {
        if ( verbose )
          printf( "Suspending event generation\n" );
        monitor->actionSuspend();
      }
      if ( function & ZMU_RESUME )
      {
        if ( verbose )
          printf( "Resuming event generation\n" );
        monitor->actionResume();
      }
      if ( function & ZMU_QUERY )
      {
        char monString[16382] = "";
        monitor->DumpSettings( monString, verbose );
        printf( "%s\n", monString );
      }
      if ( function & ZMU_BRIGHTNESS )
      {
        if ( verbose )
        {
          if ( brightness >= 0 )
            printf( "New brightness: %d\n", monitor->actionBrightness( brightness ) );
          else
            printf( "Current brightness: %d\n", monitor->actionBrightness() );
        }
        else
        {
          if ( have_output ) printf( "%c", separator );
          if ( brightness >= 0 )
            printf( "%d", monitor->actionBrightness( brightness ) );
          else
            printf( "%d", monitor->actionBrightness() );
          have_output = true;
        }
      }
      if ( function & ZMU_CONTRAST )
      {
        if ( verbose )
        {
          if ( contrast >= 0 )
            printf( "New brightness: %d\n", monitor->actionContrast( contrast ) );
          else
            printf( "Current contrast: %d\n", monitor->actionContrast() );
        }
        else
        {
          if ( have_output ) printf( "%c", separator );
          if ( contrast >= 0 )
            printf( "%d", monitor->actionContrast( contrast ) );
          else
            printf( "%d", monitor->actionContrast() );
          have_output = true;
        }
      }
      if ( function & ZMU_HUE )
      {
        if ( verbose )
        {
          if ( hue >= 0 )
            printf( "New hue: %d\n", monitor->actionHue( hue ) );
          else
            printf( "Current hue: %d\n", monitor->actionHue() );
        }
        else
        {
          if ( have_output ) printf( "%c", separator );
          if ( hue >= 0 )
            printf( "%d", monitor->actionHue( hue ) );
          else
            printf( "%d", monitor->actionHue() );
          have_output = true;
        }
      }
      if ( function & ZMU_COLOUR )
      {
        if ( verbose )
        {
          if ( colour >= 0 )
            printf( "New colour: %d\n", monitor->actionColour( colour ) );
          else
            printf( "Current colour: %d\n", monitor->actionColour() );
        }
        else
        {
          if ( have_output ) printf( "%c", separator );
          if ( colour >= 0 )
            printf( "%d", monitor->actionColour( colour ) );
          else
            printf( "%d", monitor->actionColour() );
          have_output = true;
        }
      }
      if ( have_output )
      {
        printf( "\n" );
      }
      if ( !function )
      {
        Usage();
      }
      delete monitor;
    }
    else
    {
      fprintf( stderr, "Error, invalid monitor id %d\n", mon_id );
      exit( -1 );
    }
  }
  else
  {
    if ( function & ZMU_QUERY )
    {
#if ZM_HAS_V4L
      char vidString[0x10000] = "";
      bool ok = LocalCamera::GetCurrentSettings( device, vidString, v4lVersion, verbose );
      printf( "%s", vidString );
      exit( ok?0:-1 );
#else // ZM_HAS_V4L
      fprintf( stderr, "Error, video4linux is required for device querying\n" );
      exit( -1 );
#endif // ZM_HAS_V4L
    }

    if ( function & ZMU_LIST )
    {
      std::string sql = "select Id, Function+0 from Monitors";
      if ( !verbose )
      {
        sql += "where Function != 'None'";
      }
      sql += " order by Id asc";

      if ( mysql_query( &dbconn, sql.c_str() ) )
      {
        Error( "Can't run query: %s", mysql_error( &dbconn ) );
        exit( mysql_errno( &dbconn ) );
      }

      MYSQL_RES *result = mysql_store_result( &dbconn );
      if ( !result )
      {
        Error( "Can't use query result: %s", mysql_error( &dbconn ) );
        exit( mysql_errno( &dbconn ) );
      }
      int n_monitors = mysql_num_rows( result );
      Debug( 1, "Got %d monitors", n_monitors );

      printf( "%4s%5s%6s%9s%14s%6s%6s%8s%8s\n", "Id", "Func", "State", "TrgState", "LastImgTim", "RdIdx", "WrIdx", "LastEvt", "FrmRate" );
      for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ )
      {
        int mon_id = atoi(dbrow[0]);
        int function = atoi(dbrow[1]);
        if ( !user || user->canAccess( mon_id ) )
        {
          if ( function > 1 )
          {
            Monitor *monitor = Monitor::Load( mon_id, false, Monitor::QUERY );
            if ( monitor && monitor->connect() )
            {
              struct timeval tv = monitor->GetTimestamp();
              printf( "%4d%5d%6d%9d%11ld.%02ld%6d%6d%8d%8.2f\n",
                monitor->Id(),
                function,
                monitor->GetState(),
                monitor->GetTriggerState(),
                tv.tv_sec, tv.tv_usec/10000,
                monitor->GetLastReadIndex(),
                monitor->GetLastWriteIndex(),
                monitor->GetLastEvent(),
                monitor->GetFPS()
              );
              delete monitor;
            }
          }
          else
          {
            struct timeval tv = { 0, 0 };
            printf( "%4d%5d%6d%9d%11ld.%02ld%6d%6d%8d%8.2f\n",
              mon_id,
              function,
              0,
              0,
              tv.tv_sec, tv.tv_usec/10000,
              0,
              0,
              0,
              0.0
            );
          }
        }
      }
      mysql_free_result( result );
    }
  }
  delete user;

  logTerm();
  zmDbClose();

  return( 0 );
}