|
|
@ -1,4 +1,5 @@ |
|
|
|
import socket |
|
|
|
import socket |
|
|
|
|
|
|
|
import threading |
|
|
|
import pdb |
|
|
|
import pdb |
|
|
|
|
|
|
|
|
|
|
|
class LinphoneEvent(): |
|
|
|
class LinphoneEvent(): |
|
|
@ -16,19 +17,20 @@ class LinphoneCommunicationSocket(): |
|
|
|
self.socket_path = lp_socket |
|
|
|
self.socket_path = lp_socket |
|
|
|
self.socket = socket.socket(socket.AF_UNIX) |
|
|
|
self.socket = socket.socket(socket.AF_UNIX) |
|
|
|
self.socket.connect(self.socket_path) |
|
|
|
self.socket.connect(self.socket_path) |
|
|
|
|
|
|
|
self.socket_lock = threading.Lock() |
|
|
|
|
|
|
|
|
|
|
|
def send_command(self, command, blocking=True): |
|
|
|
def send_command(self, command, blocking=True): |
|
|
|
|
|
|
|
with self.socket_lock: |
|
|
|
self.socket.send(command.encode("ascii")) |
|
|
|
self.socket.send(command.encode("ascii")) |
|
|
|
|
|
|
|
return self._await_answer() |
|
|
|
|
|
|
|
|
|
|
|
def register(self, identity, proxy_address, password = "NULL", userid = "NULL", realm = "NULL", parameters = None): |
|
|
|
def register(self, identity, proxy_address, password = "NULL", userid = "NULL", realm = "NULL", parameters = None): |
|
|
|
self.socket.send(("register {identity} {proxy_address} {password} {userid} {realm} {parameters}".format(identity=identity, proxy_address=proxy_address, password=password, userid=userid, realm=realm, parameters="" if parameters else parameters)).encode("ascii")) |
|
|
|
answer = self.send_command(("register {identity} {proxy_address} {password} {userid} {realm} {parameters}".format(identity=identity, proxy_address=proxy_address, password=password, userid=userid, realm=realm, parameters="" if parameters else parameters))) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
return int(answer["data"][0].split(":", 1)[1].strip()) #id of newly registered account |
|
|
|
return int(answer["data"][0].split(":", 1)[1].strip()) #id of newly registered account |
|
|
|
|
|
|
|
|
|
|
|
def register_status(self, account_id=None): |
|
|
|
def register_status(self, account_id=None): |
|
|
|
self.socket.send(("register-status {account_id}".format(account_id="ALL" if account_id == None else account_id)).encode("ascii")) |
|
|
|
answer = self.send_command(("register-status {account_id}".format(account_id="ALL" if account_id == None else account_id))) |
|
|
|
accounts = [] |
|
|
|
accounts = [] |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
for acc_idx in range(0, len(answer["data"]), 2): |
|
|
|
for acc_idx in range(0, len(answer["data"]), 2): |
|
|
|
acc_id = int(answer["data"][acc_idx].split(":", 1)[1].strip()) |
|
|
|
acc_id = int(answer["data"][acc_idx].split(":", 1)[1].strip()) |
|
|
@ -39,9 +41,8 @@ class LinphoneCommunicationSocket(): |
|
|
|
return accounts |
|
|
|
return accounts |
|
|
|
|
|
|
|
|
|
|
|
def register_info(self, account_id=None): |
|
|
|
def register_info(self, account_id=None): |
|
|
|
self.socket.send(("register-info {account_id}".format(account_id="ALL" if account_id == None else account_id)).encode("ascii")) |
|
|
|
answer = self.send_command(("register-info {account_id}".format(account_id="ALL" if account_id == None else account_id))) |
|
|
|
accounts = [] |
|
|
|
accounts = [] |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
for acc_idx in range(0, len(answer["data"]), 4): |
|
|
|
for acc_idx in range(0, len(answer["data"]), 4): |
|
|
|
acc_id = int(answer["data"][acc_idx+0].split(":", 1)[1].strip()) |
|
|
|
acc_id = int(answer["data"][acc_idx+0].split(":", 1)[1].strip()) |
|
|
@ -54,49 +55,42 @@ class LinphoneCommunicationSocket(): |
|
|
|
return accounts |
|
|
|
return accounts |
|
|
|
|
|
|
|
|
|
|
|
def answer(self, call_id=None): |
|
|
|
def answer(self, call_id=None): |
|
|
|
self.socket.send(("answer {call_id}".format(call_id="" if call_id == None else call_id)).encode("ascii")) |
|
|
|
answer = self.send_command(("answer {call_id}".format(call_id="" if call_id == None else call_id))) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
return True |
|
|
|
return True |
|
|
|
else: |
|
|
|
else: |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
|
|
|
|
|
|
|
|
def terminate(self, call_id=None): |
|
|
|
def terminate(self, call_id=None): |
|
|
|
self.socket.send(("terminate {call_id}".format(call_id="" if call_id == None else call_id)).encode("ascii")) |
|
|
|
answer = self.send_command(("terminate {call_id}".format(call_id="" if call_id == None else call_id))) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
return True |
|
|
|
return True |
|
|
|
else: |
|
|
|
else: |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
|
|
|
|
|
|
|
|
def call(self, sip_address): |
|
|
|
def call(self, sip_address): |
|
|
|
self.socket.send("call {sip_address}".format(sip_address=sip_address).encode("ascii")) |
|
|
|
answer = self.send_command("call {sip_address}".format(sip_address=sip_address)) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
return answer["data"][0].split(":", 1)[1].strip() |
|
|
|
return answer["data"][0].split(":", 1)[1].strip() |
|
|
|
else: |
|
|
|
else: |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
|
|
|
|
|
|
|
|
def call_mute(self, mute=True): |
|
|
|
def call_mute(self, mute=True): |
|
|
|
self.socket.send("call-mute {mute}".format(mute="1" if mute else "0").encode("ascii")) |
|
|
|
answer = self.send_command("call-mute {mute}".format(mute="1" if mute else "0")) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
return True |
|
|
|
return True |
|
|
|
else: |
|
|
|
else: |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
|
|
|
|
|
|
|
|
def call_pause(self, call_id): |
|
|
|
def call_pause(self, call_id): |
|
|
|
self.socket.send("call-pause {call_id}".format(call_id=call_id).encode("ascii")) |
|
|
|
answer = self.send_command("call-pause {call_id}".format(call_id=call_id)) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
return True |
|
|
|
return True |
|
|
|
else: |
|
|
|
else: |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
|
|
|
|
|
|
|
|
def call_status(self, call_id): |
|
|
|
def call_status(self, call_id): |
|
|
|
self.socket.send("call-status {call_id}".format(call_id=call_id).encode("ascii")) |
|
|
|
answer = self.send_command("call-status {call_id}".format(call_id=call_id)) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
data = answer["data"] |
|
|
|
data = answer["data"] |
|
|
|
status = { |
|
|
|
status = { |
|
|
@ -110,9 +104,7 @@ class LinphoneCommunicationSocket(): |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
|
|
|
|
|
|
|
|
def call_stats(self, call_id): |
|
|
|
def call_stats(self, call_id): |
|
|
|
self.socket.send("call-stats {call_id}".format(call_id=call_id).encode("ascii")) |
|
|
|
answer = self.send_command("call-stats {call_id}".format(call_id=call_id)) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
stats_offsets = [i for i, x in enumerate(answer["data"]) if "Id:" in x] |
|
|
|
stats_offsets = [i for i, x in enumerate(answer["data"]) if "Id:" in x] |
|
|
|
stats = { |
|
|
|
stats = { |
|
|
@ -146,24 +138,21 @@ class LinphoneCommunicationSocket(): |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
|
|
|
|
|
|
|
|
def call_resume(self, call_id): |
|
|
|
def call_resume(self, call_id): |
|
|
|
self.socket.send("call-resume {call_id}".format(call_id=call_id).encode("ascii")) |
|
|
|
answer = self.send_command("call-resume {call_id}".format(call_id=call_id)) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
return True |
|
|
|
return True |
|
|
|
else: |
|
|
|
else: |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
|
|
|
|
|
|
|
|
def dtmf(self, digit): |
|
|
|
def dtmf(self, digit): |
|
|
|
self.socket.send("dtmf {digit}".format(digit=digit).encode("ascii")) |
|
|
|
answer = self.send_command("dtmf {digit}".format(digit=digit)) |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
return True |
|
|
|
return True |
|
|
|
else: |
|
|
|
else: |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
raise RuntimeError(answer["error"]) |
|
|
|
|
|
|
|
|
|
|
|
def process_event(self): |
|
|
|
def process_event(self): |
|
|
|
self.socket.send("pop-event".encode("ascii")) |
|
|
|
answer = self.send_command("pop-event") |
|
|
|
answer = self._await_answer() |
|
|
|
|
|
|
|
if answer["status"]: |
|
|
|
if answer["status"]: |
|
|
|
size_string = answer["data"][0] |
|
|
|
size_string = answer["data"][0] |
|
|
|
remaining_item_count = int(size_string.split(":")[1].strip()) |
|
|
|
remaining_item_count = int(size_string.split(":")[1].strip()) |
|
|
|