Commit initial
This commit is contained in:
7
server/lib/CameraCommander/Camera.py
Normal file
7
server/lib/CameraCommander/Camera.py
Normal file
@ -0,0 +1,7 @@
|
||||
class Camera:
|
||||
def __init__(self, id, product_key, available, enabled, rtmp_handle):
|
||||
self.id = id
|
||||
self.product_key = product_key
|
||||
self.available = available
|
||||
self.enabled = enabled
|
||||
self.rtmp_handle = rtmp_handle
|
33
server/lib/CameraCommander/CameraCommander.py
Normal file
33
server/lib/CameraCommander/CameraCommander.py
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
|
||||
class CameraCommander:
|
||||
class InvalidStateException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
Cameras = []
|
||||
|
||||
|
||||
def Register(context, camera):
|
||||
for c in CameraCommander.Cameras:
|
||||
if c.camera.id == camera.id:
|
||||
print("[CameraCommander] : Camera ({}) already registered".format(camera.id))
|
||||
raise CameraCommander.InvalidStateException()
|
||||
CameraCommander.Cameras.append(context)
|
||||
print("[CameraCommander] : Camera ({}) registered".format(camera.id))
|
||||
|
||||
|
||||
def GetContext(camera):
|
||||
for c in CameraCommander.Cameras:
|
||||
if c.camera.id == camera.id:
|
||||
return c
|
||||
return None
|
||||
|
||||
|
||||
def IsRegistered(context):
|
||||
return context in CameraCommander.Cameras
|
||||
|
||||
|
||||
def Remove(context):
|
||||
CameraCommander.Cameras.remove(context)
|
||||
print("[CameraCommander] : Camera ({}) unregistered".format(context.camera.id))
|
32
server/lib/CameraCommander/CameraConnection.py
Normal file
32
server/lib/CameraCommander/CameraConnection.py
Normal file
@ -0,0 +1,32 @@
|
||||
import socket
|
||||
|
||||
|
||||
class CameraConnection:
|
||||
def __init__(self, sock, addr):
|
||||
self.sock = sock
|
||||
self.addr = addr[0]
|
||||
self.port = addr[1]
|
||||
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
||||
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 300)
|
||||
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 30)
|
||||
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 4)
|
||||
|
||||
|
||||
def receive(self):
|
||||
data = b""
|
||||
ret = self.sock.recv(1)
|
||||
while ret and ret != b"\x00":
|
||||
data = data + ret
|
||||
ret = self.sock.recv(1)
|
||||
if not data:
|
||||
return None
|
||||
return data.decode()
|
||||
|
||||
|
||||
def send(self, msg):
|
||||
data = (msg + "\0").encode()
|
||||
return self.sock.send(data) == len(data)
|
||||
|
||||
|
||||
def close(self):
|
||||
self.sock.close()
|
86
server/lib/CameraCommander/CameraContext.py
Normal file
86
server/lib/CameraCommander/CameraContext.py
Normal file
@ -0,0 +1,86 @@
|
||||
from CameraModel import CameraModel
|
||||
from CameraCommander import CameraCommander
|
||||
from WaitAuthentication import WaitAuthentication
|
||||
from WaitEnabledModeReply import WaitEnabledModeReply
|
||||
from WaitDisabledModeReply import WaitDisabledModeReply
|
||||
from WaitDisconnectedReply import WaitDisconnectedReply
|
||||
from DeadState import DeadState
|
||||
|
||||
|
||||
class CameraContext:
|
||||
class InvalidStateException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def __init__(self, connection):
|
||||
self.camera = None
|
||||
self.connection = connection
|
||||
self.state = WaitAuthentication()
|
||||
|
||||
|
||||
def handle(self):
|
||||
return self.state.handle(self)
|
||||
|
||||
|
||||
def tic(self):
|
||||
self.state.tic(self)
|
||||
|
||||
|
||||
def enable(self, userCommand = None):
|
||||
if not self.camera or not self.connection:
|
||||
raise CameraContext.InvalidStateException()
|
||||
if not self.connection.send("enable"):
|
||||
print("[CameraContext] : Connection lost with camera ({}) at {}:{}".format(self.camera.id, self.connection.addr, self.connection.port))
|
||||
self.close()
|
||||
if userCommand:
|
||||
userCommand.callback(False, "connection_lost")
|
||||
return False
|
||||
print("[CameraContext] : Ask for enabling RTMP streaming on camera ({}) at {}:{}".format(self.camera.id, self.connection.addr, self.connection.port))
|
||||
self.state = WaitEnabledModeReply(userCommand)
|
||||
return True
|
||||
|
||||
|
||||
def disable(self, userCommand = None):
|
||||
if not self.camera or not self.connection:
|
||||
raise CameraContext.InvalidStateException()
|
||||
if not self.connection.send("disable"):
|
||||
print("[CameraContext] : Connection lost with camera ({}) at {}:{}".format(self.camera.id, self.connection.addr, self.connection.port))
|
||||
self.close()
|
||||
if userCommand:
|
||||
userCommand.callback(False, "connection_lost")
|
||||
return False
|
||||
print("[CameraContext] : Ask for disabling RTMP streaming on camera ({}) at {}:{}".format(self.camera.id, self.connection.addr, self.connection.port))
|
||||
self.state = WaitDisabledModeReply(userCommand)
|
||||
return True
|
||||
|
||||
|
||||
def disconnect(self, userCommand = None):
|
||||
if not self.camera or not self.connection:
|
||||
raise CameraContext.InvalidStateException()
|
||||
if not self.connection.send("disconnect"):
|
||||
print("[CameraContext] : Connection lost with camera ({}) at {}:{}".format(self.camera.id, self.connection.addr, self.connection.port))
|
||||
self.close()
|
||||
if userCommand:
|
||||
userCommand.callback(False, "connection_lost")
|
||||
return False
|
||||
print("[CameraContext] : Ask for disconnecting camera ({}) at {}:{}".format(self.camera.id, self.connection.addr, self.connection.port))
|
||||
self.state = WaitDisconnectedReply(userCommand)
|
||||
return True
|
||||
|
||||
|
||||
def close(self):
|
||||
if not self.connection:
|
||||
raise CameraContext.InvalidStateException()
|
||||
if CameraCommander.IsRegistered(self):
|
||||
CameraCommander.Remove(self)
|
||||
if not self.camera:
|
||||
raise CameraContext.InvalidStateException()
|
||||
mdl = CameraModel()
|
||||
self.camera.available = False
|
||||
self.camera.rtmp_handle = ""
|
||||
mdl.update(self.camera)
|
||||
self.camera = None
|
||||
print("[CameraContext] : Close connection with {}:{}".format(self.connection.addr, self.connection.port))
|
||||
self.connection.close()
|
||||
self.connection = None
|
||||
self.state = DeadState()
|
24
server/lib/CameraCommander/CameraModel.py
Normal file
24
server/lib/CameraCommander/CameraModel.py
Normal file
@ -0,0 +1,24 @@
|
||||
import DataBase
|
||||
from Camera import Camera
|
||||
|
||||
|
||||
class CameraModel:
|
||||
def getById(self, id):
|
||||
db = DataBase.GetConnection()
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT * FROM camera WHERE id=%s""", (id,))
|
||||
row = cursor.fetchone()
|
||||
cursor.close()
|
||||
db.close()
|
||||
if row:
|
||||
return Camera(row[0], row[1], bool(row[2]), bool(row[3]), row[4])
|
||||
return None
|
||||
|
||||
|
||||
def update(self, camera):
|
||||
db = DataBase.GetConnection()
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""UPDATE camera SET available=%s, enabled=%s, rtmp_handle=%s WHERE id=%s""", (int(camera.available), int(camera.enabled), camera.rtmp_handle, camera.id))
|
||||
cursor.close()
|
||||
db.commit()
|
||||
db.close()
|
8
server/lib/CameraCommander/DataBase.py
Normal file
8
server/lib/CameraCommander/DataBase.py
Normal file
@ -0,0 +1,8 @@
|
||||
import mysql.connector
|
||||
|
||||
|
||||
def GetConnection():
|
||||
try:
|
||||
return mysql.connector.connect(user = "camplatform_user", password = "lLZwfSLuwye3qW4r", host = "public.lan", database = "camplatform_db")
|
||||
except mysql.connector.Error:
|
||||
return None
|
10
server/lib/CameraCommander/DeadState.py
Normal file
10
server/lib/CameraCommander/DeadState.py
Normal file
@ -0,0 +1,10 @@
|
||||
from WaitState import WaitState
|
||||
|
||||
|
||||
class DeadState(WaitState):
|
||||
def handle(self, context):
|
||||
pass
|
||||
|
||||
|
||||
def tic(self, context):
|
||||
pass
|
5
server/lib/CameraCommander/User.py
Normal file
5
server/lib/CameraCommander/User.py
Normal file
@ -0,0 +1,5 @@
|
||||
class User:
|
||||
def __init__(self, id, login, password):
|
||||
self.id = id
|
||||
self.login = login
|
||||
self.password = password
|
120
server/lib/CameraCommander/UserCommand.py
Normal file
120
server/lib/CameraCommander/UserCommand.py
Normal file
@ -0,0 +1,120 @@
|
||||
from UserModel import UserModel
|
||||
from CameraModel import CameraModel
|
||||
import CameraCommander
|
||||
from WaitActivity import WaitActivity
|
||||
|
||||
|
||||
class UserCommand:
|
||||
class InvalidStateException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def __init__(self, sock, addr):
|
||||
self.sock = sock
|
||||
self.addr = addr[0]
|
||||
self.port = addr[1]
|
||||
|
||||
|
||||
def receive(self):
|
||||
data = b""
|
||||
ret = self.sock.recv(1)
|
||||
while ret and ret != b"\x00":
|
||||
data = data + ret
|
||||
ret = self.sock.recv(1)
|
||||
if not data:
|
||||
return None
|
||||
return data.decode()
|
||||
|
||||
|
||||
def send(self, msg):
|
||||
data = (msg + "\0").encode()
|
||||
return self.sock.send(data) == len(data)
|
||||
|
||||
|
||||
def close(self):
|
||||
print("[UserCommand] : Closing connection with {}:{}".format(self.addr, self.port))
|
||||
self.sock.close()
|
||||
self.sock = None
|
||||
self.addr = None
|
||||
self.port = None
|
||||
|
||||
|
||||
def callback(self, result, error_msg = None):
|
||||
print("[UserCommand] : Send reply to {}:{}".format(self.addr, self.port))
|
||||
if result:
|
||||
self.send("ok")
|
||||
elif error_msg:
|
||||
self.send("error:" + error_msg)
|
||||
else:
|
||||
self.send("error")
|
||||
self.close()
|
||||
|
||||
|
||||
def execute(self):
|
||||
if not self.sock:
|
||||
raise UserCommand.InvalidStateException()
|
||||
data = self.receive()
|
||||
if not data:
|
||||
print("[UserCommand] : Connection lost with {}:{}".format(self.addr, self.port))
|
||||
self.close()
|
||||
return
|
||||
|
||||
words = data.split(":")
|
||||
if len(words) != 4:
|
||||
print("[UserCommand] : Error from {}:{}, invalid data".format(self.addr, self.port))
|
||||
self.send("error:invalid_data")
|
||||
self.close()
|
||||
return
|
||||
|
||||
userMdl = UserModel()
|
||||
user = userMdl.getByLogin(words[0])
|
||||
if not user:
|
||||
print("[UserCommand] : Error from {}:{}, invalid username".format(self.addr, self.port))
|
||||
self.send("error:invalid_username")
|
||||
self.close()
|
||||
return
|
||||
|
||||
if user.password != words[1]:
|
||||
print("[UserCommand] : Error from {}:{}, invalid password for user ({})".format(self.addr, self.port, user.login))
|
||||
self.send("error:invalid_password")
|
||||
self.close()
|
||||
return
|
||||
|
||||
camMdl = CameraModel()
|
||||
camera = camMdl.getById(words[3])
|
||||
if not camera:
|
||||
print("[UserCommand] : Error from user ({}) at {}:{}, invalid camera's serial number".format(user.login, self.addr, self.port))
|
||||
self.send("error:invalid_camera_id")
|
||||
self.close()
|
||||
return
|
||||
|
||||
if not userMdl.haveCamera(user, camera):
|
||||
print("[UserCommand] : User ({}) at {}:{} is not allowed to command camera ({})".format(user.login, self.addr, self.port, camera.id))
|
||||
self.send("error:not_authorized")
|
||||
self.close()
|
||||
return
|
||||
|
||||
context = CameraCommander.CameraCommander.GetContext(camera)
|
||||
if not context:
|
||||
print("[UserCommand] : Error from user ({}) at {}:{}, camera ({}) is not registered".format(user.login, self.addr, self.port, camera.id))
|
||||
self.send("error:camera_not_registered")
|
||||
self.close()
|
||||
return
|
||||
|
||||
if not isinstance(context.state, WaitActivity):
|
||||
print("[UserCommand] : Error from user ({}) at {}:{}, camera ({}) is busy".format(user.login, self.addr, self.port, camera.id))
|
||||
self.send("error:camera_busy")
|
||||
self.close()
|
||||
return
|
||||
|
||||
if words[2] == "enable":
|
||||
context.enable(self)
|
||||
elif words[2] == "disable":
|
||||
context.disable(self)
|
||||
elif words[2] == "disconnect":
|
||||
context.disconnect(self)
|
||||
else:
|
||||
print("[UserCommand] : Error from user ({}) at {}:{}, invalid command".format(user.login, self.addr, self.port))
|
||||
self.send("error:invalid_command")
|
||||
self.close()
|
||||
return
|
28
server/lib/CameraCommander/UserModel.py
Normal file
28
server/lib/CameraCommander/UserModel.py
Normal file
@ -0,0 +1,28 @@
|
||||
import DataBase
|
||||
from User import User
|
||||
|
||||
|
||||
class UserModel:
|
||||
def getByLogin(self, login):
|
||||
db = DataBase.GetConnection()
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT * FROM user WHERE login=%s""", (login,))
|
||||
row = cursor.fetchone()
|
||||
cursor.close()
|
||||
db.close()
|
||||
if row:
|
||||
return User(row[0], row[1], row[2])
|
||||
return None
|
||||
|
||||
|
||||
def haveCamera(self, user, camera):
|
||||
db = DataBase.GetConnection()
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT * FROM user_camera WHERE user_id=%s AND camera_id=%s""", (user.id, camera.id))
|
||||
row = cursor.fetchone()
|
||||
cursor.close()
|
||||
db.close()
|
||||
if row:
|
||||
return True
|
||||
return False
|
||||
|
14
server/lib/CameraCommander/WaitActivity.py
Normal file
14
server/lib/CameraCommander/WaitActivity.py
Normal file
@ -0,0 +1,14 @@
|
||||
from WaitState import WaitState
|
||||
from CameraCommander import CameraCommander
|
||||
|
||||
|
||||
class WaitActivity(WaitState):
|
||||
def handle(self, context):
|
||||
data = self.waitMsg(context)
|
||||
if data:
|
||||
print("[WaitActivity] : Error({}) from camera ({}) at {}:{}".format(data, context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
|
||||
|
||||
def tic(self, context):
|
||||
pass
|
55
server/lib/CameraCommander/WaitAuthentication.py
Normal file
55
server/lib/CameraCommander/WaitAuthentication.py
Normal file
@ -0,0 +1,55 @@
|
||||
import random
|
||||
|
||||
from CameraCommander import CameraCommander
|
||||
from CameraModel import CameraModel
|
||||
from WaitState import WaitState
|
||||
from WaitActivity import WaitActivity
|
||||
import CameraContext
|
||||
|
||||
|
||||
class WaitAuthentication(WaitState):
|
||||
def handle(self, context):
|
||||
data = self.waitMsg(context)
|
||||
if not data:
|
||||
return
|
||||
words = data.split(":")
|
||||
if len(words) != 2:
|
||||
print("[WaitAuthentication] : Invalid data from camera at {}:{}".format(context.connection.addr, context.connection.port))
|
||||
context.connection.send("invalid_data")
|
||||
context.close()
|
||||
return
|
||||
|
||||
mdl = CameraModel()
|
||||
camera = mdl.getById(words[0])
|
||||
if not camera or camera.product_key != words[1]:
|
||||
print("[WaitAuthentication] : Authentication failed for camera at {}:{}".format(context.connection.addr, context.connection.port))
|
||||
context.connection.send("refused")
|
||||
context.close()
|
||||
return
|
||||
|
||||
try:
|
||||
CameraCommander.Register(context, camera)
|
||||
except CameraCommander.InvalidStateException:
|
||||
context.connection.send("refused")
|
||||
context.close()
|
||||
return
|
||||
|
||||
context.camera = camera
|
||||
print("[WaitAuthentication] : Camera at {}:{} successfully authenticated as ({})".format(context.connection.addr, context.connection.port, context.camera.id))
|
||||
|
||||
context.camera.available = True
|
||||
context.camera.rtmp_handle = hex(hash(random.random()))[2:]
|
||||
mdl.update(context.camera)
|
||||
if not context.connection.send("accepted:{}".format(context.camera.rtmp_handle)):
|
||||
print("[WaitAuthentication] : Connection lost with camera ({}) at {}:{}".format(context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
return
|
||||
|
||||
if context.camera.enabled:
|
||||
context.enable()
|
||||
return
|
||||
context.state = WaitActivity()
|
||||
|
||||
|
||||
def tic(self, context):
|
||||
pass
|
40
server/lib/CameraCommander/WaitDisabledModeReply.py
Normal file
40
server/lib/CameraCommander/WaitDisabledModeReply.py
Normal file
@ -0,0 +1,40 @@
|
||||
import time
|
||||
|
||||
from CameraModel import CameraModel
|
||||
from WaitState import WaitState
|
||||
from WaitActivity import WaitActivity
|
||||
|
||||
|
||||
class WaitDisabledModeReply(WaitState):
|
||||
def __init__(self, userCommand):
|
||||
self.userCommand = userCommand
|
||||
self.initTime = time.time()
|
||||
|
||||
|
||||
def handle(self, context):
|
||||
data = self.waitMsg(context)
|
||||
if not data:
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(False, "connection_lost")
|
||||
return
|
||||
if data == "disabled":
|
||||
print("[WaitDisabledModeReply] : Camera ({}) at {}:{} successfully disabled".format(context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.camera.enabled = False
|
||||
mdl = CameraModel()
|
||||
mdl.update(context.camera)
|
||||
context.state = WaitActivity()
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(True)
|
||||
else:
|
||||
print("[WaitDisabledModeReply] : Error({}) from camera ({}) at {}:{}".format(data, context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(False, data)
|
||||
|
||||
|
||||
def tic(self, context):
|
||||
if time.time() - self.initTime > 10:
|
||||
print("[WaitDisabledModeReply] : Timeout exeeded for camera ({}) at {}:{}".format(context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(False, "timeout")
|
35
server/lib/CameraCommander/WaitDisconnectedReply.py
Normal file
35
server/lib/CameraCommander/WaitDisconnectedReply.py
Normal file
@ -0,0 +1,35 @@
|
||||
import time
|
||||
|
||||
from WaitState import WaitState
|
||||
|
||||
|
||||
class WaitDisconnectedReply(WaitState):
|
||||
def __init__(self, userCommand):
|
||||
self.userCommand = userCommand
|
||||
self.initTime = time.time()
|
||||
|
||||
|
||||
def handle(self, context):
|
||||
data = self.waitMsg(context)
|
||||
if not data:
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(False, "connection_lost")
|
||||
return
|
||||
if data == "disconnected":
|
||||
print("[CameraContext] : Camera ({}) at {}:{} successfully disconnected".format(context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(True)
|
||||
else:
|
||||
print("[WaitDisconnectedReply] : Error({}) from camera ({}) at {}:{}".format(data, context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(False, data)
|
||||
|
||||
|
||||
def tic(self, context):
|
||||
if time.time() - self.initTime > 10:
|
||||
print("[WaitEnabledModeReply] : Timeout exeeded for camera ({}) at {}:{}".format(context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(False, "timeout")
|
40
server/lib/CameraCommander/WaitEnabledModeReply.py
Normal file
40
server/lib/CameraCommander/WaitEnabledModeReply.py
Normal file
@ -0,0 +1,40 @@
|
||||
import time
|
||||
|
||||
from CameraModel import CameraModel
|
||||
from WaitState import WaitState
|
||||
from WaitActivity import WaitActivity
|
||||
|
||||
|
||||
class WaitEnabledModeReply(WaitState):
|
||||
def __init__(self, userCommand):
|
||||
self.userCommand = userCommand
|
||||
self.initTime = time.time()
|
||||
|
||||
|
||||
def handle(self, context):
|
||||
data = self.waitMsg(context)
|
||||
if not data:
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(False, "connection_lost")
|
||||
return
|
||||
if data == "enabled":
|
||||
print("[WaitEnabledModeReply] : Camera ({}) at {}:{} successfully enabled".format(context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.camera.enabled = True
|
||||
mdl = CameraModel()
|
||||
mdl.update(context.camera)
|
||||
context.state = WaitActivity()
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(True)
|
||||
else:
|
||||
print("[WaitEnabledModeReply] : Error({}) from camera ({}) at {}:{}".format(data, context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(False, data)
|
||||
|
||||
|
||||
def tic(self, context):
|
||||
if time.time() - self.initTime > 10:
|
||||
print("[WaitEnabledModeReply] : Timeout exeeded for camera ({}) at {}:{}".format(context.camera.id, context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
if self.userCommand:
|
||||
self.userCommand.callback(False, "timeout")
|
17
server/lib/CameraCommander/WaitState.py
Normal file
17
server/lib/CameraCommander/WaitState.py
Normal file
@ -0,0 +1,17 @@
|
||||
class WaitState:
|
||||
def waitMsg(self, context):
|
||||
data = context.connection.receive()
|
||||
if not data:
|
||||
print("[WaitState] : Connection lost with camera at {}:{}".format(context.connection.addr, context.connection.port))
|
||||
context.close()
|
||||
return None
|
||||
else:
|
||||
return data
|
||||
|
||||
|
||||
def handle(self, context):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def tic(self, context):
|
||||
raise NotImplementedError()
|
102
server/lib/CameraCommander/main.py
Normal file
102
server/lib/CameraCommander/main.py
Normal file
@ -0,0 +1,102 @@
|
||||
import socket
|
||||
import select
|
||||
import signal
|
||||
|
||||
from CameraContext import CameraContext
|
||||
from UserCommand import UserCommand
|
||||
from CameraConnection import CameraConnection
|
||||
from CameraCommander import CameraCommander
|
||||
from WaitActivity import WaitActivity
|
||||
|
||||
|
||||
def on_sigint(signal, frame):
|
||||
global server_enabled
|
||||
server_enabled = False
|
||||
|
||||
|
||||
#
|
||||
# Main
|
||||
#
|
||||
|
||||
server_enabled = True
|
||||
signal.signal(signal.SIGINT, on_sigint)
|
||||
connected_cameras = []
|
||||
connected_users = []
|
||||
|
||||
cam_listener_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
cam_listener_sock.bind(("", 41551))
|
||||
cam_listener_sock.listen(5)
|
||||
|
||||
cmd_listener_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
cmd_listener_sock.bind(("", 40550))
|
||||
cmd_listener_sock.listen(5)
|
||||
|
||||
|
||||
print("[Main] : Ready")
|
||||
|
||||
while server_enabled or len(CameraCommander.Cameras) > 0:
|
||||
if server_enabled:
|
||||
conn_list, wlist, xlist = select.select([cam_listener_sock, cmd_listener_sock], [], [], 0.05)
|
||||
if cam_listener_sock in conn_list:
|
||||
cam_sock, cam_addr = cam_listener_sock.accept()
|
||||
connected_cameras.append(CameraContext(CameraConnection(cam_sock, cam_addr)))
|
||||
elif cmd_listener_sock in conn_list:
|
||||
user_sock, user_addr = cmd_listener_sock.accept()
|
||||
connected_users.append(UserCommand(user_sock, user_addr))
|
||||
|
||||
new_connected_users = []
|
||||
for userCommand in connected_users:
|
||||
if userCommand.sock:
|
||||
new_connected_users.append(userCommand)
|
||||
connected_users = new_connected_users
|
||||
|
||||
user_sock_list = [userCommand.sock for userCommand in connected_users]
|
||||
|
||||
if server_enabled:
|
||||
sock_read_list, wlist, xlist = select.select(user_sock_list, [], [], 0.05)
|
||||
for user_sock in sock_read_list:
|
||||
for userCommand in connected_users:
|
||||
if user_sock == userCommand.sock:
|
||||
userCommand.execute()
|
||||
|
||||
new_connected_cameras = []
|
||||
for context in connected_cameras:
|
||||
if context.connection:
|
||||
new_connected_cameras.append(context)
|
||||
connected_cameras = new_connected_cameras
|
||||
|
||||
if not server_enabled:
|
||||
for context in CameraCommander.Cameras:
|
||||
if isinstance(context.state, WaitActivity):
|
||||
try:
|
||||
context.disconnect()
|
||||
except CameraContext.TransmissionErrorException:
|
||||
context.close()
|
||||
|
||||
cam_sock_list = [context.connection.sock for context in connected_cameras]
|
||||
|
||||
sock_read_list, wlist, xlist = select.select(cam_sock_list, [], [], 0.05)
|
||||
for cam_sock in sock_read_list:
|
||||
for context in connected_cameras:
|
||||
if cam_sock == context.connection.sock:
|
||||
context.handle()
|
||||
|
||||
for context in connected_cameras:
|
||||
context.tic()
|
||||
|
||||
|
||||
for context in connected_cameras:
|
||||
if context.connection:
|
||||
context.close()
|
||||
|
||||
for userCommand in connected_users:
|
||||
if userCommand.sock:
|
||||
userCommand.close()
|
||||
|
||||
cmd_listener_sock.shutdown(socket.SHUT_RDWR)
|
||||
cmd_listener_sock.close()
|
||||
|
||||
cam_listener_sock.shutdown(socket.SHUT_RDWR)
|
||||
cam_listener_sock.close()
|
||||
|
||||
print("[Main] : Bye !!")
|
Reference in New Issue
Block a user