I wrote a Perl script to control a BT 8x2 switcher via a serial port. I did this so I can read the status of the switcher and have rdairplay display it after a command is executed. The actual script is listed below.

When I tested the script, I found that it couldn't open the serial port when I ran it from rdairplay, but worked perfectly from the command line.

I had it display the real and effective UID and GID to see what user Rivendell was running the script as; to my astonishment, they were all 1000, which is the same user and group I am logged in as.

Yet doing a chmod o+rw /dev/ttyS0 made the problem go away, indicating that it is indeed a permissions problem.

I hve no problem doin a chmod o+rw /dev/ttyS0 before starting Rivendell, but I'd love to know how it's possible that a Perl script can show the same UID and GID in Rivendell as on the command line (and this user is in the dialout group), yet be unable to access a serial port when running from Rivendell until the serial port is chmodded.

There are things about Rivendell and permissons I clearly don't understand. Doesn't Rivendell always run as the user designated in /etc/rd.conf (AudioOwner and AudioGroup)? This is RD 2.17.0, by the way.


Rob

=========================================================================

#!/usr/bin/perl

use Device::SerialPort qw( :PARAM :STAT 0.07);


sub getstat {
  my $timeout = 1;
  my $chars = 0;
  my $buffer = '';
  my $saw = '';
  $p->read_char_time(0);     # don't wait for each character
  $p->read_const_time(100);  # .1 second per unfulfilled read
  while ($timeout > 0) {
    ($count,$saw) = $p->read(255);
    if ($count > 0) {
      $chars += $count;
      $buffer .= $saw;
    } else { $timeout-- }
  }
  return $buffer;
}


sub is_valid {
  my $a = shift;
  my $b = shift;
  my $c = '';
  my $i = 0;
  my $k = $#$b;
  for ($i = 0; $i <= $k; $i++) {
    $c = shift @$b;
    if ($a eq $c) { return 1 }
  }
  return 0;
}


sub parse {
  my $a = shift;
  my $o1 = '';
  my $o2 = '';
  my @a = ($a =~ 
/(\w\w)(\d{3})(\d{3})(\d{3})(\d{3})(\d{3})(\d{3})(\d{3})(\d{3})/);
  my @b = ($a[$in] =~ /(\d)(\d)(\d)/);
  my $o = '';
  if ($b[1] eq '1') { $o .= $DST[1] . ',' }
  if ($b[2] eq '1') { $o .= $DST[2] . ',' }
  if ($o gt '') {
    chop $o;
    $o = $SRC[$in] . " -> " . $o;
  } else { $o = $SRC[$in] . " -> MUTE" }
  return $o;
}


sub rmllabel {
  my $a = shift;
  my @c = ('rmlsend',"--to-host=$HOST","LB $a" . '!');
  system(@c);
}


# MAIN PROGRAM
$HOST = 'pelamis';
$PORT = '/dev/ttyS0';
@SRC = ('0','Air Studio','Source 2','Main Production','Source 4','Green Room',
'Source 6','Rivendell','Source 8');
@DST = ('0','All Xmtrs','Dest 2');
@SRX = ('1','2','3','4','5','6','7','8');
@DSX = ('0','1','2');

$in = $ARGV[0];
$out = $ARGV[1];

if ((&is_valid($in,'SRX')) && (&is_valid($out,'DSX'))) {
  if ($p = Device::SerialPort->new($PORT)) {
    $p->baudrate(2400);
    $p->parity('none');
    $p->databits(8);
    $p->stopbits(1);
    $p->handshake('none');
    $p->write_settings;
    $p->write('*' . $in . $out .'1' . "\r\n");
    $a = &parse(&getstat);
    &rmllabel($a);
    $p->close;
    undef $p;
  } else { &rmllabel("Serial port error") }
} else { &rmllabel("Invalid parameters") }


_______________________________________________
Rivendell-dev mailing list
Rivendell-dev@lists.rivendellaudio.org
http://caspian.paravelsystems.com/mailman/listinfo/rivendell-dev

Reply via email to