Ansteuerung eines ELSA ISDN4U ISDN Routers

Code-Stücke können hier veröffentlicht werden.
Antworten
juergen
User
Beiträge: 8
Registriert: Mittwoch 11. Dezember 2002, 09:55
Wohnort: Köln

Hier sind zwei Python - Files, die a) auf Basis von Telnet ein ELSA ISDN 4U steuern und b) eine Oberfläche auf Tkinter - Basis bieten, mit der man sein Provider-Passwort eintragen und auch die Verbindung beenden und sperren kann. Für Hinweise bin ich dankbar, denn ich befasse mich noch nicht sehr lange mit Python. Übrigens müsste das ganze auch - ggf. modifiziert - mit Lancom Routern funktionieren.
Jürgen
a)

Code: Alles auswählen

"""Author: Juergen Diel (J.Diel@NetCologne.de)\n
Implementiert eine Klasse ISDN4U, mit der man ein ELSA ISDN4U steuern kann."""

## ToDo:
## Prettify:    Funktionsbeschreibungen etc. dem Standard anpassen
##              Namenskonventionen nutzen
## Wenn fertig: Als Modul ablegen und Script mit schoener Benutzeroberflaeche erstellen
import sys
import telnetlib    # Bibliothek, die mit Python geliefert wird
from string import *

#-------------------------------------------------------------------------------
class ISDN4U:
    def telnetISDN4U(self, locTN,Befehl):
        "Wickelt die unmittelbare Kommunikation mit Telnet ab und sollte nicht ausserhalb der Klasse benutzt werden"
        # Setzt einen Befehl an das bereits geoeffnete Telnet-Objekt locTN ab
        # und gibt die Antwort zurueck
        # Der Befehl wird hier um \r\n ergaenzt und ueberschuessige \r aus
        # der Antwort entfernt
        locTN.write(Befehl+'\r\n')
        # bei mehrzeiligen Antworten werden die ersten Zeilen mit \r\n,
        # aber nur die letzte Zeile nur mit \n abgeschlossen.
        result=""
        while (len(result) == 0) or result.endswith("\r\n"):
            result=result+locTN.read_until("\n",1) 
        return result.replace("\r","")
        # Die folgenden Funktionen schliessen den Pfad in slashes ein; werden sie
        # aber doch im Argument uebergeben, macht das nichts: sie werden dann entfernt
    def __init__(self, HostAdr):
        "Konstruktor oeffnet die Telnet - Session zu ISDN4U mit der angegebenen IP-Adresse"
        self.MyHostAdr=HostAdr
        self.tn = telnetlib.Telnet(HostAdr) # Eroeffnung der Telnet Session
        self.Sessionstart=self.telnetISDN4U(self.tn,"")
        self.ReadOnlyConn=find(self.Sessionstart,"(read-only connection)")>0
        self.Sessionstart=map(lambda x: strip(replace(x,"|","")),split(strip(self.Sessionstart),"\n"))[1:7]
    def ISet (self, Pfad, VarName, VarValue):
        """Setze in einem Pfad eine Variable 'VarName' auf einen Wert 'VarValue'
        und liefere Wahrheitswert zurueck : true ist o.k."""
        if self.ReadOnlyConn:
            return 0
        else:
            return self.telnetISDN4U(self.tn,replace("set /"+Pfad+"/"+VarName+"="+VarValue,"//","/")).find("set ok:") > 0
    def IGetRaw (self, Pfad="", VarName=""):
        "Gib den Inhalt der Variablen 'VarName' im 'Pfad' zurueck. Bei leerem VarName: Fehler"
        return self.telnetISDN4U(self.tn,replace("ls /"+Pfad+"/"+VarName,"//","/"))
    def IGet (self, Pfad="", VarName=""):
        "Gib den Inhalt der Variablen 'VarName' im 'Pfad' zurueck."
        tempraw = self.IGetRaw(Pfad,VarName)
        ValPos = find(tempraw,"VALUE:")
        if ValPos > 0:
            return strip(tempraw[ValPos+6:])
        else:
            InfoPos = find(tempraw,"INFO:") # Im Falle von read-only sessions
            if InfoPos > 0:
                return strip(tempraw[InfoPos+5:])
            else:
                # raise Error hier einzufuegen
                return tempraw
    def IMenu (self, Pfad=""):
        "Gib die Menue-Optionen im 'Pfad' zurueck."
        tempraw = self.IGetRaw(Pfad,"")
        ValPos = find(tempraw,"MENU:")
        if ValPos == 0:
            # raise Error hier einzufuegen
            return tempraw
        else:
            return map(lambda x:strip(replace(x,"MENU:","")),split(strip(tempraw),"\n"))
    def IDo (self, Pfad, Command):
        """Fuehre das Kommando im Pfad aus
        und liefere Wahrheitswert zurueck : true ist o.k."""
        if self.ReadOnlyConn:
            return 0
        else:
            return self.telnetISDN4U(self.tn,replace("do /"+Pfad+"/"+Command,"//","/")).find("OK:") > 0
    def __del__ (self):
        "Destruktor beendet auch die Session"
        self.tn.write("exit\r\n")
    def __str__ (self):
        "Nenne die Host-Adresse und die Anmelde-Info des ISDN-4U"
        return("Telnet-Session mit "+self.MyHostAdr+"\n"+join(self.Sessionstart,"\n"))
    def IConnStat(self, ConnNo=1):
        "Gibt den Status der Connection ConnNo an"
        RawStatus=self.IGetRaw("se/i/man","s")
        RawStatus = map(strip,split(RawStatus[14:],";"))[ConnNo-1]
        if RawStatus.find("INTERNET") > 0 or RawStatus.find("Ready") > 0:
            return RawStatus[6:]
        else:
            return RawStatus
        # Holt sich die Statuszeile mit self.IGet(...)
        # Wir brauchen aber nicht die Anfangsmeldung, sondern nur ab Stelle 14 [14:]
        # Was uebrig bleibt, wird beim Semikolon aufgeteilt, es entsteht eine Liste durch Split
        # Alle Elemente der Liste (durch map) werden von leading/trailing blanks befreit (split)
        # Wir brauchen das Element [ConnNo-1] (Index beginnt bei 0)
        # ... und davon brauchen wir alles ab Stelle 6 [6:]
    def ITermConn(self):
        "Beendet Verbindungen"
        return self.IDo("se/i/man","d")
    def ISetPass(self,Passw):
        "Setzt Password"
        return self.ISet("se/i","password",Passw)
    def ISetTelNo(self,TelNo):
        "Setzt Telefonnummer des Providers"
        return self.ISet("se/i","Dialup-number",TelNo)

#-------------------------------------------------------------------------------
if __name__ == '__main__':
# Hauptprogramm folgt (Beispiele):

    HOST = "192.16.150.1"       # IP-Adresse des ISDN4U


    MySession = ISDN4U(HOST) # Eroeffnung der Telnet Session


    print ("--------- Erste Meldung folgt----------------------------------")
    print MySession
    if MySession.ReadOnlyConn:
        print("!!!!!!!!!!!!!!!!!!!! Read Only !!!!!!!!!!!!!!!!!!!!!!!!!!")
    print ("--------- Abfrage Username folgt-------# Top Level Menu--------")
    print MySession.IGet("se/i","username")
    print ("--------- ls folgt---------------------# Top Level Menu--------")
    print MySession.IMenu()
    print ("--------- ls se-i folgt----------------# Top Level Menu--------")
    print MySession.IMenu("/se/i")
    print ("--------- ls /se/i/man/s folgt---------# Verbindungsstatus-----")
    print MySession.IConnStat()
    print ("--------- set /se/i/password= folgt----# Password setzen-------")
    print MySession.ISetPass("x")
    print ("--------- do /se/i/man/d folgt---------# Verbindung schliessen-")
    print MySession.ITermConn()
    print ("--------- ls /se/i/man/s folgt---------# Verbindungsstatus-----")
    print MySession.IConnStat()
    print ("--------- exit folgt-------------------# Beenden---------------")
    del MySession
    print ("---------- nach exit-------------------------------------------")

b)

Code: Alles auswählen

#!/usr/bin/env python
"""User Interface fuer ELSA ISDN4U ISDN-Router
Erlaubt, eine Verbindung zum Provider zu ermoeglichen oder zu sperren.
Die Sperrung verhindert, dass nach aussen gerichtete Pakete eine Verbindung aufbauen koennen.
Ferner wird der Verbindungsstatus angezeigt (Update alle 2 min)
Vor Benutzung muss die Adresse des ISDN4U (siehe Konstante 'HOST') und die
Telephonnummer des Providers in SetPass angepasst werden.
Author: Juergen Diel / J.Diel@NetCologne.de """

from Telnet_ISDN4U_4 import *
from Tkinter import * 
import thread, time

def TrennenUndVerriegeln():
    MySession.ISetPass("x")
    MySession.ISetTelNo("-")
    MySession.ITermConn()

def SetPass():
    MySession.ISetTelNo("0-222900")
    MySession.ISetPass(root.entry.get())

def UpdateStatus():
    try:
        while 1:
            MyStatus = strip(MyROSession.IConnStat(1))
            Status1.set(MyStatus)
            if MyStatus == "INTERNET":
                root.LabStat1.config(fg="red")
            elif MyStatus == "Ready":
                root.LabStat1.config(fg="blue")
            else:
                root.LabStat1.config(fg="purple")
            time.sleep(2)
    except:
        return


HOST = "192.16.150.1"    # IP-Adresse des ISDN4U
MySession = ISDN4U(HOST) # Eroeffnung der Telnet Session
MyROSession = ISDN4U(HOST) # ReadOnly Session fuer die Status-Abfrage

root=Tk()

root.Meldung=Label(root,text=MySession)   # Meldung des ISDN4U
root.Meldung.pack()

if MySession.ReadOnlyConn:              # Read Only ggf. anzeigen
    root.ROLabel=Label(root,text="READ ONLY",fg="red")
    root.ROLabel.pack()

Status1=StringVar(root)                  # Verbindungsstatus anzeigen
root.LabStat1=Label(root,textvariable=Status1)
root.LabStat1.pack()
Status1.set(MySession.IConnStat(1))
if Status1 == "INTERNET":
    root.LabStat1.config(fg="red")
else:
    root.LabStat1.config(fg="blue")
                                        # Feld fuer das Password
root.entry=Entry(root,width=30,show="*")
root.entry.pack()

##print "config:----------------------"
##print root.entry.config()
##print "keys():----------------------"
##print root.entry.keys()
##print "-----------------------------"

                                        # Button, um Password einzutragen
root.button=Button(root,text="Password eintragen",command=SetPass)
root.button.pack()

                                        # Button, um Verbindung zu trennen
root.button2=Button(root,text="Verbindung trennen \nund sperren",command=TrennenUndVerriegeln)
root.button2.pack()

root.button3=Button(root,text="Beenden",command=root.quit)
root.button3.pack()

MyThread = thread.start_new_thread(UpdateStatus,())

root.mainloop()

del MySession                           # Verbindung trennen
del MyROSession

Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Sieht interessant aus. Testen kann ich es natürlich ohne die entspr. Hardware nicht.
Ich hab' mal zur 'Bändigung' meines Zyxel-ISDN-Routers etwas ganz Ähnliches programmiert, allerdings mit Java/Swing und auf Socket-Ebene. Der RFC zu Telnet ist ja zum Glück eins der einfacheren. Was Du da mit telnetlib machst, werde ich mir auf jeden Fall mal näher angucken.
Jan
Antworten