add
This commit is contained in:
parent
6155955cca
commit
ae26af0f99
@ -1,4 +1,14 @@
|
||||
# Use official Python image
|
||||
FROM python:3.9-slim
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
COPY gsm_simulator.py /app
|
||||
CMD ["python", "gsm_simulator.py"]
|
||||
|
||||
# Copy the simulator script
|
||||
COPY gsm_simulator.py .
|
||||
|
||||
# Expose the port
|
||||
EXPOSE 12345
|
||||
|
||||
# Run the simulator
|
||||
CMD ["python", "gsm_simulator.py"]
|
@ -1,94 +1,58 @@
|
||||
import socket
|
||||
import threading
|
||||
import random
|
||||
import time
|
||||
|
||||
class GSMSimulator:
|
||||
def __init__(self, host='0.0.0.0', port=5555):
|
||||
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.server_socket.bind((host, port))
|
||||
self.server_socket.listen(2)
|
||||
self.clients = {}
|
||||
print("GSM Simulator started. Waiting for connections...")
|
||||
HOST = "0.0.0.0"
|
||||
PORT = 12345
|
||||
FRAME_SIZE = 1000
|
||||
FRAME_DELAY = 0.02
|
||||
|
||||
def simulate_signal_strength(self):
|
||||
return random.uniform(0, 1)
|
||||
clients = []
|
||||
|
||||
def handle_client(self, client_socket, address):
|
||||
def handle_client(client_sock, client_id):
|
||||
print(f"Starting handle_client for Client {client_id}")
|
||||
while True:
|
||||
try:
|
||||
client_socket.settimeout(5)
|
||||
role = client_socket.recv(1024).decode().strip()
|
||||
if role not in ["CALLER", "RECEIVER"]:
|
||||
print(f"Invalid role received from {address}: {role}")
|
||||
client_socket.close()
|
||||
return
|
||||
self.clients[role] = client_socket
|
||||
print(f"{role} connected from {address}")
|
||||
|
||||
if role == "CALLER":
|
||||
self.handle_caller(client_socket)
|
||||
elif role == "RECEIVER":
|
||||
self.handle_receiver(client_socket)
|
||||
except Exception as e:
|
||||
print(f"Error handling client {address}: {e}")
|
||||
finally:
|
||||
if role in self.clients:
|
||||
del self.clients[role]
|
||||
client_socket.close()
|
||||
|
||||
def handle_caller(self, caller_socket):
|
||||
print("Caller connected, waiting for receiver...")
|
||||
while "RECEIVER" not in self.clients:
|
||||
time.sleep(1)
|
||||
receiver_socket = self.clients["RECEIVER"]
|
||||
print("Receiver found, sending RINGING...")
|
||||
receiver_socket.send("RINGING".encode())
|
||||
|
||||
while True:
|
||||
try:
|
||||
data = caller_socket.recv(1024).decode().strip()
|
||||
if not data:
|
||||
print("Caller disconnected unexpectedly.")
|
||||
receiver_socket.send("CALL_END".encode())
|
||||
break
|
||||
if data == "CALL_END":
|
||||
print("Call terminated by caller.")
|
||||
receiver_socket.send("CALL_END".encode())
|
||||
break
|
||||
|
||||
signal = self.simulate_signal_strength()
|
||||
if signal < 0.2:
|
||||
print("Call dropped due to low signal strength.")
|
||||
caller_socket.send("CALL_DROPPED".encode())
|
||||
receiver_socket.send("CALL_DROPPED".encode())
|
||||
break
|
||||
|
||||
print(f"Relaying to receiver: {data} (Signal: {signal:.2f})")
|
||||
receiver_socket.send(data.encode())
|
||||
time.sleep(0.1) # Small delay to ensure data is sent properly
|
||||
except Exception as e:
|
||||
print(f"Error in caller loop: {e}")
|
||||
receiver_socket.send("CALL_END".encode())
|
||||
other_client = clients[1 - client_id] if len(clients) == 2 else None
|
||||
print(f"Client {client_id} waiting for data, other_client exists: {other_client is not None}")
|
||||
data = client_sock.recv(1024)
|
||||
if not data:
|
||||
print(f"Client {client_id} disconnected or no data received")
|
||||
break
|
||||
|
||||
def handle_receiver(self, receiver_socket):
|
||||
print("Receiver connected, waiting for data...")
|
||||
try:
|
||||
while True:
|
||||
data = receiver_socket.recv(1024)
|
||||
if not data:
|
||||
print("Receiver disconnected.")
|
||||
break
|
||||
if other_client:
|
||||
for i in range(0, len(data), FRAME_SIZE):
|
||||
frame = data[i:i + FRAME_SIZE]
|
||||
other_client.send(frame)
|
||||
time.sleep(FRAME_DELAY)
|
||||
print(f"Forwarded {len(data)} bytes from Client {client_id} to Client {1 - client_id}")
|
||||
except Exception as e:
|
||||
print(f"Error in receiver loop: {e}")
|
||||
print(f"Error with Client {client_id}: {e}")
|
||||
break
|
||||
print(f"Closing connection for Client {client_id}")
|
||||
client_sock.close()
|
||||
|
||||
def run(self):
|
||||
def start_simulator():
|
||||
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
server.bind((HOST, PORT))
|
||||
server.listen(2)
|
||||
print(f"GSM Simulator listening on {HOST}:{PORT}...")
|
||||
|
||||
while len(clients) < 2:
|
||||
client_sock, addr = server.accept()
|
||||
client_sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # Keep connection alive
|
||||
clients.append(client_sock)
|
||||
client_id = len(clients) - 1
|
||||
print(f"Client {client_id} connected from {addr}")
|
||||
threading.Thread(target=handle_client, args=(client_sock, client_id), daemon=True).start()
|
||||
|
||||
try:
|
||||
while True:
|
||||
client_socket, address = self.server_socket.accept()
|
||||
print(f"New connection from {address}")
|
||||
thread = threading.Thread(target=self.handle_client, args=(client_socket, address))
|
||||
thread.start()
|
||||
time.sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
print("Shutting down simulator...")
|
||||
for client in clients:
|
||||
client.close()
|
||||
server.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
gsm = GSMSimulator()
|
||||
gsm.run()
|
||||
start_simulator()
|
BIN
protocol_prototype/DryBox/input.wav
Normal file
BIN
protocol_prototype/DryBox/input.wav
Normal file
Binary file not shown.
BIN
protocol_prototype/DryBox/input_8k_mono.wav
Normal file
BIN
protocol_prototype/DryBox/input_8k_mono.wav
Normal file
Binary file not shown.
BIN
protocol_prototype/DryBox/input_8k_mono.wav.gsm
Normal file
BIN
protocol_prototype/DryBox/input_8k_mono.wav.gsm
Normal file
Binary file not shown.
86
protocol_prototype/DryBox/protocol.py
Normal file
86
protocol_prototype/DryBox/protocol.py
Normal file
@ -0,0 +1,86 @@
|
||||
import socket
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
# Configuration
|
||||
HOST = "localhost"
|
||||
PORT = 12345
|
||||
INPUT_FILE = "input.wav"
|
||||
OUTPUT_FILE = "received.wav"
|
||||
|
||||
|
||||
def encrypt_data(data):
|
||||
return data # Replace with your encryption protocol
|
||||
|
||||
|
||||
def decrypt_data(data):
|
||||
return data # Replace with your decryption protocol
|
||||
|
||||
|
||||
def run_protocol(send_mode=True):
|
||||
"""Connect to the simulator and send/receive data."""
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.connect((HOST, PORT))
|
||||
print(f"Connected to simulator at {HOST}:{PORT}")
|
||||
|
||||
if send_mode:
|
||||
# Sender mode: Encode audio with toast
|
||||
os.system(f"toast -p -l {INPUT_FILE}") # Creates input.wav.gsm
|
||||
input_gsm_file = f"{INPUT_FILE}.gsm"
|
||||
if not os.path.exists(input_gsm_file):
|
||||
print(f"Error: {input_gsm_file} not created")
|
||||
sock.close()
|
||||
return
|
||||
with open(input_gsm_file, "rb") as f:
|
||||
voice_data = f.read()
|
||||
|
||||
encrypted_data = encrypt_data(voice_data)
|
||||
sock.send(encrypted_data)
|
||||
print(f"Sent {len(encrypted_data)} bytes")
|
||||
os.remove(input_gsm_file) # Clean up
|
||||
else:
|
||||
# Receiver mode: Wait for and receive data
|
||||
print("Waiting for data from sender...")
|
||||
received_data = b""
|
||||
sock.settimeout(5.0)
|
||||
try:
|
||||
while True:
|
||||
print("Calling recv()...")
|
||||
data = sock.recv(1024)
|
||||
print(f"Received {len(data)} bytes")
|
||||
if not data:
|
||||
print("Connection closed by sender or simulator")
|
||||
break
|
||||
received_data += data
|
||||
except socket.timeout:
|
||||
print("Timed out waiting for data")
|
||||
|
||||
if received_data:
|
||||
with open("received.gsm", "wb") as f:
|
||||
f.write(decrypt_data(received_data))
|
||||
print(f"Wrote {len(received_data)} bytes to received.gsm")
|
||||
# Decode with untoast, then convert to WAV with sox
|
||||
result = subprocess.run(["untoast", "received.gsm"], capture_output=True, text=True)
|
||||
print(f"untoast return code: {result.returncode}")
|
||||
print(f"untoast stderr: {result.stderr}")
|
||||
if result.returncode == 0:
|
||||
if os.path.exists("received"):
|
||||
# Convert raw PCM to WAV (8 kHz, mono, 16-bit)
|
||||
subprocess.run(["sox", "-t", "raw", "-r", "8000", "-e", "signed", "-b", "16", "-c", "1", "received",
|
||||
OUTPUT_FILE])
|
||||
os.remove("received")
|
||||
print(f"Received and saved {len(received_data)} bytes to {OUTPUT_FILE}")
|
||||
else:
|
||||
print("Error: 'received' file not created by untoast")
|
||||
else:
|
||||
print(f"untoast failed: {result.stderr}")
|
||||
else:
|
||||
print("No data received from simulator")
|
||||
|
||||
sock.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
mode = input("Enter 'send' to send data or 'receive' to receive data: ").strip().lower()
|
||||
run_protocol(send_mode=(mode == "send"))
|
BIN
protocol_prototype/DryBox/received.wav
Normal file
BIN
protocol_prototype/DryBox/received.wav
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user