diff options
-rw-r--r-- | switchctl.c | 250 |
1 files changed, 135 insertions, 115 deletions
diff --git a/switchctl.c b/switchctl.c index 5396d3d..f3daab0 100644 --- a/switchctl.c +++ b/switchctl.c @@ -358,7 +358,93 @@ int process_cmd_channel(const char* cmd, const char* param, int fd, cmd_t **cmd_ return 0; } -int update_send_health_status(int fd, client_t* client_lst) +int change_mode(switchctl_mode_t old_mode, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt) +{ + char* ch_from = NULL; + if(old_mode == MODE_MASTER && state_.channel_master_ == CHAN_MAIN) + ch_from = "master_main"; + else if(old_mode == MODE_MASTER && state_.channel_master_ == CHAN_MUSIC) + ch_from = "master_music"; + else if(old_mode == MODE_STANDBY && state_.channel_standby_ == CHAN_MAIN) + ch_from = "standby_main"; + else if(old_mode == MODE_STANDBY && state_.channel_standby_ == CHAN_MUSIC) + ch_from = "standby_music"; + else { + state_.mode_ = old_mode; + log_printf(ERROR, "EEE: mode: old config is illegal?!"); + return 0; + } + + char* ch_to = NULL; + if(state_.mode_ == MODE_MASTER && state_.channel_master_ == CHAN_MAIN) + ch_to = "master_main"; + else if(state_.mode_ == MODE_MASTER && state_.channel_master_ == CHAN_MUSIC) + ch_to = "master_music"; + else if(state_.mode_ == MODE_STANDBY && state_.channel_standby_ == CHAN_MAIN) + ch_to = "standby_main"; + else if(state_.mode_ == MODE_STANDBY && state_.channel_standby_ == CHAN_MUSIC) + ch_to = "standby_music"; + else { + state_.mode_ = old_mode; + log_printf(ERROR, "EEE: mode: current config is illegal?!"); + return 0; + } + + int ret = crossfade(ch_from, ch_to, fd, cmd_q, opt); + if(ret) { + state_.mode_ = old_mode; + if(ret > 0) + return 0; + + return ret; + } + + char* mode_str; + int len = asprintf(&mode_str, "new Mode: %s", state_.mode_ == MODE_MASTER ? "master" : "standby"); + if(len > 0) { + log_printf(NOTICE, "%s", mode_str); + client_t* client; + int listener_cnt = 0; + for(client = client_lst; client; client = client->next) + if(client->mode_listener && client->fd != fd) { + send_response(client->fd, mode_str); + listener_cnt++; + } + free(mode_str); + log_printf(DEBUG, "sent new mode to %d additional listeners", listener_cnt); + } + + return 0; +} + +int process_cmd_mode(const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt) +{ + switchctl_mode_t old_mode = state_.mode_; + + if(param) { + if(!strncmp(param, "master", 6)) + state_.mode_ = MODE_MASTER; + else if(!strncmp(param, "standby", 7)) + state_.mode_ = MODE_STANDBY; + else { + log_printf(DEBUG, "unkown mode '%s'", param); + send_response(fd, "EEE: mode: unknown mode"); + return 0; + } + + // swap master with standby channels only when mode has changed + if(old_mode != state_.mode_) + return change_mode(old_mode, fd, cmd_q, client_lst, opt); + } + else { + log_printf(ERROR, "unable to set mode: empty parameter"); + send_response(fd, "EEE: mode: missing parameter"); + } + + return 0; +} + +int send_health_status(int fd, client_t* client_lst) { bool mc, sc, hmc, hsc; mc = sc = hmc = hsc = 0; @@ -374,9 +460,6 @@ int update_send_health_status(int fd, client_t* client_lst) } } - if(!hmc) state_.hb_state_master_ = 0; - if(!hsc) state_.hb_state_standby_ = 0; - char buf[5][50]; snprintf(buf[0], 50, "Health: %s", (mc && sc && hmc && hsc && state_.hb_state_master_ && state_.hb_state_standby_) ? "ok" : "error"); snprintf(buf[1], 50, "Master: %s", (mc) ? "connected" : "offline"); @@ -406,7 +489,46 @@ int update_send_health_status(int fd, client_t* client_lst) return 0; } -void process_cmd_type(const char* param, int fd, client_t* client_lst) +int update_health_status(int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt) +{ + bool hmc, hsc; + hmc = hsc = 0; + + client_t* client; + for(client = client_lst; client; client = client->next) { + switch(client->type) { + case HB_MASTER: hmc=1; break; + case HB_STANDBY: hsc=1; break; + default: break; + } + } + + if(!hmc) state_.hb_state_master_ = 0; + if(!hsc) state_.hb_state_standby_ = 0; + + switchctl_mode_t old_mode = state_.mode_; + if(state_.mode_ == MODE_MASTER) { + if(!state_.hb_state_master_) { + if(state_.hb_state_standby_) { + state_.mode_ = MODE_STANDBY; + return change_mode(old_mode, fd, cmd_q, client_lst, opt); + } + } + } else { + if(!state_.hb_state_standby_) { + if(state_.hb_state_master_) { + state_.mode_ = MODE_MASTER; + return change_mode(old_mode, fd, cmd_q, client_lst, opt); + } + } + } + + send_health_status(fd, client_lst); + + return 0; +} + +void process_cmd_type(const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt) { if(param) { client_t* client = client_find(client_lst, fd); @@ -430,7 +552,7 @@ void process_cmd_type(const char* param, int fd, client_t* client_lst) return; } log_printf(DEBUG, "client %d type set to %s", fd, param); - update_send_health_status(-1, client_lst); + update_health_status(-1, cmd_q, client_lst, opt); } else { log_printf(ERROR, "unable to set client type for %d: type already set to %s", fd, client_type_tostring(client->type)); @@ -448,92 +570,6 @@ void process_cmd_type(const char* param, int fd, client_t* client_lst) } } -int change_mode(switchctl_mode_t old_mode, int fd, cmd_t **cmd_q, options_t* opt, client_t* client_lst) -{ - char* ch_from = NULL; - if(old_mode == MODE_MASTER && state_.channel_master_ == CHAN_MAIN) - ch_from = "master_main"; - else if(old_mode == MODE_MASTER && state_.channel_master_ == CHAN_MUSIC) - ch_from = "master_music"; - else if(old_mode == MODE_STANDBY && state_.channel_standby_ == CHAN_MAIN) - ch_from = "standby_main"; - else if(old_mode == MODE_STANDBY && state_.channel_standby_ == CHAN_MUSIC) - ch_from = "standby_music"; - else { - state_.mode_ = old_mode; - log_printf(ERROR, "EEE: mode: old config is illegal?!"); - return 0; - } - - char* ch_to = NULL; - if(state_.mode_ == MODE_MASTER && state_.channel_master_ == CHAN_MAIN) - ch_to = "master_main"; - else if(state_.mode_ == MODE_MASTER && state_.channel_master_ == CHAN_MUSIC) - ch_to = "master_music"; - else if(state_.mode_ == MODE_STANDBY && state_.channel_standby_ == CHAN_MAIN) - ch_to = "standby_main"; - else if(state_.mode_ == MODE_STANDBY && state_.channel_standby_ == CHAN_MUSIC) - ch_to = "standby_music"; - else { - state_.mode_ = old_mode; - log_printf(ERROR, "EEE: mode: current config is illegal?!"); - return 0; - } - - int ret = crossfade(ch_from, ch_to, fd, cmd_q, opt); - if(ret) { - state_.mode_ = old_mode; - if(ret > 0) - return 0; - - return ret; - } - - char* mode_str; - int len = asprintf(&mode_str, "new Mode: %s", state_.mode_ == MODE_MASTER ? "master" : "standby"); - if(len > 0) { - log_printf(NOTICE, "%s", mode_str); - client_t* client; - int listener_cnt = 0; - for(client = client_lst; client; client = client->next) - if(client->mode_listener && client->fd != fd) { - send_response(client->fd, mode_str); - listener_cnt++; - } - free(mode_str); - log_printf(DEBUG, "sent new mode to %d additional listeners", listener_cnt); - } - - return 0; -} - -int process_cmd_mode(const char* param, int fd, cmd_t **cmd_q, options_t* opt, client_t* client_lst) -{ - switchctl_mode_t old_mode = state_.mode_; - - if(param) { - if(!strncmp(param, "master", 6)) - state_.mode_ = MODE_MASTER; - else if(!strncmp(param, "standby", 7)) - state_.mode_ = MODE_STANDBY; - else { - log_printf(DEBUG, "unkown mode '%s'", param); - send_response(fd, "EEE: mode: unknown mode"); - return 0; - } - - // swap master with standby channels only when mode has changed - if(old_mode != state_.mode_) - return change_mode(old_mode, fd, cmd_q, opt, client_lst); - } - else { - log_printf(ERROR, "unable to set mode: empty parameter"); - send_response(fd, "EEE: mode: missing parameter"); - } - - return 0; -} - int process_cmd_heartbeat(const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt) { if(param) { @@ -554,23 +590,7 @@ int process_cmd_heartbeat(const char* param, int fd, cmd_t **cmd_q, client_t* cl break; } } - update_send_health_status(-1, client_lst); - switchctl_mode_t old_mode = state_.mode_; - if(state_.mode_ == MODE_MASTER) { - if(!state_.hb_state_master_) { - if(state_.hb_state_standby_) { - state_.mode_ = MODE_STANDBY; - return change_mode(old_mode, fd, cmd_q, opt, client_lst); - } - } - } else { - if(!state_.hb_state_standby_) { - if(state_.hb_state_master_) { - state_.mode_ = MODE_MASTER; - return change_mode(old_mode, fd, cmd_q, opt, client_lst); - } - } - } + update_health_status(-1, cmd_q, client_lst, opt); } else { log_printf(ERROR, "unable to update heartbeat status: client not found"); @@ -584,9 +604,9 @@ int process_cmd_heartbeat(const char* param, int fd, cmd_t **cmd_q, client_t* cl return 0; } -int process_cmd_health(const char* param, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt) +int process_cmd_health(const char* param, int fd, client_t* client_lst) { - return update_send_health_status(fd, client_lst); + return send_health_status(fd, client_lst); } void process_cmd_listen(const char* param, int fd, client_t* client_lst) @@ -718,9 +738,9 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, op return ret; break; } - case TYPE: process_cmd_type(param, fd, client_lst); break; + case TYPE: process_cmd_type(param, fd, cmd_q, client_lst, opt); break; case MODE: { - int ret = process_cmd_mode(param, fd, cmd_q, opt, client_lst); + int ret = process_cmd_mode(param, fd, cmd_q, client_lst, opt); if(ret) return ret; break; @@ -732,7 +752,7 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, op break; } case HEALTH: { - int ret = process_cmd_health(param, fd, cmd_q, client_lst, opt); + int ret = process_cmd_health(param, fd, client_lst); if(ret) return ret; break; @@ -962,7 +982,7 @@ int main_loop(int switch_fd, int cmd_listen_fd, options_t* opt) lst = lst->next; FD_CLR(deletee->fd, &readfds); client_remove(&client_lst, deletee->fd); - update_send_health_status(-1, client_lst); + update_health_status(-1, &cmd_q, client_lst, opt); return_value = 0; continue; } |