diff options
author | Christian Pointner <equinox@helsinki.at> | 2009-11-10 17:42:36 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2009-11-10 17:42:36 (GMT) |
commit | d844b581b34e52a0514156c80a9180e6cdb58a36 (patch) | |
tree | 58cc6d21cb0b1fcb35812b9735bd1fbb34cb60fc | |
parent | 6b7dbe7b1c23984b662c02c23205e38d224a5fd4 (diff) |
added command channel
-rw-r--r-- | command_queue.h | 2 | ||||
-rw-r--r-- | options.c | 1 | ||||
-rw-r--r-- | options.h | 4 | ||||
-rw-r--r-- | switchctl.c | 167 |
4 files changed, 147 insertions, 27 deletions
diff --git a/command_queue.h b/command_queue.h index 7a475fd..d77a6f6 100644 --- a/command_queue.h +++ b/command_queue.h @@ -24,7 +24,7 @@ #include <sys/time.h> -enum cmd_id_enum { SWITCH, TYPE, MODE, STATUS, LOG, LISTEN }; +enum cmd_id_enum { SWITCH, CHANNEL, TYPE, MODE, STATUS, LOG, LISTEN }; typedef enum cmd_id_enum cmd_id_t; struct cmd_struct { @@ -231,6 +231,7 @@ void options_default(options_t* opt) string_list_init(&opt->log_targets_); opt->mode_ = MODE_MASTER; + opt->channel_ = CHAN_MAIN; opt->conf_file_ = strdup("/etc/rhctl/switchctl.conf"); opt->command_sock_ = strdup("/var/run/rhctl/switchctl.sock"); opt->switch_dev_ = strdup("/dev/audioswitch"); @@ -28,6 +28,9 @@ enum mode_enum { MODE_MASTER, MODE_STANDBY }; typedef enum mode_enum mode_t; +enum channel_enum { CHAN_MAIN, CHAN_MUSIC }; +typedef enum channel_enum channel_t; + struct options_struct { char* progname_; int daemonize_; @@ -38,6 +41,7 @@ struct options_struct { string_list_t log_targets_; mode_t mode_; + channel_t channel_; char* conf_file_; char* command_sock_; char* switch_dev_; diff --git a/switchctl.c b/switchctl.c index dcf417c..5a7c94e 100644 --- a/switchctl.c +++ b/switchctl.c @@ -44,7 +44,8 @@ int send_command(int switch_fd, cmd_t* cmd) char* c = NULL; switch(cmd->cmd) { - case SWITCH: c = cmd->param; break; + case SWITCH: + case CHANNEL: c = cmd->param; break; case STATUS: c = "*0SL"; break; } @@ -81,6 +82,7 @@ int process_cmd_request(const char* cmd, cmd_id_t cmd_id, const char* param, int client_t* c = client_find(client_lst, fd); if(!c) { log_printf(WARNING, "ignoring request from unknown client"); + send_response(fd, "EEE: switch: client not found in client list?!"); return 0; } @@ -89,12 +91,13 @@ int process_cmd_request(const char* cmd, cmd_id_t cmd_id, const char* param, int if((opt->mode_ == MODE_MASTER && c->type == STANDBY )|| (opt->mode_ == MODE_STANDBY && c->type == MASTER )) { - log_printf(INFO, "ignoring request from inactive system (%s)", c->type == MASTER ? "master" : "standby"); + log_printf(INFO, "silently ignoring request from inactive system (%s)", c->type == MASTER ? "master" : "standby"); return 0; } if(!param) { log_printf(INFO, "ignoring switch command without parameter"); + send_response(fd, "EEE: switch: missing parameter"); return 0; } @@ -114,14 +117,9 @@ int process_cmd_request(const char* cmd, cmd_id_t cmd_id, const char* param, int ch_name = &(param[5]); ch_nr = &(cmd_param[4]); } - else if(!strncmp(param, "on ", 3)) { + else if(!strncmp(param, "select ", 7)) { cmd_param = strdup("*0ii1"); - ch_name = &(param[3]); - ch_nr = &(cmd_param[2]); - } - else if(!strncmp(param, "off ", 4)) { - cmd_param = strdup("*0iiM1"); - ch_name = &(param[4]); + ch_name = &(param[7]); ch_nr = &(cmd_param[2]); } else if(!strncmp(param, "add ", 4)) { @@ -134,14 +132,14 @@ int process_cmd_request(const char* cmd, cmd_id_t cmd_id, const char* param, int ch_name = &(param[3]); ch_nr = &(cmd_param[2]); } - else if(!strncmp(param, "on2 ", 4)) { - cmd_param = strdup("*0ii2"); - ch_name = &(param[4]); + else if(!strncmp(param, "mute ", 5)) { + cmd_param = strdup("*0iiM1"); + ch_name = &(param[5]); ch_nr = &(cmd_param[2]); } - else if(!strncmp(param, "off2 ", 5)) { - cmd_param = strdup("*0iiM2"); - ch_name = &(param[5]); + else if(!strncmp(param, "select2 ", 8)) { + cmd_param = strdup("*0ii2"); + ch_name = &(param[8]); ch_nr = &(cmd_param[2]); } else if(!strncmp(param, "add2 ", 5)) { @@ -154,13 +152,20 @@ int process_cmd_request(const char* cmd, cmd_id_t cmd_id, const char* param, int ch_name = &(param[4]); ch_nr = &(cmd_param[2]); } + else if(!strncmp(param, "mute2 ", 6)) { + cmd_param = strdup("*0iiM2"); + ch_name = &(param[6]); + ch_nr = &(cmd_param[2]); + } else { log_printf(INFO, "ignoring invalid switch command: '%s'", param); + send_response(fd, "EEE: switch: invalid command"); return 0; } char* ch_tmp = key_value_storage_find(&opt->alias_table_, ch_name); if(!ch_tmp || ch_tmp[0] == 0 || ch_tmp[1] == 0 || ch_tmp[2] != 0) { log_printf(ERROR, "invalid channel name or number: %s", ch_name); + send_response(fd, "EEE: switch: invalid channel name or number"); free(cmd_param); return 0; } @@ -178,14 +183,17 @@ int process_cmd_request(const char* cmd, cmd_id_t cmd_id, const char* param, int return ret; if(cmd_id == STATUS) { - char buf[30]; - snprintf(buf, 30, "Current Mode: %s", opt->mode_ == MODE_MASTER ? "Master" : "Standby"); - send_response(fd, buf); + char buf[2][30]; + snprintf(buf[0], 30, "Current Mode: %s", opt->mode_ == MODE_MASTER ? "Master" : "Standby"); + send_response(fd, buf[0]); + snprintf(buf[1], 30, "Current Channel: %s", opt->channel_ == CHAN_MAIN ? "Main" : "Music"); + send_response(fd, buf[1]); client_t* client; int listener_cnt = 0; for(client = client_lst; client; client = client->next) if(client->status_listener && client->fd != fd) { - send_response(client->fd, buf); + send_response(client->fd, buf[0]); + send_response(client->fd, buf[1]); listener_cnt++; } log_printf(DEBUG, "sent status to %d additional listeners", listener_cnt); @@ -196,6 +204,93 @@ int process_cmd_request(const char* cmd, cmd_id_t cmd_id, const char* param, int return 0; } +int process_cmd_channel(const char* cmd, const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt) +{ + client_t* c = client_find(client_lst, fd); + if(!c) { + log_printf(WARNING, "ignoring request from unknown client"); + send_response(fd, "EEE: channel: client not found in client list?!"); + return 0; + } + + if(c->type != MASTER && c->type != STANDBY) { + log_printf(WARNING, "ignoring request from client of wrong type"); + send_response(fd, "EEE: channel: client type doesn't fit"); + return 0; + } + + if((opt->mode_ == MODE_MASTER && c->type == STANDBY )|| + (opt->mode_ == MODE_STANDBY && c->type == MASTER )) + { + log_printf(INFO, "silently ignoring request from inactive system (%s)", c->type == MASTER ? "master" : "standby"); + return 0; + } + + if(!param) { + log_printf(INFO, "ignoring channel command without parameter"); + send_response(fd, "EEE: channel: missing parameter"); + return 0; + } + + char* cmd_param = strdup("*0FDii*0FUii"); + char* ch_from = NULL; + char* ch_to = NULL; + if(!strcmp(param, "main")) { + if(opt->mode_ == MODE_MASTER) { + ch_from = "master_music"; + ch_to = "master_main"; + } + else { + ch_from = "standby_music"; + ch_to = "standby_main"; + } + opt->channel_ = CHAN_MAIN; + } + else if(!strcmp(param, "music")) { + if(opt->mode_ == MODE_MASTER) { + ch_from = "master_main"; + ch_to = "master_music"; + } + else { + ch_from = "standby_main"; + ch_to = "standby_music"; + } + opt->channel_ = CHAN_MUSIC; + } + + + char* ch_nr_from = key_value_storage_find(&opt->alias_table_, ch_from); + if(!ch_nr_from || ch_nr_from[0] == 0 || ch_nr_from[1] == 0 || ch_nr_from[2] != 0) { + log_printf(ERROR, "invalid channel name or number: %s", ch_from); + send_response(fd, "EEE: channel: invalid channel name or number"); + free(cmd_param); + return 0; + } + + char* ch_nr_to = key_value_storage_find(&opt->alias_table_, ch_to); + if(!ch_nr_to || ch_nr_to[0] == 0 || ch_nr_to[1] == 0 || ch_nr_to[2] != 0) { + log_printf(ERROR, "invalid channel name or number: %s", ch_to); + send_response(fd, "EEE: channel: invalid channel name or number"); + free(cmd_param); + return 0; + } + + cmd_param[4] = ch_nr_from[0]; + cmd_param[5] = ch_nr_from[1]; + cmd_param[10] = ch_nr_to[0]; + cmd_param[11] = ch_nr_to[1]; + + log_printf(DEBUG, "enqueing command to switch: '%s'", cmd_param); + int ret = cmd_push(cmd_q, fd, CHANNEL, cmd_param); + free(cmd_param); + if(ret) + return ret; + + log_printf(NOTICE, "command: %s", cmd); + + return 0; +} + void process_cmd_type(const char* param, int fd, client_t* client_lst) { if(param) { @@ -209,19 +304,24 @@ void process_cmd_type(const char* param, int fd, client_t* client_lst) client->type = HEARTBEAT; else { log_printf(DEBUG, "unkown client type '%s'", param); + send_response(fd, "EEE: type: unknown client type"); return; } log_printf(DEBUG, "client %d type set to %s", fd, param); } - else + else { log_printf(ERROR, "unable to set client type for %d: client not found", fd); + send_response(fd, "EEE: type: client not found in client list?!"); + } } - else + else { log_printf(ERROR, "unable to set client type for %d: empty parameter", fd); + send_response(fd, "EEE: type: missing parameter"); + } } -void process_cmd_mode(const char* param, options_t* opt) +void process_cmd_mode(const char* param, int fd, options_t* opt) { if(param) { if(!strncmp(param, "master", 6)) @@ -230,11 +330,14 @@ void process_cmd_mode(const char* param, options_t* opt) opt->mode_ = MODE_STANDBY; else { log_printf(DEBUG, "unkown mode '%s'", param); + send_response(fd, "EEE: mode: unknown mode"); return; } } - else + else { log_printf(ERROR, "unable to set mode: empty parameter"); + send_response(fd, "EEE: mode: missing parameter"); + } log_printf(NOTICE, "new mode: %s", opt->mode_ == MODE_MASTER ? "master" : "standby"); } @@ -258,13 +361,16 @@ void process_cmd_listen(const char* param, int fd, client_t* client_lst) } else { log_printf(DEBUG, "unkown listener type '%s'", param); + send_response(fd, "EEE: listen: unkown type"); return; } } log_printf(DEBUG, "listener %d requests %s messages", fd, param ? param:"all"); } - else + else { log_printf(ERROR, "unable to add listener %d", fd); + send_response(fd, "EEE: listen: client not found in client list?!"); + } } int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt) @@ -277,6 +383,8 @@ 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)) + cmd_id = CHANNEL; else if(!strncmp(cmd, "type", 4)) cmd_id = TYPE; else if(!strncmp(cmd, "mode", 4)) @@ -290,13 +398,14 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, op } else { log_printf(WARNING, "unknown command '%s'", cmd); + send_response(fd, "EEE: unknown command"); return 0; } char* param = strchr(cmd, ' '); if(param) param++; - if(cmd_id == SWITCH || cmd_id == MODE) { + if(cmd_id == SWITCH || cmd_id == CHANNEL || cmd_id == MODE) { char* resp; asprintf(&resp, "Request: %s", cmd); if(resp) { @@ -323,8 +432,14 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, op return ret; break; } + case CHANNEL: { + int ret = process_cmd_channel(cmd, param, fd, cmd_q, client_lst, opt); + if(ret) + return ret; + break; + } case TYPE: process_cmd_type(param, fd, client_lst); break; - case MODE: process_cmd_mode(param, opt); break; + case MODE: process_cmd_mode(param, fd, opt); break; case LOG: { if(param && param[0]) log_printf(NOTICE, "ext msg: %s", param); |