Commit 59d72043 authored by Bc. Petr Elexa's avatar Bc. Petr Elexa

server: fix protocol and data model

parent 5debd32d
......@@ -18,24 +18,24 @@ SET 814190 door_C
SET 814185 door_C
SET 814204 door_D
SET 814199 door_D
SET 1000 _void
SET 1001 _void
SET 1002 _void
SET 1003 _void
SET 1004 _void
SET 1005 _void
SET 1006 _void
SET 1007 _void
SET 1008 _void
SET 1009 _void
SET 1010 _void
SET 1000 __void
SET 1001 __void
SET 1002 __void
SET 1003 __void
SET 1004 __void
SET 1005 __void
SET 1006 __void
SET 1007 __void
SET 1008 __void
SET 1009 __void
SET 1010 __void
SELECT 2
RPUSH 4 1 2
RPUSH 5 1 2
RPUSH 6 1 2
RPUSH 7 1 2
RPUSH 8 1 2
RPUSH 9 1 2
RPUSH 10 1 2
RPUSH 11 1 2
RPUSH 12 1 2
RPUSH 4 on closed
RPUSH 5 on closed
RPUSH 6 on closed
RPUSH 7 on closed
RPUSH 8 on closed
RPUSH 9 on closed
RPUSH 10 on closed
RPUSH 11 on closed
RPUSH 12 on closed
FLUSHALL
SADD _all 0
SADD _void 0
SADD door_A 4
SADD door_B 5
SADD door_C 6
SADD door_D 7
SET 7632370 _all
SET 7573990 door_A
SET 7627526 door_A
SET 7575678 door_B
SET 7577396 door_B
SET 814190 door_C
SET 814185 door_C
SET 814204 door_D
SET 814199 door_D
SET 100 _void
SET 101 _void
SET 102 _void
SET 103 _void
SET 104 _void
SET 105 _void
SET 106 _void
SET 107 _void
SET 108 _void
SET 109 _void
SET 110 _void
#!/bin/sh
cat _test_dataset.txt | redis-cli -h localhost -p 6379 --pipe
\ No newline at end of file
cat _example_redis_dataset.txt | redis-cli -h localhost -p 6379 --pipe
\ No newline at end of file
......@@ -259,13 +259,12 @@ class acs_can_proto(object):
if self.cb_user_auth_req is not None:
user_id = int.from_bytes(msg_data[:4], "little", signed=True)
if self.cb_user_auth_req(src, user_id):
self.msg_auth_ok(src, user_id)
return self.msg_auth_ok(src, user_id)
else:
self.msg_auth_fail(src, user_id)
return self.msg_auth_fail(src, user_id)
elif fc == self.FC_DOOR_STATUS:
if self.cb_door_status_update is not None:
status = int.from_bytes(msg_data[:1], "little", signed=True)
self.cb_door_status_update(src, status)
self.cb_door_status_update(src, msg_data[:1] == self.DATA_DOOR_STATUS_OPEN)
return self.NO_MESSAGE
else:
return self.NO_MESSAGE
......
import redis
import logging
from acs_can_proto import acs_can_proto
class acs_database(object):
"""
......@@ -33,9 +32,11 @@ class acs_database(object):
# Doors can be disabled to prevent access. Or switched to learn mode where authorization request
# is interpreted that door is unlocked and user is added to database and given access to source door.
DOOR_MODE_DISABLE = 0
DOOR_MODE_ENABLED = 1
DOOR_MODE_LEARN = 2
DOOR_MODE_DISABLE = b"off"
DOOR_MODE_ENABLED = b"on"
DOOR_MODE_LEARN = b"learn"
DOOR_STATUS_OPEN = b"open"
DOOR_STATUS_CLOSED = b"closed"
def __init__(self, host=__DEFAULT_HOST, port=__DEFAULT_PORT):
# create database connection
......@@ -79,6 +80,12 @@ class acs_database(object):
# If returned cursor is 0 then end was reached.
return (cursor, users)
# Return portition of groups (depending on the cursor value).
def get_groups(self, cursor:int=0):
cursor, users = self.__rclient_user.scan(cursor, ".*", 15)
# If returned cursor is 0 then end was reached.
return (cursor, users)
# Return created group's name, None if failed.
def create_group_for_panel(self, reader_addr:int) -> str:
group = "{}{}".format(self.__NONAME_GRP_PREFIX, reader_addr)
......@@ -89,15 +96,15 @@ class acs_database(object):
# Return the number of readers that were added,
# not including all the readers already present.
def add_panels_to_group(self, group:str, readers:list) -> int:
def add_panels_to_group(self, group:str, *readers) -> int:
for reader_addr in readers:
if self.__rclient_door.llen(reader_addr) == 0:
self.__rclient_door.rpush(reader_addr, self.DOOR_MODE_ENABLED, acs_can_proto.DATA_DOOR_STATUS_OPEN)
return self.__rclient_group.sadd(group, readers)
self.__rclient_door.rpush(reader_addr, self.DOOR_MODE_ENABLED, self.DOOR_STATUS_CLOSED)
return self.__rclient_group.sadd(group, *readers)
# Return the number of readers that were removed from the set,
# not including non existing readers.
def remove_panels_from_group(self, group:str, readers:list) -> int:
def remove_panels_from_group(self, group:str, *readers) -> int:
for reader_addr in readers:
self.__rclient_door.delete(reader_addr)
return self.__rclient_group.srem(group, readers)
......@@ -120,16 +127,24 @@ class acs_database(object):
def log_user_access(self, user_id, reader_addr):
logging.info("User \"{}\" accessed door \"{}\"".format(user_id, reader_addr))
# Mode is one of DOOR_MODE_...
def set_door_mode(self, reader_addr, mode):
self.__rclient_door.lset(reader_addr, self.__DOOR_MODE_IDX, mode)
# Return one of DOOR_MODE_...
def get_door_mode(self, reader_addr):
return self.__rclient_door.lindex(reader_addr, self.__DOOR_MODE_IDX)
# Door open/close status is tracked.
def set_door_status(self, reader_addr, status):
def set_door_is_open(self, reader_addr, is_open:bool):
status = self.DOOR_STATUS_CLOSED
if is_open:
status = self.DOOR_STATUS_OPEN
self.__rclient_door.lset(reader_addr, self.__DOOR_STATUS_IDX, status)
# Door open/close status is tracked. Return data type for FC_DOOR_STATUS
def get_door_status(self, reader_addr):
return self.__rclient_door.lindex(reader_addr, self.__DOOR_STATUS_IDX)
# Door open/close status is tracked.
def is_door_open(self, reader_addr) -> bool:
if self.__rclient_door.lindex(reader_addr, self.__DOOR_STATUS_IDX) == self.DOOR_STATUS_OPEN:
return True
else:
return False
......@@ -4,9 +4,9 @@ import sys
import os
import logging
import time
# For remote debugging add firewall exception e.g. iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5678 -j ACCEPT
# import ptvsd
from helpers import parse_args, format_data
from acs_database import acs_database
from acs_can_proto import acs_can_proto, can_raw_sock
......@@ -83,12 +83,11 @@ class acs_server(object):
def resp_to_auth_req(self, reader_addr, user_id):
if self.debug:
logging.debug("resp_to_auth_req: reader={}, user={}".format(reader_addr, user_id))
mode = self.db.get_door_mode(reader_addr)
if mode is None:
logging.debug("resp_to_auth_req: no door mode!")
if self.debug:
logging.debug("resp_to_auth_req: no door mode!")
mode = self.db.DOOR_MODE_ENABLED # fallback to default
if mode == self.db.DOOR_MODE_ENABLED:
if self.db.is_user_authorized(user_id, reader_addr):
self.db.log_user_access(user_id, reader_addr)
......@@ -102,10 +101,10 @@ class acs_server(object):
return False
# callback for door status update
def door_status_update(self, reader_addr, status):
def door_status_update(self, reader_addr, is_open):
if self.debug:
logging.debug("door_status_update: reader={} open={}".format(reader_addr, status == self.proto.DATA_DOOR_STATUS_OPEN))
self.db.set_door_status(reader_addr, status)
logging.debug("door_status_update: reader={} open={}".format(reader_addr, is_open))
self.db.set_door_is_open(reader_addr, is_open)
# main processing loop
def run(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment