tayler6000 / pyVoIP

Pure python VoIP/SIP/RTP library. Currently supports PCMA, PCMU, and telephone-event
https://pypi.org/project/pyVoIP/
GNU General Public License v3.0
235 stars 109 forks source link

call state real time #255

Open thiva7 opened 7 months ago

thiva7 commented 7 months ago

Hey ,

trying to get call state in "real time" but is not work

my example code

def answer(call): 
    try:
        print("call state is ", call.state)
        while True:
            if call.state == CallState.ENDED:
                print("Call ended")
            elif call.state == CallState.ANSWERED:
                print("Call answered")
            elif call.state == CallState.RINGING:
                print("Ringing")
            elif call.state == CallState.DIALING:
                print("Dialing")
            else:
                print("Call state is ", call.state)
            time.sleep(1)

when i make the call is print state ("Ringing") but even if i end the call without anwser from my phone is keep print Ringing , how i can make it to get current call state?

Thank you

s-manterola commented 7 months ago

try:

if str(call.state) == 'CallState.ENDED'

thiva7 commented 7 months ago

try:

if str(call.state) == 'CallState.ENDED'

not work , but what the point to check call.state as CallState.ENDED string?

mptsolutions commented 6 months ago

I also ran into this issue (v1.6.8). It seems that even though SIPCompatibleMethods includes CANCEL, the call state is not updated if CANCEL is received before the call is answered. I made three small changes in ./pyVoIP/pyVoIP/VoIP/VoIP.py which fixes it for me:

Added a new CANCELLED call state (line 43):

class CallState(Enum):
    DIALING = "DIALING"
    RINGING = "RINGING"
    ANSWERED = "ANSWERED"
    ENDED = "ENDED"
    CANCELLED = "CANCELLED"

Added an additional condition in the bye() function of the VoIPCall class to set the new CANCELLED state if bye() is called while the call state is RINGING (line 433):

def bye(self) -> None:
    if self.state == CallState.ANSWERED:
        for x in self.RTPClients:
            x.stop()
        self.state = CallState.ENDED
    elif self.state == CallState.RINGING:
        self.state = CallState.CANCELLED
    if self.request.headers["Call-ID"] in self.phone.calls:
        del self.phone.calls[self.request.headers["Call-ID"]]

Added a check for the CANCEL method to call bye() (line 531):

def callback(self, request: SIP.SIPMessage) -> None:
    # debug("Callback: "+request.summary())
    if request.type == pyVoIP.SIP.SIPMessageType.MESSAGE:
        # debug("This is a message")
        if request.method == "INVITE":
            self._callback_MSG_Invite(request)
        elif request.method == "BYE" or request.method == "CANCEL":
            self._callback_MSG_Bye(request)
    else:
        if request.status == SIP.SIPStatus.OK:
            self._callback_RESP_OK(request)
        elif request.status == SIP.SIPStatus.NOT_FOUND:
            self._callback_RESP_NotFound(request)
        elif request.status == SIP.SIPStatus.SERVICE_UNAVAILABLE:
            self._callback_RESP_Unavailable(request)