Skip to content

Commit

Permalink
Merge pull request #203 from tayler6000/bugfix/Issue-202
Browse files Browse the repository at this point in the history
Fix #202
  • Loading branch information
tayler6000 authored Jan 5, 2024
2 parents b873445 + ceaabd4 commit 666d5c1
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 66 deletions.
15 changes: 3 additions & 12 deletions pyVoIP/SIP/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,7 @@
from pyVoIP.SIP import message

__all__ = [
"SIPClient",
"SIPMessage",
"SIPMessageType",
"SIPParseError",
"InvalidAccountInfoError",
"error",
"client",
"message",
]

SIPClient = client.SIPClient
SIPMessage = message.SIPMessage
SIPStatus = message.SIPStatus
SIPMessageType = message.SIPMessageType
InvalidAccountInfoError = error.InvalidAccountInfoError
SIPParseError = error.SIPParseError
18 changes: 9 additions & 9 deletions pyVoIP/SIP/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ def gen_answer(
body = "v=0\r\n"
# TODO: Check IPv4/IPv6
body += (
f"o=pyVoIP {sess_id} {int(sess_id)+2} IN IP4 {self.bind_ip}\r\n"
f"o=pyVoIP {sess_id} {int(sess_id) + 2} IN IP4 {self.bind_ip}\r\n"
)
body += f"s=pyVoIP {pyVoIP.__version__}\r\n"
# TODO: Check IPv4/IPv6
Expand Down Expand Up @@ -781,7 +781,7 @@ def gen_invite(
# Generate body first for content length
body = "v=0\r\n"
body += (
f"o=pyVoIP {sess_id} {int(sess_id)+2} IN IP"
f"o=pyVoIP {sess_id} {int(sess_id) + 2} IN IP"
+ f"{self.nat.bind_ip.version} {self.bind_ip}\r\n"
)
body += f"s=pyVoIP {pyVoIP.__version__}\r\n"
Expand Down Expand Up @@ -1291,25 +1291,25 @@ def register(self) -> bool:
registered = self.__register()
if not registered:
debug("REGISTERATION FAILED")
self.registerFailures += 1
self.register_failures += 1
else:
self.phone._status = PhoneStatus.REGISTERED
self.registerFailures = 0
self.register_failures = 0

if self.registerFailures >= pyVoIP.REGISTER_FAILURE_THRESHOLD:
if self.register_failures >= pyVoIP.REGISTER_FAILURE_THRESHOLD:
debug("Too many registration failures, stopping.")
self.stop()
self.fatalCallback()
self.fatal_callback()
return False
self.__start_register_timer()

return registered
except BaseException as e:
debug(f"REGISTERATION ERROR: {e}")
self.registerFailures += 1
if self.registerFailures >= pyVoIP.REGISTER_FAILURE_THRESHOLD:
self.register_failures += 1
if self.register_failures >= pyVoIP.REGISTER_FAILURE_THRESHOLD:
self.stop()
self.fatalCallback()
self.fatal_callback()
return False
if isinstance(e, RetryRequiredError):
time.sleep(5)
Expand Down
8 changes: 2 additions & 6 deletions pyVoIP/VoIP/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
from pyVoIP.VoIP import status
from pyVoIP.VoIP import call, error, phone
from pyVoIP.VoIP import call, phone, status

InvalidRangeError = error.InvalidRangeError
InvalidStateError = error.InvalidStateError
NoPortsAvailableError = error.NoPortsAvailableError
CallState = call.CallState
PhoneStatus = status.PhoneStatus
VoIPCall = call.VoIPCall
PhoneStatus = status.PhoneStatus
VoIPPhone = phone.VoIPPhone
22 changes: 11 additions & 11 deletions pyVoIP/VoIP/call.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from enum import Enum
from pyVoIP import RTP, SIP
from pyVoIP import RTP
from pyVoIP.SIP.error import SIPParseError
from pyVoIP.SIP.message import SIPMessage, SIPMessageType, SIPStatus
from pyVoIP.VoIP.error import InvalidStateError
Expand Down Expand Up @@ -116,7 +116,7 @@ def init_outgoing_call(self, ms: Optional[Dict[int, RTP.PayloadType]]):
self.port = m
self.assignedPorts[m] = self.ms[m]

def init_incoming_call(self, request: SIP.SIPMessage):
def init_incoming_call(self, request: SIPMessage):
audio = []
video = []
for x in self.request.body["c"]:
Expand Down Expand Up @@ -214,7 +214,7 @@ def create_rtp_clients(
codecs: Dict[int, RTP.PayloadType],
ip: str,
port: int,
request: SIP.SIPMessage,
request: SIPMessage,
baseport: int,
) -> None:
for ii in range(len(request.body["c"])):
Expand Down Expand Up @@ -260,7 +260,7 @@ def gen_ms(self) -> Dict[int, Dict[int, RTP.PayloadType]]:

return m

def renegotiate(self, request: SIP.SIPMessage) -> None:
def renegotiate(self, request: SIPMessage) -> None:
m = self.gen_ms()
message = self.sip.gen_answer(
request, self.session_id, m, self.sendmode
Expand Down Expand Up @@ -373,7 +373,7 @@ def transfer(
return True
return False

def rtp_answered(self, request: SIP.SIPMessage) -> None:
def rtp_answered(self, request: SIPMessage) -> None:
for i in request.body["m"]:
if i["type"] == "video": # Disable Video
continue
Expand Down Expand Up @@ -406,7 +406,7 @@ def rtp_answered(self, request: SIP.SIPMessage) -> None:
self.request.headers["Contact"] = request.headers["Contact"]
self.request.headers["To"]["tag"] = request.headers["To"]["tag"]

def answered(self, request: SIP.SIPMessage) -> None:
def answered(self, request: SIPMessage) -> None:
if self.state == CallState.DIALING:
self.rtp_answered(request)
elif self.state != CallState.PROGRESS:
Expand All @@ -415,14 +415,14 @@ def answered(self, request: SIP.SIPMessage) -> None:
ack = self.phone.sip.gen_ack(request)
self.conn.send(ack)

def progress(self, request: SIP.SIPMessage) -> None:
def progress(self, request: SIPMessage) -> None:
if self.state != CallState.DIALING:
return
self.request = request
self.rtp_answered(request)
self.state = CallState.PROGRESS

def not_found(self, request: SIP.SIPMessage) -> None:
def not_found(self, request: SIPMessage) -> None:
if self.state != CallState.DIALING:
debug(
"TODO: 500 Error, received a not found response for a "
Expand All @@ -447,7 +447,7 @@ def not_found(self, request: SIP.SIPMessage) -> None:
# also resets all other warnings.
warnings.simplefilter("default")

def unavailable(self, request: SIP.SIPMessage) -> None:
def unavailable(self, request: SIPMessage) -> None:
if self.state != CallState.DIALING:
debug(
"TODO: 500 Error, received an unavailable response for a "
Expand All @@ -471,13 +471,13 @@ def unavailable(self, request: SIP.SIPMessage) -> None:
# also resets all other warnings.
warnings.simplefilter("default")

def ringing(self, request: SIP.SIPMessage) -> None:
def ringing(self, request: SIPMessage) -> None:
if self.state == CallState.RINGING:
self.deny()
else:
self.request = request

def busy(self, request: SIP.SIPMessage) -> None:
def busy(self, request: SIPMessage) -> None:
self.bye()

def deny(self) -> None:
Expand Down
50 changes: 26 additions & 24 deletions pyVoIP/VoIP/phone.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from pyVoIP import SIP, RTP
from pyVoIP import RTP
from pyVoIP.credentials import CredentialsManager
from pyVoIP.SIP.client import SIPClient
from pyVoIP.SIP.message import SIPMessage, SIPStatus
from pyVoIP.sock.sock import VoIPConnection
from pyVoIP.sock.transport import TransportMode
from pyVoIP.types import KEY_PASSWORD
Expand Down Expand Up @@ -42,7 +44,7 @@ class VoIPPhoneParameter:
rtp_port_low: Optional[int] = 10000
rtp_port_high: Optional[int] = 20000
call_class: Type[VoIPCall] = None
sip_class: Type[SIP.SIPClient] = None
sip_class: Type[SIPClient] = None


class VoIPPhone:
Expand All @@ -63,7 +65,7 @@ def __init__(self, voip_phone_parameter: VoIPPhoneParameter):
self.sip_class = (
self.voip_phone_parameter.sip_class is not None
and self.voip_phone_parameter.sip_class
or SIP.SIPClient
or SIPClient
)
# data defined in class
self._status = PhoneStatus.INACTIVE
Expand Down Expand Up @@ -100,10 +102,10 @@ def __init__(self, voip_phone_parameter: VoIPPhoneParameter):
)

def callback(
self, conn: VoIPConnection, request: SIP.SIPMessage
self, conn: VoIPConnection, request: SIPMessage
) -> Optional[str]:
# debug("Callback: "+request.summary())
if request.type == pyVoIP.SIP.SIPMessageType.REQUEST:
if request.type == pyVoIP.SIPMessageType.REQUEST:
# debug("This is a message")
if request.method == "INVITE":
self._callback_MSG_Invite(conn, request)
Expand All @@ -112,27 +114,27 @@ def callback(
elif request.method == "OPTIONS":
return self._callback_MSG_Options(request)
else:
if request.status == SIP.SIPStatus.OK:
if request.status == SIPStatus.OK:
self._callback_RESP_OK(request)
elif request.status == SIP.SIPStatus.NOT_FOUND:
elif request.status == SIPStatus.NOT_FOUND:
self._callback_RESP_NotFound(request)
elif request.status == SIP.SIPStatus.SERVICE_UNAVAILABLE:
elif request.status == SIPStatus.SERVICE_UNAVAILABLE:
self._callback_RESP_Unavailable(request)
elif request.status == SIP.SIPStatus.RINGING:
elif request.status == SIPStatus.RINGING:
self._callback_RESP_Ringing(request)
elif request.status == SIP.SIPStatus.SESSION_PROGRESS:
elif request.status == SIPStatus.SESSION_PROGRESS:
self._callback_RESP_Progress(request)
elif request.status == SIP.SIPStatus.BUSY_HERE:
elif request.status == SIPStatus.BUSY_HERE:
self._callback_RESP_Busy(request)
elif request.status == SIP.SIPStatus.REQUEST_TERMINATED:
elif request.status == SIPStatus.REQUEST_TERMINATED:
self._callback_RESP_Terminated(request)
return None

def get_status(self) -> PhoneStatus:
return self._status

def _callback_MSG_Invite(
self, conn: VoIPConnection, request: SIP.SIPMessage
self, conn: VoIPConnection, request: SIPMessage
) -> None:
call_id = request.headers["Call-ID"]
if self.call_class is None:
Expand Down Expand Up @@ -162,22 +164,22 @@ def _callback_MSG_Invite(
)
raise

def _callback_MSG_Bye(self, request: SIP.SIPMessage) -> None:
def _callback_MSG_Bye(self, request: SIPMessage) -> None:
debug("BYE recieved")
call_id = request.headers["Call-ID"]
if call_id not in self.calls:
return
self.calls[call_id].bye()

def _callback_MSG_Options(self, request: SIP.SIPMessage) -> str:
def _callback_MSG_Options(self, request: SIPMessage) -> str:
debug("Options recieved")
response = self.sip.gen_busy(request)
if self.call_class:
response = response.replace("486 Busy Here", "200 OK")
# TODO: Remove warning, implement RFC 3264
return response

def _callback_RESP_OK(self, request: SIP.SIPMessage) -> None:
def _callback_RESP_OK(self, request: SIPMessage) -> None:
debug("OK received")
call_id = request.headers["Call-ID"]
if call_id not in self.calls:
Expand All @@ -200,23 +202,23 @@ def _callback_RESP_OK(self, request: SIP.SIPMessage) -> None:
),
)

def _callback_RESP_Ringing(self, request: SIP.SIPMessage) -> None:
def _callback_RESP_Ringing(self, request: SIPMessage) -> None:
debug("Ringing received")
call_id = request.headers["Call-ID"]
if call_id not in self.calls:
debug("Unknown/No call")
return
self.calls[call_id].ringing(request)

def _callback_RESP_Progress(self, request: SIP.SIPMessage) -> None:
def _callback_RESP_Progress(self, request: SIPMessage) -> None:
debug("Session progress received")
call_id = request.headers["Call-ID"]
if call_id not in self.calls:
debug("Unknown/No call")
return
self.calls[call_id].progress(request)

def _callback_RESP_Busy(self, request: SIP.SIPMessage) -> None:
def _callback_RESP_Busy(self, request: SIPMessage) -> None:
debug("Busy received")
call_id = request.headers["Call-ID"]
if call_id not in self.calls:
Expand All @@ -226,7 +228,7 @@ def _callback_RESP_Busy(self, request: SIP.SIPMessage) -> None:
ack = self.sip.gen_ack(request)
self.sip.sendto(ack)

def _callback_RESP_Terminated(self, request: SIP.SIPMessage) -> None:
def _callback_RESP_Terminated(self, request: SIPMessage) -> None:
debug("Request terminated received")
call_id = request.headers["Call-ID"]
if call_id not in self.calls:
Expand All @@ -236,7 +238,7 @@ def _callback_RESP_Terminated(self, request: SIP.SIPMessage) -> None:
ack = self.sip.gen_ack(request)
self.sip.sendto(ack)

def _callback_RESP_NotFound(self, request: SIP.SIPMessage) -> None:
def _callback_RESP_NotFound(self, request: SIPMessage) -> None:
debug("Not Found recieved, invalid number called?")
call_id = request.headers["Call-ID"]
if call_id not in self.calls:
Expand All @@ -250,7 +252,7 @@ def _callback_RESP_NotFound(self, request: SIP.SIPMessage) -> None:
ack = self.sip.gen_ack(request)
self.sip.sendto(ack)

def _callback_RESP_Unavailable(self, request: SIP.SIPMessage) -> None:
def _callback_RESP_Unavailable(self, request: SIPMessage) -> None:
debug("Service Unavailable recieved")
call_id = request.headers["Call-ID"]
if call_id not in self.calls:
Expand All @@ -265,7 +267,7 @@ def _callback_RESP_Unavailable(self, request: SIP.SIPMessage) -> None:
self.sip.sendto(ack)

def _create_call(
self, conn: VoIPConnection, request: SIP.SIPMessage, sess_id: int
self, conn: VoIPConnection, request: SIPMessage, sess_id: int
) -> VoIPCall:
"""
Create VoIP call object. Should be separated to enable better
Expand Down Expand Up @@ -353,7 +355,7 @@ def message(
self, number: str, body: str, ctype: str = "text/plain"
) -> bool:
response = self.sip.message(number, body, ctype)
return response and response.status == SIP.SIPStatus.OK
return response and response.status == SIPStatus.OK

def request_port(self, blocking=True) -> int:
ports_available = [
Expand Down
2 changes: 1 addition & 1 deletion pyVoIP/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def debug(s, e=None):
# noqa because import will fail if debug is not defined
from pyVoIP.RTP import PayloadType # noqa: E402

SIPCompatibleMethods = ["INVITE", "ACK", "BYE", "CANCEL", "OPTIONS"]
SIPCompatibleMethods = ["INVITE", "ACK", "BYE", "CANCEL", "OPTIONS", "NOTIFY"]
SIPCompatibleVersions = ["SIP/2.0"]

RTPCompatibleVersions = [2]
Expand Down
2 changes: 1 addition & 1 deletion pyVoIP/sock/sock.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import TYPE_CHECKING, List, Optional, Tuple, Union
from pyVoIP.types import KEY_PASSWORD, SOCKETS
from pyVoIP.SIP import SIPMessage, SIPMessageType
from pyVoIP.SIP.message import SIPMessage, SIPMessageType
from pyVoIP.SIP.error import SIPParseError
from pyVoIP.networking.nat import NAT, AddressType
from pyVoIP.sock.transport import TransportMode
Expand Down
2 changes: 1 addition & 1 deletion tests/test_sip_requests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyVoIP.SIP import SIPMessage
from pyVoIP.SIP.message import SIPMessage
import pytest


Expand Down
2 changes: 1 addition & 1 deletion tests/test_sip_responses.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyVoIP.SIP import SIPMessage
from pyVoIP.SIP.message import SIPMessage
import pytest


Expand Down

0 comments on commit 666d5c1

Please sign in to comment.