sippy 2.2.0__tar.gz → 2.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sippy-2.2.0/sippy.egg-info → sippy-2.2.1}/PKG-INFO +15 -4
- {sippy-2.2.0 → sippy-2.2.1}/README.md +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/setup.py +3 -2
- {sippy-2.2.0 → sippy-2.2.1}/sippy/B2BRoute.py +2 -2
- {sippy-2.2.0 → sippy-2.2.1}/sippy/CCEvents.py +32 -19
- {sippy-2.2.0 → sippy-2.2.1}/sippy/CLIManager.py +6 -2
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Core/EventDispatcher.py +1 -2
- sippy-2.2.1/sippy/Exceptions/RtpProxyError.py +30 -0
- sippy-2.2.1/sippy/Exceptions/SdpParseError.py +33 -0
- sippy-2.2.0/sippy/Exceptions/SipParseError.py → sippy-2.2.1/sippy/Exceptions/SipHandlingError.py +6 -16
- sippy-2.2.0/sippy/Exceptions/RtpProxyError.py → sippy-2.2.1/sippy/Exceptions/SipParseError.py +10 -13
- {sippy-2.2.0 → sippy-2.2.1}/sippy/External_command.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Math/recfilter.py +2 -2
- {sippy-2.2.0 → sippy-2.2.1}/sippy/MsgBody.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/MultipartMixBody.py +14 -3
- {sippy-2.2.0 → sippy-2.2.1}/sippy/RadiusAccounting.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Radius_client.py +1 -1
- sippy-2.2.1/sippy/Rtp_proxy/Client/__init__.py +1 -0
- sippy-2.2.1/sippy/Rtp_proxy/Client/local.py +53 -0
- sippy-2.2.1/sippy/Rtp_proxy/Client/net.py +42 -0
- sippy-2.2.1/sippy/Rtp_proxy/Client/stream.py +213 -0
- sippy-2.2.1/sippy/Rtp_proxy/Client/udp.py +224 -0
- sippy-2.2.1/sippy/Rtp_proxy/Cmd/__init__.py +1 -0
- sippy-2.2.1/sippy/Rtp_proxy/Cmd/sequencer.py +63 -0
- sippy-2.2.1/sippy/Rtp_proxy/Session/__init__.py +1 -0
- sippy-2.2.1/sippy/Rtp_proxy/Session/side.py +263 -0
- sippy-2.2.1/sippy/Rtp_proxy/Session/subcommand.py +117 -0
- sippy-2.2.1/sippy/Rtp_proxy/Session/subcommand_ice.py +101 -0
- sippy-2.2.1/sippy/Rtp_proxy/Session/update.py +121 -0
- sippy-2.2.1/sippy/Rtp_proxy/Session/webrtc.py +42 -0
- sippy-2.2.1/sippy/Rtp_proxy/__init__.py +1 -0
- sippy-2.2.1/sippy/Rtp_proxy/client.py +279 -0
- sippy-2.2.1/sippy/Rtp_proxy/cmd.py +224 -0
- sippy-2.2.1/sippy/Rtp_proxy/session.py +221 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SdpBody.py +5 -4
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipAddressHF.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipAuthorization.py +0 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipHeader.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipMsg.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipRegistrationAgent.py +4 -2
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipRequest.py +11 -2
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipTransactionManager.py +26 -22
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipWWWAuthenticate.py +2 -2
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Time/MonoTime.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UA.py +63 -40
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UaStateConnected.py +38 -54
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UaStateDead.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UaStateDisconnected.py +6 -9
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UaStateFailed.py +3 -6
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UacStateCancelling.py +7 -14
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UacStateIdle.py +11 -12
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UacStateRinging.py +29 -24
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UacStateTrying.py +36 -34
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UacStateUpdating.py +30 -32
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UasStateIdle.py +4 -7
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UasStateRinging.py +21 -38
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UasStateTrying.py +18 -39
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UasStateUpdating.py +29 -44
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Udp_server.py +14 -10
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Wss_server.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1}/sippy/XMPP_server.py +3 -3
- sippy-2.2.0/sippy/b2bua_radius.py → sippy-2.2.1/sippy/b2bua.py +15 -18
- {sippy-2.2.0 → sippy-2.2.1}/sippy/b2bua_simple.py +1 -1
- {sippy-2.2.0 → sippy-2.2.1/sippy.egg-info}/PKG-INFO +15 -4
- {sippy-2.2.0 → sippy-2.2.1}/sippy.egg-info/SOURCES.txt +21 -1
- sippy-2.2.1/sippy.egg-info/entry_points.txt +4 -0
- sippy-2.2.1/tests/test_Multipart.py +45 -0
- sippy-2.2.0/sippy.egg-info/entry_points.txt +0 -3
- {sippy-2.2.0 → sippy-2.2.1}/LICENSE +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/MANIFEST.in +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/pyproject.toml +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/requirements.txt +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/setup.cfg +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/B2BTransforms.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Core/Exceptions.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Core/__init__.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/ESipHeaderCSV.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/ESipHeaderIgnore.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Exceptions/__init__.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/FakeAccounting.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Math/__init__.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/MyConfigParser.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Network_server.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/RadiusAuthorisation.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SdpConnecton.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SdpGeneric.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SdpMedia.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SdpMediaDescription.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SdpOrigin.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Security/SipNonce.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Security/__init__.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Signal.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipAddress.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipAllow.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipAlso.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipCCDiversion.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipCSeq.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipCallId.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipCiscoGUID.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipConf.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipContact.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipContentLength.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipContentType.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipDiversion.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipExpires.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipFrom.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipGenericHF.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipLogger.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipMaxForwards.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipNumericHF.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipPAssertedIdentity.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipPath.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipProxyAuthenticate.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipProxyAuthorization.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipRAck.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipRSeq.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipReason.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipRecordRoute.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipReferTo.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipReferredBy.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipReplaces.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipResponse.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipRoute.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipServer.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipSupported.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipTo.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipURL.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipUserAgent.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipVia.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/SipWarning.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/StatefulProxy.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Time/Timeout.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Time/__init__.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/Time/clock_dtime.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/UaStateGeneric.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/__init__.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/dictionary +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy/misc.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy.egg-info/dependency_links.txt +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy.egg-info/requires.txt +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/sippy.egg-info/top_level.txt +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/tests/__init__.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/tests/test_B2BRoute.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/tests/test_B2BTransforms.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/tests/test_SdbBody.py +0 -0
- {sippy-2.2.0 → sippy-2.2.1}/tests/test_Udp_server.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: sippy
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: RFC3261 SIP Stack and Back-to-Back User Agent (B2BUA)
|
|
5
5
|
Home-page: http://www.b2bua.org/
|
|
6
6
|
Author: Sippy Software, Inc.
|
|
@@ -15,8 +15,19 @@ License-File: LICENSE
|
|
|
15
15
|
Requires-Dist: ElPeriodic>=1.1
|
|
16
16
|
Requires-Dist: pycryptodome
|
|
17
17
|
Requires-Dist: websockets
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
Dynamic: author
|
|
19
|
+
Dynamic: author-email
|
|
20
|
+
Dynamic: classifier
|
|
21
|
+
Dynamic: description
|
|
22
|
+
Dynamic: description-content-type
|
|
23
|
+
Dynamic: home-page
|
|
24
|
+
Dynamic: keywords
|
|
25
|
+
Dynamic: license
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
Dynamic: requires-dist
|
|
28
|
+
Dynamic: summary
|
|
29
|
+
|
|
30
|
+
[](https://github.com/sippy/b2bua/actions/workflows/python-wheels.yml?query=branch%3Amaster++)
|
|
20
31
|
|
|
21
32
|
# Sippy B2BUA
|
|
22
33
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://github.com/sippy/b2bua/actions/workflows/python-wheels.yml?query=branch%3Amaster++)
|
|
2
2
|
|
|
3
3
|
# Sippy B2BUA
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ with open("README.md", "r") as fh:
|
|
|
8
8
|
|
|
9
9
|
setup(
|
|
10
10
|
name = "sippy",
|
|
11
|
-
version = "2.2.
|
|
11
|
+
version = "2.2.1",
|
|
12
12
|
packages = find_packages(),
|
|
13
13
|
|
|
14
14
|
install_requires = requirements,
|
|
@@ -20,7 +20,8 @@ setup(
|
|
|
20
20
|
entry_points = {
|
|
21
21
|
'console_scripts': [
|
|
22
22
|
'b2bua_simple = sippy.b2bua_simple:main_func',
|
|
23
|
-
'b2bua_radius = sippy.
|
|
23
|
+
'b2bua_radius = sippy.b2bua:main_func',
|
|
24
|
+
'b2bua = sippy.b2bua:main_func',
|
|
24
25
|
],
|
|
25
26
|
},
|
|
26
27
|
|
|
@@ -82,7 +82,7 @@ class B2BRoute(object):
|
|
|
82
82
|
self.cli_set = cself.cli_set
|
|
83
83
|
self.params = dict(cself.params)
|
|
84
84
|
self.ainfo = cself.ainfo
|
|
85
|
-
if cself.extra_headers
|
|
85
|
+
if cself.extra_headers is not None:
|
|
86
86
|
self.extra_headers = tuple([x.getCopy() for x in cself.extra_headers])
|
|
87
87
|
return
|
|
88
88
|
route = sroute.split(';')
|
|
@@ -183,7 +183,7 @@ class B2BRoute(object):
|
|
|
183
183
|
if 'gt' in self.params:
|
|
184
184
|
timeout, skip = self.params['gt'].split(',', 1)
|
|
185
185
|
self.params['group_timeout'] = (int(timeout), rnum + int(skip))
|
|
186
|
-
if self.extra_headers
|
|
186
|
+
if self.extra_headers is not None:
|
|
187
187
|
self.extra_headers = self.extra_headers + tuple(pass_headers)
|
|
188
188
|
else:
|
|
189
189
|
self.extra_headers = tuple(pass_headers)
|
|
@@ -25,19 +25,21 @@
|
|
|
25
25
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
26
26
|
|
|
27
27
|
from sippy.Time.MonoTime import MonoTime
|
|
28
|
+
from sippy.SipHeader import SipHeader
|
|
29
|
+
from sippy.SipWarning import SipWarning
|
|
28
30
|
|
|
29
31
|
class CCEventGeneric(object):
|
|
30
32
|
data = None
|
|
31
33
|
name = None
|
|
32
34
|
rtime = None
|
|
33
35
|
origin = None
|
|
34
|
-
|
|
36
|
+
reason_rfc3326 = None
|
|
35
37
|
extra_headers = None
|
|
36
38
|
seq = 1
|
|
37
39
|
|
|
38
40
|
def __init__(self, data = None, rtime = None, origin = None):
|
|
39
41
|
self.data = data
|
|
40
|
-
if rtime
|
|
42
|
+
if rtime is None:
|
|
41
43
|
self.rtime = MonoTime()
|
|
42
44
|
else:
|
|
43
45
|
self.rtime = rtime
|
|
@@ -50,12 +52,20 @@ class CCEventGeneric(object):
|
|
|
50
52
|
|
|
51
53
|
def getCopy(self):
|
|
52
54
|
cself = self.__class__(self.data, self.rtime, self.origin)
|
|
53
|
-
if self.
|
|
54
|
-
cself.
|
|
55
|
-
if self.
|
|
56
|
-
cself.
|
|
55
|
+
if self.extra_headers is not None:
|
|
56
|
+
cself.extra_headers = tuple(x.getCopy() for x in self.extra_headers)
|
|
57
|
+
if self.reason_rfc3326 is not None:
|
|
58
|
+
cself.reason_rfc3326 = self.reason_rfc3326.getCopy()
|
|
57
59
|
return cself
|
|
58
60
|
|
|
61
|
+
def getExtraHeaders(self):
|
|
62
|
+
extra_headers = []
|
|
63
|
+
if self.extra_headers is not None:
|
|
64
|
+
extra_headers.extend(self.extra_headers)
|
|
65
|
+
if self.reason_rfc3326 is not None:
|
|
66
|
+
extra_headers.append(SipHeader(body = self.reason_rfc3326))
|
|
67
|
+
return tuple(extra_headers) if len(extra_headers) > 0 else None
|
|
68
|
+
|
|
59
69
|
def __str__(self):
|
|
60
70
|
return self.name
|
|
61
71
|
|
|
@@ -64,7 +74,7 @@ class CCEventTry(CCEventGeneric):
|
|
|
64
74
|
max_forwards = None
|
|
65
75
|
|
|
66
76
|
def getCopy(self):
|
|
67
|
-
cself =
|
|
77
|
+
cself = super().getCopy()
|
|
68
78
|
cself.max_forwards = self.max_forwards
|
|
69
79
|
return cself
|
|
70
80
|
|
|
@@ -75,35 +85,27 @@ class CCEventTry(CCEventGeneric):
|
|
|
75
85
|
|
|
76
86
|
class CCEventRing(CCEventGeneric):
|
|
77
87
|
name = 'CCEventRing'
|
|
78
|
-
pass
|
|
79
88
|
|
|
80
89
|
class CCEventPreConnect(CCEventGeneric):
|
|
81
90
|
name = 'CCEventPreConnect'
|
|
82
|
-
pass
|
|
83
91
|
|
|
84
92
|
class CCEventConnect(CCEventGeneric):
|
|
85
93
|
name = 'CCEventConnect'
|
|
86
|
-
pass
|
|
87
94
|
|
|
88
95
|
class CCEventUpdate(CCEventGeneric):
|
|
89
96
|
name = 'CCEventUpdate'
|
|
90
97
|
max_forwards = None
|
|
91
98
|
|
|
92
99
|
def getCopy(self):
|
|
93
|
-
cself =
|
|
100
|
+
cself = super().getCopy()
|
|
94
101
|
cself.max_forwards = self.max_forwards
|
|
95
102
|
return cself
|
|
96
103
|
|
|
97
104
|
class CCEventInfo(CCEventGeneric):
|
|
98
105
|
name = 'CCEventInfo'
|
|
99
|
-
pass
|
|
100
106
|
|
|
101
107
|
class CCEventDisconnect(CCEventGeneric):
|
|
102
108
|
name = 'CCEventDisconnect'
|
|
103
|
-
pass
|
|
104
|
-
|
|
105
|
-
from sippy.SipHeader import SipHeader
|
|
106
|
-
from sippy.SipWarning import SipWarning
|
|
107
109
|
|
|
108
110
|
class CCEventFail(CCEventGeneric):
|
|
109
111
|
name = 'CCEventFail'
|
|
@@ -111,14 +113,25 @@ class CCEventFail(CCEventGeneric):
|
|
|
111
113
|
warning = None
|
|
112
114
|
|
|
113
115
|
def getCopy(self):
|
|
114
|
-
cself =
|
|
115
|
-
if self.challenges
|
|
116
|
+
cself = super().getCopy()
|
|
117
|
+
if self.challenges is not None:
|
|
116
118
|
cself.challenges = [x.getCopy() for x in self.challenges]
|
|
119
|
+
if self.warning is not None:
|
|
120
|
+
cself.warning = self.warning.getCopy()
|
|
117
121
|
return cself
|
|
118
122
|
|
|
123
|
+
def getExtraHeaders(self):
|
|
124
|
+
extra_headers = []
|
|
125
|
+
if (eh := super().getExtraHeaders()) is not None:
|
|
126
|
+
extra_headers.extend(eh)
|
|
127
|
+
if self.challenges is not None:
|
|
128
|
+
extra_headers.extend(self.challenges)
|
|
129
|
+
if self.warning is not None:
|
|
130
|
+
extra_headers.append(self.warning)
|
|
131
|
+
return tuple(extra_headers) if len(extra_headers) > 0 else None
|
|
132
|
+
|
|
119
133
|
def setWarning(self, eistr):
|
|
120
134
|
self.warning = SipHeader(body = SipWarning(text = eistr))
|
|
121
135
|
|
|
122
136
|
class CCEventRedirect(CCEventGeneric):
|
|
123
137
|
name = 'CCEventRedirect'
|
|
124
|
-
pass
|
|
@@ -169,7 +169,11 @@ class _CLIManager_w(Thread):
|
|
|
169
169
|
self.wbuffer = None
|
|
170
170
|
self.w_available.release()
|
|
171
171
|
while True:
|
|
172
|
-
|
|
172
|
+
try:
|
|
173
|
+
res = self.clientsock.send(wbuffer)
|
|
174
|
+
except BrokenPipeError:
|
|
175
|
+
self.clim = None
|
|
176
|
+
return
|
|
173
177
|
if res == len(wbuffer):
|
|
174
178
|
break
|
|
175
179
|
if res > 0:
|
|
@@ -276,7 +280,7 @@ class CLIManager(object):
|
|
|
276
280
|
self.clientsock.shutdown(socket.SHUT_RDWR)
|
|
277
281
|
except Exception as e:
|
|
278
282
|
if not isinstance(e, socket.error) or e.errno != ENOTCONN: # pylint: disable=no-member
|
|
279
|
-
dump_exception('self.clientsock.shutdown(socket.SHUT_RDWR)')
|
|
283
|
+
dump_exception('CLIManager: unhandled exception in self.clientsock.shutdown(socket.SHUT_RDWR)')
|
|
280
284
|
self.clientsock.close()
|
|
281
285
|
self.wthr = None
|
|
282
286
|
self.rthr = None
|
|
@@ -255,8 +255,7 @@ class EventDispatcher2(Singleton):
|
|
|
255
255
|
self.bands.insert(0, fb)
|
|
256
256
|
self.endloop = False
|
|
257
257
|
self.last_ts = MonoTime()
|
|
258
|
-
if timeout
|
|
259
|
-
etime = self.last_ts.getOffsetCopy(timeout)
|
|
258
|
+
etime = None if timeout is None else self.last_ts.getOffsetCopy(timeout)
|
|
260
259
|
while True:
|
|
261
260
|
if len(self.signals_pending) > 0:
|
|
262
261
|
self.dispatchSignals()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Copyright (c) 2023 Sippy Software, Inc. All rights reserved.
|
|
2
|
+
#
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
|
6
|
+
# are permitted provided that the following conditions are met:
|
|
7
|
+
#
|
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
# list of conditions and the following disclaimer.
|
|
10
|
+
#
|
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
# this list of conditions and the following disclaimer in the documentation and/or
|
|
13
|
+
# other materials provided with the distribution.
|
|
14
|
+
#
|
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
16
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
17
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
19
|
+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
20
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
21
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
22
|
+
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
23
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
24
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
25
|
+
|
|
26
|
+
from .SipHandlingError import SipHandlingError
|
|
27
|
+
|
|
28
|
+
class RtpProxyError(SipHandlingError):
|
|
29
|
+
code = 502
|
|
30
|
+
msg = 'Bad Gateway'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Copyright (c) 20012-2023 Sippy Software, Inc. All rights reserved.
|
|
2
|
+
#
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
|
6
|
+
# are permitted provided that the following conditions are met:
|
|
7
|
+
#
|
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
# list of conditions and the following disclaimer.
|
|
10
|
+
#
|
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
# this list of conditions and the following disclaimer in the documentation and/or
|
|
13
|
+
# other materials provided with the distribution.
|
|
14
|
+
#
|
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
16
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
17
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
19
|
+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
20
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
21
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
22
|
+
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
23
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
24
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
25
|
+
|
|
26
|
+
from .SipHandlingError import SipHandlingError
|
|
27
|
+
from .RtpProxyError import RtpProxyError
|
|
28
|
+
|
|
29
|
+
class SdpParseError(SipHandlingError):
|
|
30
|
+
code = 488
|
|
31
|
+
msg = 'Not Acceptable Here'
|
|
32
|
+
|
|
33
|
+
SdpHandlingErrors = (SdpParseError, RtpProxyError)
|
sippy-2.2.0/sippy/Exceptions/SipParseError.py → sippy-2.2.1/sippy/Exceptions/SipHandlingError.py
RENAMED
|
@@ -24,33 +24,23 @@
|
|
|
24
24
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
25
25
|
|
|
26
26
|
from sippy.SipReason import SipReason
|
|
27
|
-
from sippy.SipHeader import SipHeader
|
|
28
27
|
|
|
29
|
-
class
|
|
28
|
+
class SipHandlingError(Exception):
|
|
29
|
+
code: int
|
|
30
|
+
msg: str
|
|
30
31
|
sip_response = None
|
|
31
32
|
arg = None
|
|
32
33
|
|
|
33
|
-
def __init__(self, arg
|
|
34
|
+
def __init__(self, arg):
|
|
34
35
|
super().__init__()
|
|
35
36
|
self.arg = arg
|
|
36
|
-
self.sip_response = sip_response
|
|
37
37
|
|
|
38
38
|
def __str__(self):
|
|
39
39
|
return str(self.arg)
|
|
40
40
|
|
|
41
|
-
def getResponse(self, req=None):
|
|
42
|
-
return self.sip_response
|
|
43
|
-
|
|
44
|
-
class SdpParseError(SipParseError):
|
|
45
|
-
code = 488
|
|
46
|
-
msg = 'Not Acceptable Here'
|
|
47
41
|
def getResponse(self, req):
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
resp = req.genResponse(self.code, self.msg)
|
|
51
|
-
if (reason:=self.getReason()) is not None:
|
|
52
|
-
rsh = SipHeader(body = reason)
|
|
53
|
-
resp.appendHeader(rsh)
|
|
42
|
+
reason = self.getReason()
|
|
43
|
+
resp = req.genResponse(self.code, self.msg, ext_reason = reason)
|
|
54
44
|
return resp
|
|
55
45
|
|
|
56
46
|
def getReason(self):
|
sippy-2.2.0/sippy/Exceptions/RtpProxyError.py → sippy-2.2.1/sippy/Exceptions/SipParseError.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2023 Sippy Software, Inc. All rights reserved.
|
|
1
|
+
# Copyright (c) 20012-2023 Sippy Software, Inc. All rights reserved.
|
|
2
2
|
#
|
|
3
3
|
# All rights reserved.
|
|
4
4
|
#
|
|
@@ -23,19 +23,16 @@
|
|
|
23
23
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
24
24
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
25
25
|
|
|
26
|
-
from
|
|
26
|
+
from .SipHandlingError import SipHandlingError
|
|
27
27
|
|
|
28
|
-
class
|
|
28
|
+
class SipParseError(SipHandlingError):
|
|
29
29
|
sip_response = None
|
|
30
|
-
arg = None
|
|
31
|
-
code = 502
|
|
32
|
-
msg = 'Bad Gateway'
|
|
33
|
-
def __init__(self, arg):
|
|
34
|
-
super().__init__()
|
|
35
|
-
self.arg = arg
|
|
36
30
|
|
|
37
|
-
def
|
|
38
|
-
|
|
31
|
+
def __init__(self, arg, sip_response = None):
|
|
32
|
+
super().__init__(arg)
|
|
33
|
+
self.sip_response = sip_response
|
|
39
34
|
|
|
40
|
-
def
|
|
41
|
-
|
|
35
|
+
def getResponse(self, req):
|
|
36
|
+
if self.sip_response is not None:
|
|
37
|
+
return self.sip_response
|
|
38
|
+
return super().getResponse(req)
|
|
@@ -69,7 +69,7 @@ class _Worker(Thread):
|
|
|
69
69
|
wi.result_callback = None
|
|
70
70
|
wi.callback_parameters = None
|
|
71
71
|
continue
|
|
72
|
-
batch = [x + b'\n' for x in wi.data]
|
|
72
|
+
batch = [x.encode() + b'\n' for x in wi.data]
|
|
73
73
|
batch.append(b'\n')
|
|
74
74
|
pipe.stdin.writelines(batch)
|
|
75
75
|
pipe.stdin.flush()
|
|
@@ -38,7 +38,7 @@ class recfilter(object):
|
|
|
38
38
|
b = None
|
|
39
39
|
|
|
40
40
|
def __init__(self, fcoef, initval):
|
|
41
|
-
#print
|
|
41
|
+
#print('recfilter::init()')
|
|
42
42
|
self.lastval = float(initval)
|
|
43
43
|
self.a = 1.0 - float(fcoef)
|
|
44
44
|
self.b = float(fcoef)
|
|
@@ -49,5 +49,5 @@ class recfilter(object):
|
|
|
49
49
|
|
|
50
50
|
class recfilter_ts(local, recfilter):
|
|
51
51
|
def __init__(self, *args):
|
|
52
|
-
#print
|
|
52
|
+
#print('recfilter_ts::init()')
|
|
53
53
|
recfilter.__init__(self, *args)
|
|
@@ -39,11 +39,22 @@ class MultipartMixBody():
|
|
|
39
39
|
assert bparts[-1].strip() == '--'
|
|
40
40
|
parts = [p.lstrip() for p in bparts[1:-1]]
|
|
41
41
|
self.parts = []
|
|
42
|
+
self.part_headers = []
|
|
42
43
|
for sect in parts:
|
|
43
|
-
|
|
44
|
-
ct =
|
|
44
|
+
headers = []
|
|
45
|
+
ct = None
|
|
46
|
+
headersect, sect = sect.split('\r\n\r\n', 1)
|
|
47
|
+
# parse sub headers
|
|
48
|
+
for hl in headersect.split('\r\n'):
|
|
49
|
+
h = SipHeader(hl)
|
|
50
|
+
if h.name == "content-type":
|
|
51
|
+
ct = h.getBody()
|
|
52
|
+
else:
|
|
53
|
+
headers.append(h)
|
|
54
|
+
# add part
|
|
45
55
|
sect = MsgBody(sect, ct)
|
|
46
56
|
self.parts.append(sect)
|
|
57
|
+
self.part_headers.append(headers)
|
|
47
58
|
self.boundary = ctype.params["boundary"]
|
|
48
59
|
|
|
49
60
|
def __str__(self):
|
|
@@ -67,5 +78,5 @@ class MultipartMixBody():
|
|
|
67
78
|
cself.boundary = self.boundary
|
|
68
79
|
return cself
|
|
69
80
|
|
|
70
|
-
if
|
|
81
|
+
if 'MsgBody' not in globals():
|
|
71
82
|
from sippy.MsgBody import MsgBody
|
|
@@ -158,7 +158,7 @@ class RadiusAccounting(object):
|
|
|
158
158
|
if self.user_agent != None:
|
|
159
159
|
attributes.append(('h323-ivr-out', 'sip_ua:' + self.user_agent))
|
|
160
160
|
if self.p1xx_ts != None:
|
|
161
|
-
attributes.append(('Acct-Delay-Time', round(self.p1xx_ts)))
|
|
161
|
+
attributes.append(('Acct-Delay-Time', round(self.p1xx_ts.realt)))
|
|
162
162
|
if self.p100_ts != None:
|
|
163
163
|
attributes.append(('provisional-timepoint', self.ftime(self.p100_ts.realt)))
|
|
164
164
|
pattributes = ['%-32s = \'%s\'\n' % (x[0], str(x[1])) for x in attributes]
|
|
@@ -68,7 +68,7 @@ class Radius_client(External_command):
|
|
|
68
68
|
return
|
|
69
69
|
nav = []
|
|
70
70
|
for av in result[:-1]:
|
|
71
|
-
a, v = [x.strip() for x in av.split(' = ', 1)]
|
|
71
|
+
a, v = [x.strip() for x in av.decode().split(' = ', 1)]
|
|
72
72
|
v = v.strip('\'')
|
|
73
73
|
if (a == 'Cisco-AVPair' or a in self._cisco_vsa_names):
|
|
74
74
|
t = v.split('=', 1)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Copyright (c) 2003-2005 Maxim Sobolev. All rights reserved.
|
|
2
|
+
# Copyright (c) 2006-2014 Sippy Software, Inc. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
|
7
|
+
# are permitted provided that the following conditions are met:
|
|
8
|
+
#
|
|
9
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
# list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
# this list of conditions and the following disclaimer in the documentation and/or
|
|
14
|
+
# other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
17
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
18
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
19
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
20
|
+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
21
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
22
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
23
|
+
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
24
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
25
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
|
|
27
|
+
from sippy.Rtp_proxy.Client.stream import Rtp_proxy_client_stream
|
|
28
|
+
|
|
29
|
+
import socket
|
|
30
|
+
|
|
31
|
+
class Rtp_proxy_client_local(Rtp_proxy_client_stream):
|
|
32
|
+
is_local = True
|
|
33
|
+
|
|
34
|
+
def __init__(self, global_config, address = '/var/run/rtpproxy.sock', \
|
|
35
|
+
bind_address = None, nworkers = 1):
|
|
36
|
+
Rtp_proxy_client_stream.__init__(self, global_config = global_config, \
|
|
37
|
+
address = address, bind_address = bind_address, nworkers = nworkers, \
|
|
38
|
+
family = socket.AF_UNIX)
|
|
39
|
+
|
|
40
|
+
if __name__ == '__main__':
|
|
41
|
+
from sippy.Core.EventDispatcher import ED2
|
|
42
|
+
class robj(object):
|
|
43
|
+
rval = None
|
|
44
|
+
r = robj()
|
|
45
|
+
def display(res, ro, arg):
|
|
46
|
+
print(res, arg)
|
|
47
|
+
ro.rval = (res, arg)
|
|
48
|
+
ED2.breakLoop()
|
|
49
|
+
rc = Rtp_proxy_client_local({'_sip_address':'1.2.3.4'})
|
|
50
|
+
rc.send_command('VF 123456', display, r, 'abcd')
|
|
51
|
+
ED2.loop()
|
|
52
|
+
rc.shutdown()
|
|
53
|
+
assert(r.rval == ('0', 'abcd'))
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Copyright (c) 2016 Sippy Software, Inc. All rights reserved.
|
|
2
|
+
#
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
|
6
|
+
# are permitted provided that the following conditions are met:
|
|
7
|
+
#
|
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
# list of conditions and the following disclaimer.
|
|
10
|
+
#
|
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
# this list of conditions and the following disclaimer in the documentation and/or
|
|
13
|
+
# other materials provided with the distribution.
|
|
14
|
+
#
|
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
16
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
17
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
19
|
+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
20
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
21
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
22
|
+
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
23
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
24
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
25
|
+
|
|
26
|
+
from socket import getaddrinfo, SOCK_DGRAM, AF_INET, AF_INET6
|
|
27
|
+
|
|
28
|
+
class Rtp_proxy_client_net(object):
|
|
29
|
+
sock_type = None # Set me in superclass!
|
|
30
|
+
|
|
31
|
+
def getdestbyaddr(self, address, af):
|
|
32
|
+
#print('getaddrinfo', address[0], address[1], af, self.sock_type)
|
|
33
|
+
if af == AF_INET6 and address[0].startswith('['):
|
|
34
|
+
return address
|
|
35
|
+
ainfo = getaddrinfo(address[0], address[1], af, self.sock_type)
|
|
36
|
+
amatch = [x[4] for x in ainfo if x[0] == af]
|
|
37
|
+
if len(amatch) == 0:
|
|
38
|
+
raise Exception('no match for the %s in AF %s' % (address, af))
|
|
39
|
+
amatch = amatch[0]
|
|
40
|
+
if af == AF_INET6:
|
|
41
|
+
return (('[%s]' % amatch[0], amatch[1]))
|
|
42
|
+
return ((amatch[0], amatch[1]))
|