add
This commit is contained in:
parent
6155955cca
commit
ae26af0f99
@ -1,4 +1,14 @@
|
|||||||
|
# Use official Python image
|
||||||
FROM python:3.9-slim
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY gsm_simulator.py /app
|
|
||||||
|
# Copy the simulator script
|
||||||
|
COPY gsm_simulator.py .
|
||||||
|
|
||||||
|
# Expose the port
|
||||||
|
EXPOSE 12345
|
||||||
|
|
||||||
|
# Run the simulator
|
||||||
CMD ["python", "gsm_simulator.py"]
|
CMD ["python", "gsm_simulator.py"]
|
@ -1,94 +1,58 @@
|
|||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import random
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
class GSMSimulator:
|
HOST = "0.0.0.0"
|
||||||
def __init__(self, host='0.0.0.0', port=5555):
|
PORT = 12345
|
||||||
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
FRAME_SIZE = 1000
|
||||||
self.server_socket.bind((host, port))
|
FRAME_DELAY = 0.02
|
||||||
self.server_socket.listen(2)
|
|
||||||
self.clients = {}
|
|
||||||
print("GSM Simulator started. Waiting for connections...")
|
|
||||||
|
|
||||||
def simulate_signal_strength(self):
|
clients = []
|
||||||
return random.uniform(0, 1)
|
|
||||||
|
|
||||||
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:
|
try:
|
||||||
client_socket.settimeout(5)
|
other_client = clients[1 - client_id] if len(clients) == 2 else None
|
||||||
role = client_socket.recv(1024).decode().strip()
|
print(f"Client {client_id} waiting for data, other_client exists: {other_client is not None}")
|
||||||
if role not in ["CALLER", "RECEIVER"]:
|
data = client_sock.recv(1024)
|
||||||
print(f"Invalid role received from {address}: {role}")
|
if not data:
|
||||||
client_socket.close()
|
print(f"Client {client_id} disconnected or no data received")
|
||||||
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())
|
|
||||||
break
|
break
|
||||||
|
if other_client:
|
||||||
def handle_receiver(self, receiver_socket):
|
for i in range(0, len(data), FRAME_SIZE):
|
||||||
print("Receiver connected, waiting for data...")
|
frame = data[i:i + FRAME_SIZE]
|
||||||
try:
|
other_client.send(frame)
|
||||||
while True:
|
time.sleep(FRAME_DELAY)
|
||||||
data = receiver_socket.recv(1024)
|
print(f"Forwarded {len(data)} bytes from Client {client_id} to Client {1 - client_id}")
|
||||||
if not data:
|
|
||||||
print("Receiver disconnected.")
|
|
||||||
break
|
|
||||||
except Exception as e:
|
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:
|
while True:
|
||||||
client_socket, address = self.server_socket.accept()
|
time.sleep(1)
|
||||||
print(f"New connection from {address}")
|
except KeyboardInterrupt:
|
||||||
thread = threading.Thread(target=self.handle_client, args=(client_socket, address))
|
print("Shutting down simulator...")
|
||||||
thread.start()
|
for client in clients:
|
||||||
|
client.close()
|
||||||
|
server.close()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
gsm = GSMSimulator()
|
start_simulator()
|
||||||
gsm.run()
|
|
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