Pberndt V4

Direkt zum Inhalt springen


Quellcode recharge-o2-huawei-linux.py

Sourcecode

#!/usr/bin/python
# vim:fileencoding=utf-8
#
# Hacked by Phillip Berndt, www.pberndt.com
#
import gtk
import glib
import sys
import serial
import time

# Functions for PDU en-/decoding
def pduDecode(text):
    pad = lambda number: number + "0" * (8 - len(number))
    data = "".join([ pad("".join(reversed(bin(ord(c))[2:]))) for c in text.decode("hex") ])
    output = ""
    while len(data) >= 7:
        output += chr(int("".join(reversed(data[:7])), 2))
        data = data[7:]
    return output

def pduDecodeSMS(text):
    text = text[2 + int(text[:2], 16) * 2:] # Skip SMSC
    text = text[2:] # Skip info
    #text = text[2:] # Skip reference
    text = text[2 + (int(text[:2], 16) + int(text[:2], 16) % 2) + 2:] # Skip telephone number
    text = text[2:] # Skip protocol
    text = text[2:] # Skip data coding scheme
    text = text[14:] # Skip date
    text = text[2:] # Skip content length
    return pduDecode(text)

def pduEncode(text):
    pad = lambda number: number + "0" * (7 - len(number))
    binrep = ""
    while text:
        binrep += pad("".join(reversed(bin(ord(text[0]) & ~(1<<7))[2:])))
        text = text[1:]
    output = ""
    while len(binrep) >= 8:
        output += chr(int("".join(reversed(binrep[:8])), 2)).encode("hex")
        binrep = binrep[8:]
    if binrep:
        binrep = "".join(reversed(binrep))
        output += chr(int(binrep, 2)).encode("hex")
    return output.upper()

# Function to show „action pending“ message
def doPendingDialog():
    dlg = gtk.MessageDialog(wnd)
    dlg.set_markup("Waiting for response from the dongle")
    progress = gtk.ProgressBar()
    dlg.vbox.add(progress)
    def do_pulse(*w):
        if progress.get_window() is None:
            return False
        progress.pulse()
        return True
    glib.timeout_add(100, do_pulse)
    dlg.set_modal(True)
    dlg.show_all()
    return dlg

# Function to show error dialog
def doError(message):
    dlg = gtk.MessageDialog()
    dlg.set_markup(message)
    dlg.set_title("Error")
    dlg.add_button("Ok", gtk.RESPONSE_OK)
    dlg.run()
    sys.exit(1)

# Function to ask for sth
def doAsk(question):
    dlg = gtk.MessageDialog()
    dlg.set_markup(question)
    dlg.set_title("Question")
    entry = gtk.Entry()
    dlg.vbox.add(entry)
    entry.show()
    dlg.add_button("Ok", gtk.RESPONSE_OK)
    dlg.add_button("Cancel", gtk.RESPONSE_CANCEL)
    if dlg.run() == gtk.RESPONSE_CANCEL:
        dlg.destroy()
        return False
    retVal = entry.get_text()
    dlg.destroy()
    return retVal

def sendNWait(send):
    usbTTY.write(send + "\r\n")
    usbTTY.flush()
    globals()["pending"] = doPendingDialog()

def ttyReceivedCallback(source, condition):
    if condition != glib.IO_IN:
        doError("Connection to dongle lost")
    textInput = usbTTY.readline().strip()
    print textInput

    if "cmglMode" in globals():
        if textInput[0:2] == "AT": return True
        if textInput == "": return True
        if textInput[:5] == "+CMGL":
            msgNo = textInput[7:textInput.find(",")]
            appendText("Message no. " + msgNo + " follows:")
            return True
        if textInput == "OK":
            del globals()["cmglMode"]
            if "pending" in globals():
                globals()["pending"].destroy()
                del globals()["pending"]
            appendText("No further messages")
            appendText("")
        else:
            try:
                appendText(" * " + pduDecodeSMS(textInput))
            except:
                appendText("Did not understand " + textInput)
        return True
   
    if len(textInput) == 0 or textInput[0] != "+":
        # Not of interest for us
        return True

    if "pending" in globals():
        globals()["pending"].destroy()
        del globals()["pending"]

    if textInput[0:5] == "+CPIN":
        result = textInput[7:]
        if result != 'READY':
            pin = doAsk("The card asks for " + result)
            if pin == False:
                sys.exit(1)
            sendNWait('AT+CPIN="' + pin + '"')
            usbTTY.flush()
            def send_ask_pin(*w):
                usbTTY.write("AT+CPIN?\r\n")
                return False
            glib.timeout_add(300, send_ask_pin)
        else:
            appendText("Pin ok; dongle accessible")
            usbTTY.write("AT+CNUM\r\n")
            usbTTY.flush()
            usbTTY.write("AT+CMGF=0\r\n")
            usbTTY.flush()
            usbTTY.write("AT+CNMI=1,1,0,0,0\r\n")
        return True
   
    if textInput[0:5] == "+CUSD":
        textInput = textInput[textInput.find('"') + 1:textInput.rfind('"')]
        appendText(pduDecode(textInput))
        appendText("")
   
    if textInput[:5] == "+CNUM":
        textInput = textInput[10:]
        textInput = textInput[textInput.find('"') + 1:textInput.rfind('"')]
        appendText("Own phone number is " + textInput)
        appendText("")
   
    if textInput[:5] == "+CMTI":
        appendText("A new text message has arrived!")

    return True

# Open TTY
try:
    usbTTY = serial.Serial("/dev/ttyUSB3")
    glib.io_add_watch(usbTTY.fileno(), glib.IO_IN | glib.IO_ERR, ttyReceivedCallback)
except:
    doError("Failed to upen USB-tty. Make sure to have the dongle attached, <i>/dev/ttyUSB3</i> accessible " +
        "and the <i>usbserial</i> module loaded")


# Create main window
wnd = gtk.Window()
wnd.set_title("USB UMTS dongle recharge tool")
wnd.set_size_request(640, 240)
hbox = gtk.HBox()
vbox = gtk.VBox()
textView = gtk.TextView()
textView.set_editable(False)
textView.set_cursor_visible(False)
textView.set_size_request(440, 240)
textView.set_wrap_mode(gtk.WRAP_WORD)
buffer = textView.get_buffer()
def appendText(text):
    buffer.insert(buffer.get_end_iter(), text.strip() + "\n")
    textView.scroll_to_iter(buffer.get_end_iter(), 0.25)
checkButton = gtk.Button("Check balance")
def checkAction(widget):
    appendText("Sending request for balance check")
    sendNWait('AT+CUSD=1,"' + pduEncode("*101#") + '",15')
checkButton.connect("clicked", checkAction)
rechargeButton = gtk.Button("Recharge")
def rechargeAction(widget):
    code = doAsk("Enter recharge code:")
    if code == False: return
    appendText("Sending recharge-request")
    sendNWait('AT+CUSD=1,"' + pduEncode("*103*" + code + "#") + '",15')
rechargeButton.connect("clicked", rechargeAction)
readTextButton = gtk.Button("Read new text messages")
def readTextAction(widget):
    appendText("Receiving text messages")
    sendNWait("AT+CMGL")
    globals()["cmglMode"] = True
readTextButton.connect("clicked", readTextAction)
readAllTextButton = gtk.Button("Read all text messages")
def readAllTextAction(widget):
    appendText("Receiving text messages")
    sendNWait("AT+CMGL=4")
    globals()["cmglMode"] = True
readAllTextButton.connect("clicked", readAllTextAction)
deleteTextButton = gtk.Button("Delete a text message")
def deleteTextAction(widget):
    delw = doAsk("Enter message no. to be deleted")
    if delw == False: return True
    usbTTY.write("AT+CMGD=" + delw + "\r\n")
deleteTextButton.connect("clicked", deleteTextAction)
sendCusdButton = gtk.Button("Send CUSD")
def sendCusdAction(widget):
    cusd = doAsk("CUSD to send: (e.g. *101#)")
    if cusd == False:
        return
    sendNWait('AT+CUSD=1,"' + pduEncode(cusd) + '",15')
sendCusdButton.connect("clicked", sendCusdAction)
wnd.connect("hide", lambda *f: gtk.main_quit())
hbox.add(vbox)
hbox.pack_end(textView, padding=5)
vbox.pack_start(checkButton, False, padding=3)
vbox.pack_start(rechargeButton, False, padding=3)
vbox.pack_start(readTextButton, False, padding=3)
vbox.pack_start(readAllTextButton, False, padding=3)
vbox.pack_start(deleteTextButton, False, padding=3)
vbox.pack_start(sendCusdButton, False, padding=3)
wnd.add(hbox)
wnd.show_all()
usbTTY.write("ATZ\r\n")
sendNWait("AT+CPIN?")

# Run
gtk.main()

Download

Dateiname
recharge-o2-huawei-linux.py
Größe
6.92kb