]>
git.ipfire.org Git - ipfire.org.git/blob - src/backend/talk.py
ed0b1210bd50e773a43d1cd1c8fdc9eb494495e6
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_sip_channels(self
, account
):
38 res
= self
.db
.query("SELECT * FROM channels \
39 WHERE (direction = %s AND cid_num = %s) OR \
40 (direction = %s AND callee_num = %s) ORDER BY created_epoch",
41 "inbound", account
.sip_id
, "outbound", account
.sip_id
)
46 c
= Channel(self
, data
=row
)
51 def get_cdr_by_account(self
, account
, limit
=None):
52 res
= self
.db
.query("SELECT * FROM cdr \
53 WHERE (caller_id_number = %s AND bleg_uuid IS NOT NULL) \
54 OR (destination_number = %s AND bleg_uuid IS NULL) \
55 ORDER BY end_stamp DESC LIMIT %s", account
.sip_id
, account
.sip_id
, limit
)
58 yield CDR(self
, data
=row
)
61 class SIPRegistration(object):
62 def __init__(self
, freeswitch
, data
):
63 self
.freeswitch
= freeswitch
68 m
= re
.match(r
"Registered\(([A-Z]+)(\-NAT)?\)", self
.data
.status
)
75 return ipaddress
.ip_address(self
.data
.network_ip
)
78 def network_port(self
):
79 return self
.data
.network_port
83 return self
.data
.user_agent
85 def is_reachable(self
):
86 return self
.data
.ping_status
== "Reachable"
90 if self
.is_reachable() and self
.data
.ping_time
:
91 return self
.data
.ping_time
/ 1000.0
94 class Channel(object):
95 def __init__(self
, freeswitch
, data
):
96 self
.freeswitch
= freeswitch
101 return self
.freeswitch
.backend
105 return self
.data
.uuid
109 return self
.data
.direction
113 return self
.backend
.accounts
.get_by_sip_id(self
.caller_number
)
116 def caller_name(self
):
117 return self
.data
.cid_name
120 def caller_number(self
):
121 return self
.data
.cid_num
125 return self
.backend
.accounts
.get_by_sip_id(self
.callee_number
)
128 def callee_name(self
):
129 return self
.data
.callee_name
132 def callee_number(self
):
133 return self
.data
.callee_num
136 def called_number(self
):
137 return self
.data
.dest
140 def application(self
):
141 return self
.data
.application
144 def application_data(self
):
145 return self
.data
.application_data
149 return time
.time() - self
.data
.created_epoch
153 # We always assume a symmetric codec
155 self
.data
.write_codec
,
158 if self
.data
.write_rate
:
159 s
.append("%.0f kHz" % (int(self
.data
.write_rate
) / 1000.0))
161 if self
.data
.write_bit_rate
== "0":
164 s
.append("%.0f kBit/s" % (int(self
.data
.write_bit_rate
) / 1000.0))
177 transport_protocol
, key_negotiation
, cipher_suite
= self
.data
.secure
.split(":")
181 return "%s: %s" % (key_negotiation
.upper(), cipher_suite
.replace("_", "-"))
185 def __init__(self
, freeswitch
, data
):
186 self
.freeswitch
= freeswitch
191 return self
.freeswitch
.backend
195 if self
.data
.bleg_uuid
:
202 return self
.backend
.accounts
.get_by_phone_number(self
.data
.caller_id_number
)
205 def caller_number(self
):
206 return self
.data
.caller_id_number
210 return self
.backend
.accounts
.get_by_phone_number(self
.data
.destination_number
)
213 def callee_number(self
):
214 return self
.data
.destination_number
217 def time_start(self
):
218 return self
.data
.start_stamp
221 def time_answered(self
):
222 return self
.data
.answer_stamp
226 return self
.data
.duration
230 return self
.data
.write_codec
233 def user_agent(self
):
234 return self
.data
.user_agent
.replace("_", " ")
238 return sum((self
.data
.rtp_audio_in_raw_bytes
or 0, self
.data
.rtp_audio_out_raw_bytes
or 0))
242 return self
.data
.rtp_audio_in_mos
247 # Connect to FreeSWITCH
248 self
.freeswitch
= Freeswitch(self
.backend
)
253 def conferences(self
):
256 for no
in range(1, 10):
257 conference
= Conference(self
.backend
, no
)
258 conferences
.append(conference
)
262 def get_conference(self
, id):
263 for c
in self
.conferences
:
264 if not c
.sip_id
== id:
270 class Conference(Object
):
271 def __init__(self
, backend
, no
):
272 Object
.__init
__(self
, backend
)
275 def __cmp__(self
, other
):
276 return cmp(self
.no
, other
.no
)
280 return "IPFire Conference Room %s" % self
.no
284 return "%s" % (9000 + self
.no
)
288 return "%s@ipfire.org" % self
.sip_id
291 def participants(self
):
292 if not hasattr(self
, "_participants"):
293 self
._participants
= self
.backend
.talk
.get_ongoing_calls(sip_id
=self
.sip_id
)
295 return self
._participants