-- Control module for Cisco 9300 switch -- retreives the 1st mac address available at each port ---------------------- -- Initialise ---------------------- Controls['Switch.Status'].Value = 4 Controls['Switch.Status'].String = '' Switch = TcpSocket.New() Switch.ReconnectTimeout = 5 SwitchIP_AddressEventFunctions = {} Controls['Switch.IP_Address'].EventHandler = function() for SwitchIP_Address_i, SwitchIP_Address_confun in pairs(SwitchIP_AddressEventFunctions) do SwitchIP_Address_confun() end end switch_size = 48 SwitchIP_AddressEventFunctions['IP_AddressChanged'] = function() -- TCP RE-CONNECT print('reconnecting TCP because of control property change') Controls['Switch.Status'].Value = 5 Controls['Switch.Status'].String = 'Reconnecting' Switch:Disconnect() do if (not (Controls['Switch.IP_Address'].String == '')) and (not (Controls['Switch.Port'].String == '')) then local success, err = pcall(function() Switch:Connect(Controls['Switch.IP_Address'].String, Controls['Switch.Port'].Value) end) if not success then Controls['Switch.Status'].Value = 2 Controls['Switch.Status'].String = err end else Controls['Switch.Status'].Value = 2 Controls['Switch.Status'].String = 'Check TCP connection properties.' end end end SwitchPortEventFunctions = {} Controls['Switch.Port'].EventHandler = function() for SwitchPort_i, SwitchPort_confun in pairs(SwitchPortEventFunctions) do SwitchPort_confun() end end SwitchPortEventFunctions['PortChanged'] = function() -- TCP RE-CONNECT print('reconnecting TCP because of control property change') Controls['Switch.Status'].Value = 5 Controls['Switch.Status'].String = 'Reconnecting' Switch:Disconnect() do if (not (Controls['Switch.IP_Address'].String == '')) and (not (Controls['Switch.Port'].String == '')) then local success, err = pcall(function() Switch:Connect(Controls['Switch.IP_Address'].String, Controls['Switch.Port'].Value) end) if not success then Controls['Switch.Status'].Value = 2 Controls['Switch.Status'].String = err end else Controls['Switch.Status'].Value = 2 Controls['Switch.Status'].String = 'Check TCP connection properties.' end end end SwitchStatusEventFunctions = {} Controls['Switch.Status'].EventHandler = function() for SwitchStatus_i, SwitchStatus_confun in pairs(SwitchStatusEventFunctions) do SwitchStatus_confun() end end SwitchStatusEventFunctions['StatusChanged'] = function() -- TCP RE-CONNECT print('reconnecting TCP because of control property change') Controls['Switch.Status'].Value = 5 Controls['Switch.Status'].String = 'Reconnecting' Switch:Disconnect() do if (not (Controls['Switch.IP_Address'].String == '')) and (not (Controls['Switch.Port'].String == '')) then local success, err = pcall(function() Switch:Connect(Controls['Switch.IP_Address'].String, Controls['Switch.Port'].Value) end) if not success then Controls['Switch.Status'].Value = 2 Controls['Switch.Status'].String = err end else Controls['Switch.Status'].Value = 2 Controls['Switch.Status'].String = 'Check TCP connection properties.' end end end SwitchStatusConnectedFunctions = {} SwitchStatusConnectedFunctions['StandardConnected'] = function() Controls['Switch.Status'].Value = 0 Controls['Switch.Status'].String = '' end SwitchStatusClosedFunctions = {} SwitchStatusClosedFunctions['StandardClosed'] = function() Controls['Switch.Status'].Value = 2 Controls['Switch.Status'].String = 'Closed' end Switch.Connected = function() for Switch_i, Switch_confun in pairs(SwitchStatusConnectedFunctions) do Switch_confun() end end Switch.Closed = function() for Switch_i, Switch_clofun in pairs(SwitchStatusClosedFunctions) do Switch_clofun() end end Switch.Reconnect = function() Controls['Switch.Status'].Value = 5 Controls['Switch.Status'].String = 'Reconnect' end Switch.Timeout = function() Controls['Switch.Status'].Value = 2 Controls['Switch.Status'].String = 'Timeout' end SwitchConnectionErrorFunctions = {} SwitchConnectionErrorFunctions['StandardError'] = function(error_message) Controls['Switch.Status'].Value = 2 Controls['Switch.Status'].String = error_message end Switch.Error = function(connection, error_message) if error_message == nil then error_message = '' end for Switch_i, Switch_errfun in pairs(SwitchConnectionErrorFunctions) do Switch_errfun(error_message) end end ---- QSYS Initialization ---- function string_contains(str_array, does_contain) if type(str_array) == 'string' then local i = string.find(str_array, does_contain) if i ~= null then return true end else for _, v in ipairs(str_array) do if v == does_contain then return true end end end return false end function logic_ternary(condition, if_true, if_false) if condition then return if_true() else return if_false() end end -- read mac address at each port Switch.Data = function() message = Switch:ReadLine(TcpSocket.EOL.Any) while (message ~= nil) do print(tostring(message)) if message == 'User Access Verification' then Controls['Connect'].IsInvisible = false end Controls['Response'].String = (tostring(message)) for port_number = 1, 48 do text_no = -7 if port_number >= 11 then text_no = -8 end -- run for switch 1 if string_contains(tostring(logic_ternary(((string.sub(tostring(logic_ternary((message == nil), function() return '' end, function() return message end)), text_no, -1)) == nil), function() return '' end, function() return (string.sub(tostring(logic_ternary((message == nil), function() return '' end, function() return message end)), -7, -1)) end)), 'Gi1/0/%s', port_number) then Controls['Mac Address SW1'][port_number].String = (string.sub(tostring(logic_ternary((message == nil), function() return '' end, function() return message end)), 9, 22)) end -- run for switch 2 if string_contains(tostring(logic_ternary(((string.sub(tostring(logic_ternary((message == nil), function() return '' end, function() return message end)), text_no, -1)) == nil), function() return '' end, function() return (string.sub(tostring(logic_ternary((message == nil), function() return '' end, function() return message end)), -7, -1)) end)), 'Gi1/0/%s', port_number) then Controls['Mac Address SW1'][port_number].String = (string.sub(tostring(logic_ternary((message == nil), function() return '' end, function() return message end)), 9, 22)) end end message = Switch:ReadLine(TcpSocket.EOL.Any) end end -- reboot switch Controls['Reboot'].EventHandler = function() Switch:Write((table.concat({tostring('reload'), tostring('\r'), tostring('y'), tostring('\r \r')}))) Controls['Device Online'].Boolean = false end function escape_control_string(text) local result = string.gsub(text, "\\\\", "\\") result = string.gsub(result, "\\r", "\r") result = string.gsub(result, "\\n", "\n") result = string.gsub(result, "\\t", "\t") result = string.gsub(result, "\\b", "\b") result = string.gsub(result, "\\f", "\f") result = string.gsub(result, "\\v", "\v") result = string.gsub(result, "\\0", "\0") result = string.gsub(result, "\\0", "\0") return result end --port reboot SW1 for r=1,#Controls['Reboot Port SW1'] do Controls['Reboot Port SW1'][r].EventHandler = function() Switch:Write((tostring('configure terminal') .. tostring('\r'))) Switch:Write((table.concat({tostring('interface gigabitethernet 1/0/'), tostring(escape_control_string(r)), tostring('\r')}))) Switch:Write((tostring('power inline never') .. tostring('\r'))) Controls['POE Enabled SW1'][r].Boolean = false Timer.CallAfter(function() Switch:Write((tostring('power inline auto') .. tostring('\r'))) Switch:Write((tostring('exit') .. tostring('\r'))) Switch:Write((tostring('exit') .. tostring('\r'))) Controls['POE Enabled SW1'][r].Boolean = true end,5) end end --port reboot SW2 for s=1,#Controls['Reboot Port SW2'] do Controls['Reboot Port SW2'][s].EventHandler = function() Switch:Write((tostring('configure terminal') .. tostring('\r'))) Switch:Write((table.concat({tostring('interface gigabitethernet 2/0/'), tostring(escape_control_string(s)), tostring('\r')}))) Switch:Write((tostring('power inline never') .. tostring('\r'))) Controls['POE Enabled SW2'][s].Boolean = false Timer.CallAfter(function() Switch:Write((tostring('power inline auto') .. tostring('\r'))) Switch:Write((tostring('exit') .. tostring('\r'))) Switch:Write((tostring('exit') .. tostring('\r'))) Controls['POE Enabled SW2'][s].Boolean = true end,5) end end --Make Connect Button Visible Controls['Connect'].EventHandler = function() Switch:Write((tostring(escape_control_string( Controls['Password'].String )) .. tostring('\r \r'))) Timer.CallAfter(function() Switch:Write((tostring('enable') .. tostring('\r \r'))) Timer.CallAfter(function() Switch:Write((tostring(escape_control_string( Controls['ENBABLE Password'].String )) .. tostring('\r \r'))) Timer.CallAfter(function() if string_contains(tostring(logic_ternary((escape_control_string( Controls['Response'].String ) == nil), function() return '' end, function() return escape_control_string( Controls['Response'].String ) end)), '# ') == true then Controls['Device Online'].Boolean = true end Timer.CallAfter(function() Switch:Write((tostring('sh mac address-table | include Gi1/0/([1-2])') .. tostring('\r'))) Timer.CallAfter(function() Switch:Write((tostring('sh mac address-table | include Gi1/0/([3-9])') .. tostring('\r'))) Timer.CallAfter(function() Switch:Write((tostring('sh mac address-table | include Gi2/0/([1-2])') .. tostring('\r'))) Timer.CallAfter(function() Switch:Write((tostring('sh mac address-table | include Gi2/0/([3-9])') .. tostring('\r'))) end,0.1) end,0.1) end,0.1) end,0.1) end,0.1) end,0.2) end,0.2) end --Initialise states on program startup Response = '' Controls['Response'].String = '' for i = 1, 48 do Controls['Mac Address SW1'][i].String = '' end for i = 1, 48 do Controls['Mac Address SW2'][i].String = '' end Controls['Device Online'].Boolean = false for i = 1, 48 do Controls['POE Enabled SW1'][1].Boolean = true end for i = 1, 48 do Controls['POE Enabled SW2'][1].Boolean = true end Controls ['Connect'].IsInvisible = true Controls['Switch.IP_Address'].String = escape_control_string( Controls['IP Address'].String )