# SimpleCapi.py
#
# Python implementation of the SimpleCapi interface, to be used
# to interface to the capiserver program.
# 
# Copyright (c) 2002 Matthias Kramm (kramm@quiss.org)
# 
# This program 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 2 of the License, or
# (at your option) any later version.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import socket

TIMEOUT = 0
CAPI_EVENT_HANGUP = 1
CAPI_EVENT_INCOMING = 2
CAPI_EVENT_DONE = 3
CAPI_EVENT_DIALTONE = 4
CAPI_EVENT_CONNECTED = 5

CAPI_REASON_TECHNICAL = 1
CAPI_REASON_BUSY = 2
CAPI_REASON_WRONGNUMBER = 3
CAPI_REASON_REJECTED = 4
CAPI_REASON_NOANSWER = 5

class CapiEvent:

    def __init__(this):
	this.msisdn=""
	this.called_msisdn=""
	this.id=0
	this.type=0
	this.jobid=0
	this.tone=0
	this.reason=0

class SimpleCapi:
    
    def _getline(this):
	a=""
	while 1:
	    b = this.sock.recv(1)
	    if ord(b)==10:
		break
	    if ord(b)!=13:
		a+=b
	return a

    def _readanswer(this, expected="ok"):
    	line = this._getline()
	l=len(expected)
	if(l <= len(line) and line[0:l]==expected):
		return line[l:]
	else:
		raise Error, "Wrong answer from server, expected: "+expected+", got: "+line

    def __init__(this, servername, serverport):
	sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	sock.connect((servername, serverport))
	this.sock = sock
	this.line = 0
	line = this._readanswer("open=")

    def setMSISDN(this, msisdn):
	this.sock.send("set msisdn "+msisdn+"\n")
	this.line = this._readanswer("ok=")

    def acceptCalls(this):
	this.sock.send("accept\n")
	this._readanswer("ok")

    def call(this, number, timeout="60"):
	this.sock.send("call "+number+" "+str(timeout)+"\n")
	return this._readanswer("ok=")

    def call_nonblock(this, number):
	this.sock.send("call_nonbclock "+number+"\n")
	return this._readanswer("ok=")

	#def put(this, filename, destfilename):
	#    this.sock.send("put "+filename+" "+destfilename+"\n")
	#    return this._readanswer("ok")
	#
	#def get(this, filename, destfilename):
	#    this.sock.send("get "+filename+" "+destfilename+"\n")
	#    return this._readanswer("ok")

    def delete(this, filename):
	this.sock.send("del "+filename+"\n")
        this._readanswer("ok")

    def beep(this, tones):
	this.sock.send("beep "+tones+"\n")
	this._readanswer("ok")

    def hold(this):
	this.sock.send("hold\n")
	return this._readanswer("ok=")

    def retrieve(this):
	this.sock.send("retrieve\n")
	return this._readanswer("ok=")

    def supplemental(this, name):
	this.sock.send("supplemental "+name+"\n")
	return this._readanswer("ok=")

    def play(this, filename):
	this.sock.send("play "+filename+"\n")
	return this._readanswer("ok=")

    def speak(this, text):
	this.sock.send("play "+text+"\n")
	return this._readanswer("ok=")

    def record(this, filename="recording.wav", length="60"):
	this.sock.send("record "+text+"\n")
	this.sock.send("record "+filename+" "+str(length)+"\n")
	return this._readanswer("ok=")

    def fax(this, filename, timeout="120"):
	this.sock.send("fax "+filename+" "+str(timeout)+"\n")
	return this._readanswer("ok=")

    def stop(this, jobid):
	this.sock.send("stop "+jobid+"\n")
	this._readanswer("ok")

    def listen(this, timeout="1"):
	this.sock.send("listen "+timeout+"\n")
	event=CapiEvent()
	event.msisdn=this._readanswer("msisdn=")
	event.called_msisdn=this._readanswer("called_msisdn=")
	event.id=int(this._readanswer("id="))
	event.type=int(this._readanswer("type="))
	event.jobid=int(this._readanswer("jobid="))
	event.tone=int(this._readanswer("tone="))
	event.reason=int(this._readanswer("reason="))
	this._readanswer("ok")
	return event

    def answer(this, event):
    	if type(event) == instance:
		# param "event" is the event itself
		this.sock.send("answer "+event.id+"\n")
	else:
		# param "event" is the eventid
		this.sock.send("answer "+event+"\n")
	return this._readanswer("ok=")

    def reject(this, event):
    	if type(event)==instance:
		# param "event" is the event itself
		this.sock.send("reject "+event.id+"\n")
	else:
		# param "event" is the eventid
		this.sock.send("reject "+event+"\n")
	this._readanswer("ok")

    def ignore(this, event):
    	if type(event)==instance:
		# param "event" is the event itself
		this.sock.send("ignore "+event.id+"\n")
	else:
		# param "event" is the eventid
		this.sock.send("ignore "+event+"\n")
	this._readanswer("ok")

    def forward(this, number):
	this.sock.send("forward "+number+"\n")
	return this._readanswer("ok=")

    def hangup(this):
	this.sock.send("hangup\n")
	this._readanswer("ok")

    def connect(this, capi2):
	this.sock.send("connect "+this.line+" "+capi2.line+"\n")
	this._readanswer("ok")

    def close(this):
	this.sock.send("close\n")
	this._readanswer("ok")

    def printEvent(this, event):
    	if event.type==TIMEOUT:
	    print "type:TIMEOUT"
    	if event.type==CAPI_EVENT_HANGUP:
	    print "type:HANGUP"
    	if event.type==CAPI_EVENT_INCOMING:
	    print "type:INCOMING"
    	if event.type==CAPI_EVENT_DONE:
	    print "type:DONE"
    	if event.type==CAPI_EVENT_DIALTONE:
	    print "type:DIALTONE"
    	if event.type==CAPI_EVENT_CONNECTED:
	    print "type:CONNECTED"
	print "msisdn:"+event.msisdn
	print "called_msisdn:"+event.called_msisdn
	print "id:"+str(event.id)
	if event.type == CAPI_EVENT_DONE:
	    print "jobid:"+str(event.jobid)
	if event.type == CAPI_EVENT_DIALTONE:
	    print "tone: %d %c"%(event.tone,event.tone)
	if event.type == CAPI_EVENT_HANGUP:
	    print "reason:".str(event.reason),
	    if event.reason==CAPI_REASON_TECHNICAL: print "(no answer)"
	    if event.reason==CAPI_REASON_BUSY: print "(busy)"
	    if event.reason==CAPI_REASON_WRONGNUMBER: print "(wrongnumber)"
	    if event.reason==CAPI_REASON_REJECTED: print "(rejected)"
	    if event.reason==CAPI_REASON_NOANSWER: print "(noanswer)"

