From 566a092a202dacaf7fcef896a0b64eb6deb7097c Mon Sep 17 00:00:00 2001
From: Christian Pointner <equinox@helsinki.at>
Date: Thu, 12 Nov 2009 15:26:22 +0000
Subject: added mode and channel cmdline parameter forcing output channel after
 init


diff --git a/openwrt/rhctl/files/switchctl.conf b/openwrt/rhctl/files/switchctl.conf
index 0364e0d..bc7c9db 100644
--- a/openwrt/rhctl/files/switchctl.conf
+++ b/openwrt/rhctl/files/switchctl.conf
@@ -1,3 +1,11 @@
+ch1            01
+ch2            02
+ch3            03
+ch4            04
+ch5            05
+ch6            06
+ch7            07
+ch8            08
 master_main    01
 master_music   02
 standby_main   03
diff --git a/options.c b/options.c
index 8cb11a8..839909e 100644
--- a/options.c
+++ b/options.c
@@ -158,6 +158,9 @@ int options_parse(options_t* opt, int argc, char* argv[])
 
   argc--;
 
+  char* mode = NULL;
+  char* channel = NULL;
+
   int i;
   for(i=1; argc > 0; ++i)
   {
@@ -175,10 +178,36 @@ int options_parse(options_t* opt, int argc, char* argv[])
     PARSE_STRING_PARAM("-f","--config", opt->conf_file_)
     PARSE_STRING_PARAM("-s","--socket", opt->command_sock_)
     PARSE_STRING_PARAM("-d","--device", opt->switch_dev_)
+    PARSE_STRING_PARAM("-m","--mode", mode)
+    PARSE_STRING_PARAM("-c","--channel", channel)
     else 
       return i;
   }
 
+  if(mode) {
+    if(!strcmp(mode, "master"))
+      opt->mode_ = MODE_MASTER;
+    else if(!strcmp(mode, "standby"))
+      opt->mode_ = MODE_STANDBY;
+    else {
+      free(mode);
+      return -3;
+    }
+    free(mode);
+  }
+
+  if(channel) {
+    if(!strcmp(channel, "main"))
+      opt->channel_ = CHAN_MAIN;
+    else if(!strcmp(channel, "music"))
+      opt->channel_ = CHAN_MUSIC;
+    else {
+      free(channel);
+      return -4;
+    }
+    free(channel);
+  }
+
   return 0;
 }
 
@@ -278,6 +307,8 @@ void options_print_usage()
   printf("          [-f|--config] <file>                the configuration file e.g. /etc/rhctl/switchctl.conf\n");
   printf("          [-s|--command-sock] <unix sock>     the command socket e.g. /var/run/rhctl/switchctl.sock\n");
   printf("          [-d|--device] <tty>                 the tty the audio switch is connected to\n");
+  printf("          [-m|--mode] <mode>                  the initial mode to use\n");
+  printf("          [-c|--channel] <channel>            the initial channel to use\n");
 }
 
 void options_print(options_t* opt)
@@ -294,6 +325,8 @@ void options_print(options_t* opt)
   printf("log_targets: \n");
   string_list_print(&opt->log_targets_, "  '", "'\n");
 
+  printf("mode: '%s'\n", opt->mode_ == MODE_MASTER ? "master" : "standby");
+  printf("channel: '%s'\n", opt->channel_ == CHAN_MAIN ? "main" : "music");
   printf("conf_file: '%s'\n", opt->conf_file_);
   printf("command_sock: '%s'\n", opt->command_sock_);
   printf("switch_dev: '%s'\n", opt->switch_dev_);
diff --git a/switchctl.c b/switchctl.c
index ad9d05b..c04d5b8 100644
--- a/switchctl.c
+++ b/switchctl.c
@@ -66,6 +66,9 @@ int send_response(int fd, const char* response)
   if(!response)
     return -1;
 
+  if(fd < 0)
+    return 0;
+
   int ret = send_string(fd, response);
   do {
     ret = write(fd, "\n", 1);
@@ -204,7 +207,7 @@ int process_cmd_request(const char* cmd, cmd_id_t cmd_id, const char* param, int
   return 0;
 }
 
-int swap_channels(const char* ch_from, const char* ch_to, int fd, cmd_t **cmd_q, options_t* opt)
+int crossfade(const char* ch_from, const char* ch_to, int fd, cmd_t **cmd_q, options_t* opt)
 {
   char* cmd_param = strdup("*0FDii*0FUii");
 
@@ -290,7 +293,7 @@ int process_cmd_channel(const char* cmd, const char* param, int fd, cmd_t **cmd_
     opt->channel_ = CHAN_MUSIC;
   }
 
-  int ret = swap_channels(ch_from, ch_to, fd, cmd_q, opt);
+  int ret = crossfade(ch_from, ch_to, fd, cmd_q, opt);
   if(ret) {
     opt->channel_ = old_channel;
     if(ret > 0)
@@ -380,7 +383,7 @@ int process_cmd_mode(const char* param, int fd, cmd_t **cmd_q, options_t* opt)
       return 0;
     }
 
-    int ret = swap_channels(ch_from, ch_to, fd, cmd_q, opt);
+    int ret = crossfade(ch_from, ch_to, fd, cmd_q, opt);
     if(ret) {
       opt->mode_ = old_mode;
       if(ret > 0)
@@ -440,7 +443,7 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, op
   cmd_id_t cmd_id;
   if(!strncmp(cmd, "switch", 6))
     cmd_id = SWITCH;
-  if(!strncmp(cmd, "channel", 7))
+  else if(!strncmp(cmd, "channel", 7))
     cmd_id = CHANNEL;
   else if(!strncmp(cmd, "type", 4))
     cmd_id = TYPE;
@@ -546,29 +549,31 @@ int process_switch(read_buffer_t* buffer, int switch_fd, cmd_t **cmd_q, client_t
       if(buffer->offset > 0 && buffer->buf[buffer->offset-1] == '\r')
         buffer->buf[buffer->offset-1] = 0;
 
-      log_printf(NOTICE, "switch-firmware: %s", buffer->buf);
-
-      int cmd_fd = -1;
-      if(cmd_q && (*cmd_q)) {
-        cmd_fd = (*cmd_q)->fd;
-        send_response(cmd_fd, buffer->buf);
-      }
-      
-      if(!strncmp(buffer->buf, "S0L", 3)) {
-        client_t* client;
-        int listener_cnt = 0;
-        for(client = client_lst; client; client = client->next)
-          if(client->status_listener && client->fd != cmd_fd) {
-            send_response(client->fd, buffer->buf);
-            listener_cnt++;
-          }
-        log_printf(DEBUG, "sent status to %d additional listeners", listener_cnt);
+      if(strlen(buffer->buf)) {
+        log_printf(NOTICE, "switch-firmware: '%s'", buffer->buf);
+        
+        int cmd_fd = -1;
+        if(cmd_q && (*cmd_q)) {
+          cmd_fd = (*cmd_q)->fd;
+          send_response(cmd_fd, buffer->buf);
+        }
+        
+        if(!strncmp(buffer->buf, "S0L", 3)) {
+          client_t* client;
+          int listener_cnt = 0;
+          for(client = client_lst; client; client = client->next)
+            if(client->status_listener && client->fd != cmd_fd) {
+              send_response(client->fd, buffer->buf);
+              listener_cnt++;
+            }
+          log_printf(DEBUG, "sent status to %d additional listeners", listener_cnt);
+        }
+        
+        if((!strncmp(buffer->buf, "RRR", 3)) || 
+           (!strncmp(buffer->buf, "EEE", 3)))
+          cmd_pop(cmd_q);
       }
-
-      if((!strncmp(buffer->buf, "RRR", 3)) || 
-         (!strncmp(buffer->buf, "EEE", 3)))
-        cmd_pop(cmd_q);
-
+        
       buffer->offset = 0;
       return 0;
     }
@@ -605,8 +610,30 @@ int main_loop(int switch_fd, int cmd_listen_fd, options_t* opt)
   FD_SET(sig_fd, &readfds);
   max_fd = (max_fd < sig_fd) ? sig_fd : max_fd;
 
-  struct timeval timeout;
   int return_value = 0;
+
+  char* channel;
+  if(opt->mode_ == MODE_MASTER && opt->channel_ == CHAN_MAIN) channel = "master_main";
+  else if(opt->mode_ == MODE_MASTER && opt->channel_ == CHAN_MUSIC) channel = "master_music";
+  else if(opt->mode_ == MODE_STANDBY && opt->channel_ == CHAN_MAIN) channel = "standby_main";
+  else if(opt->mode_ == MODE_STANDBY && opt->channel_ == CHAN_MUSIC) channel = "standby_music";
+  
+  char* cmd_param = strdup("*0M1*0ii1");
+  char* ch_nr = key_value_storage_find(&opt->alias_table_, channel);
+  if(!ch_nr || ch_nr[0] == 0 || ch_nr[1] == 0 || ch_nr[2] != 0) {
+    log_printf(ERROR, "invalid channel name or number: %s", channel);
+    free(cmd_param);
+    return_value = -1;
+  }
+  else {
+    cmd_param[6] = ch_nr[0];
+    cmd_param[7] = ch_nr[1];
+    return_value = cmd_push(&cmd_q, -1, SWITCH, cmd_param);
+    free(cmd_param);
+    send_command(switch_fd, cmd_q);
+  }
+
+  struct timeval timeout;
   while(!return_value) {
     memcpy(&tmpfds, &readfds, sizeof(tmpfds));
 
@@ -699,6 +726,12 @@ int main(int argc, char* argv[])
     if(ret == -2) {
       fprintf(stderr, "memory error on options_parse, exiting\n");
     }
+    if(ret == -3) {
+      fprintf(stderr, "syntax error: mode name must be either master or standby\n");
+    }
+    if(ret == -4) {
+      fprintf(stderr, "syntax error: channel name must be either main or music\n");
+    }
 
     if(ret != -2)
       options_print_usage();
-- 
cgit v0.10.2