summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2014-03-25 19:14:42 (GMT)
committerChristian Pointner <equinox@helsinki.at>2014-03-25 19:14:42 (GMT)
commitc4989d4bd8821e3ff853a41b3ff235adcc4fe925 (patch)
tree61a3b2b805fde8db2518455fdfadbab466a896cd
parenta6afa899228cdd6a42a77bd5f75471871c2ef026 (diff)
updating health info on disconnect and reconnect
also changing mode if health state changes..
-rw-r--r--switchctl.c250
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;
}