98 lines
2.8 KiB
Python
98 lines
2.8 KiB
Python
import os
|
|
import sys
|
|
import urllib3
|
|
|
|
from multiprocessing import Pipe, Process
|
|
from threading import Thread
|
|
|
|
from .audiosocket import Audiosocket
|
|
|
|
|
|
def open_url(direction, connection, username, password):
|
|
print(f"start {direction}", flush=True)
|
|
if direction not in ("transmit", "receive"):
|
|
raise NotImplementedError
|
|
method, headers = {
|
|
"receive": ("GET", {}),
|
|
"transmit": ("POST", {"Content-Type": "audio/basic", "Content-Length": "0"}),
|
|
}[direction]
|
|
|
|
url = f"http://192.168.0.74/axis-cgi/audio/{direction}.cgi"
|
|
|
|
http = urllib3.PoolManager()
|
|
|
|
print(f"start {direction} request", flush=True)
|
|
|
|
response = http.request(
|
|
method,
|
|
url,
|
|
headers={
|
|
**urllib3.make_headers(basic_auth=f"{username}:{password}"),
|
|
**headers,
|
|
},
|
|
preload_content=False,
|
|
body=(
|
|
None
|
|
if direction != "transmit"
|
|
else os.fdopen(connection.fileno(), "rb", buffering=0)
|
|
),
|
|
)
|
|
print(f"{direction} status is {response.status}", flush=True)
|
|
|
|
if direction == "receive":
|
|
for data in response.stream(amt=160):
|
|
connection.send_bytes(data)
|
|
|
|
|
|
def handle_connection(call, username, password):
|
|
print(f"Received connection from {call.peer_addr}")
|
|
|
|
pipe_transmit_in, pipe_transmit_out = Pipe()
|
|
doorbell_transmit_process = Process(
|
|
target=open_url, args=("transmit", pipe_transmit_out, username, password)
|
|
)
|
|
doorbell_transmit_process.start()
|
|
|
|
pipe_receive_in, pipe_receive_out = Pipe()
|
|
doorbell_receive_process = Process(
|
|
target=open_url, args=("receive", pipe_receive_in, username, password)
|
|
)
|
|
doorbell_receive_process.start()
|
|
|
|
with os.fdopen(os.dup(pipe_transmit_in.fileno()), "wb", buffering=0) as f_transmit:
|
|
while call.connected:
|
|
f_transmit.write(call.read())
|
|
call.write(pipe_receive_out.recv_bytes())
|
|
|
|
print(f"Connection with {call.peer_addr} is now over")
|
|
doorbell_transmit_process.terminate()
|
|
doorbell_receive_process.terminate()
|
|
doorbell_transmit_process.join()
|
|
doorbell_receive_process.join()
|
|
|
|
|
|
def main():
|
|
audiosocket = Audiosocket(
|
|
(os.environ["LISTEN_ADDRESS"], int(os.environ["LISTEN_PORT"]))
|
|
)
|
|
|
|
audiosocket.prepare_output(outrate=8000, channels=1, lin2ulaw=True)
|
|
audiosocket.prepare_input(inrate=8000, channels=1, ulaw2lin=True)
|
|
|
|
print("Listening for new connections " f"from Asterisk on port {audiosocket.port}")
|
|
username = os.environ["USERNAME"]
|
|
|
|
with open(os.environ["PASSWORD_FILE"], "r", encoding="utf-8") as f:
|
|
password = f.read()
|
|
|
|
while True:
|
|
call = audiosocket.listen()
|
|
|
|
call_thread = Thread(target=handle_connection, args=(call, username, password))
|
|
call_thread.start()
|
|
|
|
call_thread.join()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|