// // rhctl // // Copyright (C) 2009-2016 Christian Pointner // // This file is part of rhctl. // // rhctl is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // rhctl is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with rhctl. If not, see . // package main import ( "github.com/spreadspace/telgo" ) type TelnetInterface struct { server *telgo.Server } func telnetCmdStatus(c *telgo.Client, args []string, ctrl *SwitchControl) bool { ctrl.Commands <- &Command{Type: CmdStatus} // TODO: implement this return false } func telnetUpdateListener(c *telgo.Client, ctrl *SwitchControl) { ch := c.UserData.(chan interface{}) for { data, ok := <-ch if !ok { return } switch data.(type) { case SwitchUpdate: update := data.(SwitchUpdate) if !c.Sayln("audio-switch status(%v): %s", update.Type, update.Data) { ctrl.Updates.Unsub(ch) return } case ServerStatus: status := data.(ServerStatus) if !c.Sayln("playout-server(%s): health=%s, channel=%s", status.Name, status.Health, status.Channel) { ctrl.Updates.Unsub(ch) return } default: if !c.Sayln("unknown update of type: %T", data) { ctrl.Updates.Unsub(ch) return } } } } func telnetCmdListen(c *telgo.Client, args []string, ctrl *SwitchControl) bool { if len(args) <= 1 { c.Sayln("missing argument: ") return false } var ch chan interface{} if c.UserData == nil { ch = ctrl.Updates.Sub() c.UserData = ch } else { ch = c.UserData.(chan interface{}) } switch args[1] { case "status": ctrl.Updates.AddSub(ch, "status") case "server": ctrl.Updates.AddSub(ch, "server:status") case "audio": fallthrough case "gpi": fallthrough case "oc": fallthrough case "relay": fallthrough case "silence": ctrl.Updates.AddSub(ch, "switch:"+args[1]) default: c.Sayln("unknown message type") return false } go telnetUpdateListener(c, ctrl) return false } func telnetCmdServer(c *telgo.Client, args []string, ctrl *SwitchControl) bool { ctrl.Commands <- &Command{Type: CmdServer} // TODO: implement this return false } func telnetCmdSwitch(c *telgo.Client, args []string, ctrl *SwitchControl) bool { if len(args) < 2 { c.Sayln("missing switch command") return false } resp := make(chan interface{}) ctrl.Commands <- &Command{Type: CmdSwitch, Args: args[1:], Response: resp} r := <-resp switch r.(type) { case error: c.Sayln("%v", r) case SwitchResponse: if r.(SwitchResponse).Result != SwitchOK { c.Sayln("%v: %s", r.(SwitchResponse).Result, r.(SwitchResponse).Message) } default: c.Sayln("invalid response of type %T: %+v", r, r) } return false } func telnetHelp(c *telgo.Client, args []string) bool { switch len(args) { case 2: switch args[1] { case "quit": c.Sayln("usage: quit") c.Sayln(" terminates the client connection. You may also use Ctrl-D to do this.") return false case "help": c.Sayln("usage: help [ ]") c.Sayln(" prints command overview or detailed info to .") return false case "status": c.Sayln("usage: status") c.Sayln(" show the status of the switch and servers") return false case "listen": c.Sayln("usage: listen ") c.Sayln(" subscribe to messages of type . The following types are allowed:") c.Sayln(" - status overall status changes") c.Sayln(" - server status/health of the playout server") c.Sayln(" - audio audio input/output mapping changes") c.Sayln(" - gpi general purpose input status messages") c.Sayln(" - oc open-collector status messages") c.Sayln(" - relay relay status messages") c.Sayln(" - silence status of the silence detector") return false case "server": c.Sayln("usage: server ") c.Sayln(" switch to the server of name . If the given server name does not") c.Sayln(" exist or is dead, the switch-over will be denied") return false case "switch": c.Sayln("usage: switch [ [ ] ... ]") c.Sayln(" send commands to tha audio switch directley.") return false } fallthrough default: c.Sayln("usage: [ [ ] ... ]") c.Sayln(" available commands:") c.Sayln(" quit close connection (or use Ctrl-D)") c.Sayln(" help [ ] print this, or help for specific command") c.Sayln(" status show status of switch and all servers") c.Sayln(" listen add listener for messages of type ") c.Sayln(" server switch to server ") c.Sayln(" switch [ [ ] ... ] send command to switch") } return false } func telnetQuit(c *telgo.Client, args []string) bool { return true } func (telnet *TelnetInterface) Run() { rhdl.Printf("Telnet: handler running...") if err := telnet.server.Run(); err != nil { rhl.Printf("Telnet: server returned: %s", err) } } func TelnetInit(conf *Config, ctrl *SwitchControl) (telnet *TelnetInterface) { telnet = &TelnetInterface{} cmdlist := make(telgo.CmdList) cmdlist["status"] = func(c *telgo.Client, args []string) bool { return telnetCmdStatus(c, args, ctrl) } cmdlist["listen"] = func(c *telgo.Client, args []string) bool { return telnetCmdListen(c, args, ctrl) } cmdlist["server"] = func(c *telgo.Client, args []string) bool { return telnetCmdServer(c, args, ctrl) } cmdlist["switch"] = func(c *telgo.Client, args []string) bool { return telnetCmdSwitch(c, args, ctrl) } cmdlist["help"] = telnetHelp cmdlist["quit"] = telnetQuit telnet.server = telgo.NewServer(conf.Clients.Telnet.Address, "rhctl> ", cmdlist, nil) return }