]>
git.ipfire.org Git - ipfire.org.git/blob - src/backend/talk.py
10 from .misc
import Object
11 from .decorators
import *
13 class Freeswitch(Object
):
17 "host" : self
.settings
.get("freeswitch_database_host"),
18 "database" : self
.settings
.get("freeswitch_database_name", "freeswitch"),
19 "user" : self
.settings
.get("freeswitch_database_user"),
20 "password" : self
.settings
.get("freeswitch_database_password"),
23 return database
.Connection(**credentials
)
25 def get_sip_registrations(self
, sip_uri
):
26 logging
.debug("Fetching SIP registrations for %s" % sip_uri
)
28 user
, delim
, domain
= sip_uri
.partition("@")
30 res
= self
.db
.query("SELECT * FROM sip_registrations \
31 WHERE sip_user = %s AND sip_host = %s AND expires >= EXTRACT(epoch FROM CURRENT_TIMESTAMP) \
32 ORDER BY contact", user
, domain
)
35 yield SIPRegistration(self
, data
=row
)
37 def _get_channels(self
, query
, *args
):
38 res
= self
.db
.query(query
, *args
)
42 c
= Channel(self
, data
=row
)
47 def get_sip_channels(self
, account
):
48 return self
._get
_channels
("SELECT * FROM channels \
49 WHERE (direction = %s AND cid_num = %s) OR \
50 (direction = %s AND (callee_num = %s OR callee_num = ANY(%s))) \
51 AND callstate != %s ORDER BY created_epoch",
52 "inbound", account
.sip_id
, "outbound", account
.sip_id
,
53 account
._all
_telephone
_numbers
, "DOWN")
55 def get_conferences(self
):
56 res
= self
.db
.query("SELECT DISTINCT application_data AS handle FROM channels \
57 WHERE application = %s AND application_data LIKE %s \
58 ORDER BY application_data", "conference", "%%@ipfire.org")
62 c
= Conference(self
, row
.handle
)
67 def get_agent_status(self
, account
):
68 res
= self
.db
.get("SELECT status FROM agents \
69 WHERE name = %s", account
.sip_url
)
74 class SIPRegistration(object):
75 def __init__(self
, freeswitch
, data
):
76 self
.freeswitch
= freeswitch
81 m
= re
.match(r
"Registered\(([A-Z]+)(\-NAT)?\)", self
.data
.status
)
88 return ipaddress
.ip_address(self
.data
.network_ip
)
91 def network_port(self
):
92 return self
.data
.network_port
96 return self
.data
.user_agent
98 def is_reachable(self
):
99 return self
.data
.ping_status
== "Reachable"
103 if self
.is_reachable() and self
.data
.ping_time
:
104 return self
.data
.ping_time
/ 1000.0
107 class Channel(object):
108 def __init__(self
, freeswitch
, data
):
109 self
.freeswitch
= freeswitch
114 return self
.freeswitch
.backend
118 return self
.data
.uuid
122 return self
.data
.direction
126 return self
.backend
.accounts
.get_by_sip_id(self
.caller_number
)
129 def caller_name(self
):
130 return self
.data
.cid_name
133 def caller_number(self
):
134 return self
.data
.cid_num
138 return self
.backend
.accounts
.get_by_sip_id(self
.callee_number
)
141 def callee_name(self
):
142 return self
.data
.callee_name
145 def callee_number(self
):
146 return self
.data
.callee_num
149 def called_number(self
):
150 return self
.data
.dest
154 return self
.data
.callstate
157 def application(self
):
158 return self
.data
.application
161 def application_data(self
):
162 return self
.data
.application_data
165 def conference(self
):
166 if self
.application
== "conference":
167 return Conference(self
.freeswitch
, self
.application_data
)
171 return time
.time() - self
.data
.created_epoch
175 # We always assume a symmetric codec
176 return format_codec(self
.data
.write_codec
, int(self
.data
.write_rate
or 0), int(self
.data
.write_bit_rate
or 0))
187 transport_protocol
, key_negotiation
, cipher_suite
= self
.data
.secure
.split(":")
191 return "%s: %s" % (key_negotiation
.upper(), cipher_suite
.replace("_", "-"))
194 class Conference(object):
195 def __init__(self
, freeswitch
, handle
):
196 self
.freeswitch
= freeswitch
200 return "<%s %s>" % (self
.__class
__.__name
__, self
.handle
)
203 return len(self
.channels
)
205 def __eq__(self
, other
):
206 if isinstance(other
, self
.__class
__):
207 return self
.handle
== other
.handle
210 return iter(self
.channels
)
214 m
= re
.match(r
"conf(\d+)@", self
.handle
)
222 return 900 + self
.number
226 return "%s@ipfire.org" % self
.sip_id
229 def phone_numbers(self
):
231 "+4923636035%s" % self
.sip_id
,
236 return self
.freeswitch
._get
_channels
("SELECT * FROM channels \
237 WHERE application = %s AND application_data = %s \
238 ORDER BY created_epoch", "conference", self
.handle
)
243 # Connect to FreeSWITCH
244 self
.freeswitch
= Freeswitch(self
.backend
)
247 def conferences(self
):
248 return self
.freeswitch
.get_conferences()
251 def format_codec(name
, bit_rate
, bandwidth
):
260 s
.append("%.0f kHz" % (bit_rate
/ 1000.0))
263 s
.append("%.0f kBit/s" % (bandwidth
/ 1000.0))