|
|
Back unit Device; interface Uses SysUtils, Classes, Controls, Dialogs; {$DEFINE DEBUG} const MAX_AG_TZ=8; MAX_HOL=16; MAX_TZ=15; MAX_AG=10; MAX_TIME_DIFF=60; MAX_TIME_OUT=5; MAX_TIME_TIME_OUT=60; REF_NAME=1; REF_AG=2; REF_TZ=4; REF_HOL=8; REF_DEV=16; INIT_REF_STATE=REF_NAME OR REF_AG OR REF_TZ OR REF_HOL OR REF_DEV; type TCommand = record cmd: Byte; dev: Byte; bcc: Byte; body: String; crc: Boolean; end; EHKError=class private FMsg: String; FOnMsg: TNotifyEvent; procedure SetMsg(const Value: string); public property Msg: string read FMsg write SetMsg; property OnMsg: TNotifyEvent read FOnMsg write FOnMsg; procedure MsgFmt(const Fmt: string; const Args: array of const); procedure LogComm(Lab: String; p_comm: TCommand); end; TRekord = class private FCardNo: string; Fivent: Byte; Fvreme: TDateTime; procedure SetVreme(hh, min, dd, mm, yy: Byte); public constructor Create; property CardNo: string read FCardNo write FCardNo; property ivent: Byte read Fivent write Fivent; property vreme: TDateTime read Fvreme write Fvreme; end; TDevice = class; TStatus = class private FProcess: Integer; FProcess2: Integer; FState: Integer; FTimeOut: Boolean; FT1: Integer; FNoTimeOut: Integer; FTimeTimeOut: TDateTime; FNewDev: Boolean; FRefState: Integer; WaitForCmd: Boolean; public Rekordi: TList; Owner: TDevice; constructor Create(Value: TDevice); destructor Destroy; override; property Process: Integer read Fprocess write FProcess; property Process2: Integer read Fprocess2 write FProcess2; property State: Integer read FState write FState; property NewDev: Boolean read FNewDev write FNewDev; property RefState: Integer read FRefState write FRefState; property NoTimeOut: Integer read FNoTimeOut write FNoTimeOut; property TimeTimeOut: TDateTime read FTimeTimeOut write FTimeTimeOut; function RecCommand(var Cmd: TCommand; TOut: Boolean): Boolean; function RProcess100(var Cmd: TCommand; TOut: Boolean): Boolean; function RProcess101(var Cmd: TCommand; TOut: Boolean): Boolean; function RProcess103(var Cmd: TCommand; TOut: Boolean): Boolean; function RProcess106(var Cmd: TCommand; TOut: Boolean): Boolean; function RProcess110(var Cmd: TCommand; TOut: Boolean): Boolean; procedure RProcess0001(var Cmd: TCommand; TOut: Boolean); procedure RProcess0003(var Cmd: TCommand; TOut: Boolean); procedure RProcess0005(var Cmd: TCommand; TOut: Boolean); procedure RProcess0100(var Cmd: TCommand; TOut: Boolean); procedure RProcess0101(var Cmd: TCommand; TOut: Boolean); procedure RProcess0103(var Cmd: TCommand; TOut: Boolean); procedure RProcess0200(var Cmd: TCommand; TOut: Boolean); procedure RProcess0201(var Cmd: TCommand; TOut: Boolean); procedure RProcess0203(var Cmd: TCommand; TOut: Boolean); procedure RProcess0300(var Cmd: TCommand; TOut: Boolean); procedure RProcess0301(var Cmd: TCommand; TOut: Boolean); procedure RProcess0303(var Cmd: TCommand; TOut: Boolean); procedure RProcess0401(var Cmd: TCommand; TOut: Boolean); procedure RProcess0403(var Cmd: TCommand; TOut: Boolean); procedure RProcess0405(var Cmd: TCommand; TOut: Boolean); function NextCommand(var Cmd: TCommand): Boolean; function SCmd9(var Cmd: TCommand): Boolean; function SCmd12(var Cmd: TCommand): Boolean; function SCmd13(var Cmd: TCommand): Boolean; function SCmd14(var Cmd: TCommand): Boolean; function SCmd15(var Cmd: TCommand): Boolean; function SCmd16(var Cmd: TCommand): Boolean; function SCmd17(var Cmd: TCommand): Boolean; function SCmd18(var Cmd: TCommand): Boolean; function SCmd19(var Cmd: TCommand): Boolean; function SCmd22(var Cmd: TCommand): Boolean; function SCmd25(var Cmd: TCommand): Boolean; function SCmd26(var Cmd: TCommand): Boolean; function SCmd27(var Cmd: TCommand): Boolean; function SNACK(var Cmd: TCommand): Boolean; function SACK(var Cmd: TCommand): Boolean; function SCmd11(var Cmd: TCommand): Boolean; procedure CalcBCC(var Cmd: TCommand); procedure NextState; end; TBCD = class private FHiLo: Byte; function GetHi: Byte; procedure SetHi(Value: Byte); function GetLo: Byte; procedure SetLo(Value: Byte); procedure SetHiLo(Value: Byte); function GetSHiLo: string; procedure SetSHiLo(Value: string); public constructor Create; property Hi: Byte read GetHi write SetHi; property Lo: Byte read GetLo write SetLo; property HiLo: Byte read FHiLo write SetHiLo; property SHiLo: string read GetSHiLo write SetSHiLo; function BCD2Byte: Byte; procedure SetByte(Value: Byte); end; BCD = TBCD; TDevice = class private FDevNo: Byte; FComCode1: BCD; FComCode2: BCD; FDoorTime: Byte; procedure SetComCode1(Value: Byte); function GetComCode1: Byte; procedure SetComCode2(Value: Byte); function GetComCode2: Byte; function GetSComCode: string; procedure SetSComCode(Value: string); public FId: Integer; FTimeZone: TList; FHolyday: TList; FAccessGroup: TList; FName: TList; Status: TStatus; constructor Create(Value: Integer); destructor Destroy; override; property DevNo: Byte read FDevNo write FDevNo; property ComCode1: Byte read GetComCode1 write SetComCode1; property ComCode2: Byte read GetComCode2 write SetComCode2; property SComCode: string read GetSComCode write SetSComCode; property DoorTime: Byte read FDoorTime write FDoorTime; procedure DoorBlock; procedure DoorOpen; end; TTimeZone = class private FOnHour: BCD; FOnMin: BCD; FOffHour: BCD; FOffMin: BCD; FZoneDays: BCD; FTemp: BCD; procedure SetOnHour(Value: Byte); function GetOnHour: Byte; procedure SetOnMin(Value: Byte); function GetOnMin: Byte; procedure SetOffHour(Value: Byte); function GetOffHour: Byte; procedure SetOffMin(Value: Byte); function GetOffMin: Byte; procedure SetZoneDays(Value: Byte); function GetZoneDays: Byte; procedure SetFromZD(Value: Byte); function GetFromZD: Byte; procedure SetToZD(Value: Byte); function GetToZD: Byte; public FId: Integer; constructor Create(Value: Integer); destructor Destroy; override; property OnHour: Byte read GetOnHour write SetOnHour; property OnMin: Byte read GetOnMin write SetOnMin; property OffHour: Byte read GetOffHour write SetOffHour; property OffMin: Byte read GetOffMin write SetOffMin; property ZoneDays: Byte read GetZoneDays write SetZoneDays; property FromZD: Byte read GetFromZD write SetFromZD; property ToZD: Byte read GetToZD write SetToZD; property id_base: Integer read FId; end; THolyday = class private FHDate: BCD; FHMonth: BCD; procedure SetHDate(Value: Byte); function GetHDate: Byte; procedure SetHMonth(Value: Byte); function GetHMonth: Byte; function GetDate: TDate; procedure SetDate(Value: TDate); public FId: Integer; constructor Create(Value: Integer); destructor Destroy; override; property HDate: Byte read GetHDate write SetHDate; property HMonth: Byte read GetHMonth write SetHMonth; property Date: TDate read GetDate write SetDate; end; TAccessGroup = class private FAz12, FAz34, FAz56, FAz78: Byte; procedure SetAz12(Value: Byte); function GetAz12: Byte; procedure SetAz34(Value: Byte); function GetAz34: Byte; procedure SetAz56(Value: Byte); function GetAz56: Byte; procedure SetAz78(Value: Byte); function GetAz78: Byte; public FId: Integer; constructor Create(Value: Integer); destructor Destroy; override; property Az12: Byte read GetAz12 write SetAz12; property Az34: Byte read GetAz34 write SetAz34; property Az56: Byte read GetAz56 write SetAz56; property Az78: Byte read GetAz78 write SetAz78; property id_base: Integer read FId; procedure SetAz(No: Integer; Value: Byte); function GetAZ(No: Integer): Byte; end; TName = class private FCardNo: string; FName: string; FAG: Byte; procedure SetCardNo(Value: string); procedure SetName(Value: string); procedure SetAG(Value: Byte); public FId: Integer; constructor Create(Value: Integer); destructor Destroy; override; property CardNo: string read FCardNo write SetCardNo; property Name: string read FName write SetName; property AG: Byte read FAG write SetAG; end; function BCDByte2Byte(Value: Byte): Byte; function BCDByte2String(Value: Byte): string; function Str2BCDByte(Value: string; prv, vtor: Integer): Byte; function Byte2BCDByte(Value: Byte): Byte; procedure FreeList(Value: TList); var HKError: EHKError; p_MAX_AG_TZ, p_MAX_HOL, p_MAX_TZ, p_MAX_AG: Integer; p_MAX_TIME_DIFF, p_MAX_TIME_OUT, p_MAX_TIME_TIME_OUT: Integer; implementation // TBCD constructor TBCD.Create; begin inherited Create; FHiLo:=0; end; function TBCD.GetHi: Byte; begin Result := FHiLo shr 4; end; procedure TBCD.SetHi(Value: Byte); begin if Value<10 then FHiLo:=(FHiLo and $0F) or (Value shl 4) else HKError.MsgFmt('SetHi Value %d > 9',[Value]); end; function TBCD.GetLo: Byte; begin Result := FHiLo and $0F; end; procedure TBCD.SetLo(Value: Byte); begin if Value<10 then FHiLo:=(FHiLo and $F0) or Value else HKError.MsgFmt('SetLo Value %d > 9',[Value]); end; procedure TBCD.SetHiLo(Value: Byte); begin if Value<>FHiLo then if ((((Value and $F0) shr 4)>9) or ((Value and $0F)>9)) then HKError.MsgFmt('SetHiLo Invalid Value %d',[Value]) else FHiLo:=Value; end; function TBCD.GetSHiLo: string; begin Result:=IntToStr((FHiLo and $F0) shr 4)+IntToStr(FHiLo and $0F); end; procedure TBCD.SetSHiLo(Value: string); begin SetHiLo(StrToInt(Value)); end; function TBCD.BCD2Byte: Byte; begin Result:=Hi*10+Lo; end; procedure TBCD.SetByte(Value: Byte); begin if Value<100 then begin SetHi(Value div 10); SetLo(Value mod 10); end else HKError.MsgFmt('SetByte Invalid Value %d',[Value]); end; // TTimeZone. constructor TTimeZone.Create(Value: Integer); begin inherited Create; FOnHour:=TBCD.Create; FOnMin:=TBCD.Create; FOffHour:=TBCD.Create; FOffMin:=TBCD.Create; FZoneDays:=TBCD.Create; FTemp:=TBCD.Create; FId:=Value; end; destructor TTimeZone.Destroy; begin FTemp.Free; FZoneDays.Free; FOffMin.Free; FOffHour.Free; FOnMin.Free; FOnHour.Free; inherited Destroy; end; procedure TTimeZone.SetOnHour(Value: Byte); begin if Value<>FOnHour.HiLo then begin if BCDByte2Byte(Value)<24 then FOnHour.HiLo:=Value else HKError.MsgFmt('SetOnHour Invalid Value %d',[Value]); end; end; function TTimeZone.GetOnHour: Byte; begin Result:=FOnHour.HiLo; end; procedure TTimeZone.SetOnMin(Value: Byte); begin if Value<>FOnMin.HiLo then begin if BCDByte2Byte(Value)<60 then FOnMin.HiLo:=Value else HKError.MsgFmt('SetOnMin Invalid Value %d',[Value]); end; end; function TTimeZone.GetOnMin: Byte; begin Result:=FOnMin.HiLo; end; procedure TTimeZone.SetOffHour(Value: Byte); begin if Value<>FOffHour.HiLo then begin if BCDByte2Byte(Value)<24 then FOffHour.HiLo:=Value else HKError.MsgFmt('SetOffHour Invalid Value %d',[Value]); end; end; function TTimeZone.GetOffHour: Byte; begin Result:=FOffHour.HiLo; end; procedure TTimeZone.SetOffMin(Value: Byte); begin if Value<>FOffMin.HiLo then begin if BCDByte2Byte(Value)<60 then FOffMin.HiLo:=Value else HKError.MsgFmt('SetOffMin Invalid Value %d',[Value]); end; end; function TTimeZone.GetOffMin: Byte; begin Result:=FOffMin.HiLo; end; procedure TTimeZone.SetZoneDays(Value: Byte); begin if Value<>FZoneDays.HiLo then begin FTemp.HiLo:=Value; if ((FTemp.Hi<8) and (FTemp.Lo<9) and (FTemp.Hi<=FTemp.Lo)) then FZoneDays.HiLo:=Value else HKError.MsgFmt('SetZoneDays Invalid Value %d',[Value]); end; end; procedure TTimeZone.SetFromZD(Value: Byte); begin if Value<>FZoneDays.Hi then if Value < 8 then FZoneDays.Hi:=Value else HKError.MsgFmt('SetFromZD Invalid Value %d',[Value]); end; procedure TTimeZone.SetToZD(Value: Byte); begin if Value<>FZoneDays.Lo then if Value < 9 then FZoneDays.Lo:=Value else HKError.MsgFmt('SetToZD Invalid Value %d',[Value]); end; function TTimeZone.GetZoneDays: Byte; begin Result:=FZoneDays.HiLo; end; function TTimeZone.GetFromZD: Byte; begin Result:=FZoneDays.Hi; end; function TTimeZone.GetToZD: Byte; begin Result:=FZoneDays.Lo; end; // THolyday. constructor THolyday.Create(Value: Integer); begin inherited Create; FHDate:=TBCD.Create; FHMonth:=TBCD.Create; FId:=Value; end; destructor THolyday.Destroy; begin FHDate.Free; FHMonth.Free; inherited Destroy; end; procedure THolyday.SetHDate(Value: Byte); begin if Value<>FHDate.HiLo then if ((BCDByte2Byte(Value)>0) and (BCDByte2Byte(Value)<32)) then FHDate.HiLo:=Value else HKError.MsgFmt('SetHDate Invalid Value %d',[Value]); end; function THolyday.GetHDate: Byte; begin Result:=FHDate.HiLo; end; procedure THolyday.SetHMonth(Value: Byte); begin if Value<>FHMonth.HiLo then if ((BCDByte2Byte(Value)>0) and (BCDByte2Byte(Value)<13)) then FHMonth.HiLo:=Value else HKError.MsgFmt('SetHMonth Invalid Value %d',[Value]); end; function THolyday.GetHMonth: Byte; begin Result:=FHMonth.HiLo; end; function THolyday.GetDate: TDate; var Y,M,D: Word; begin DecodeDate(Now, Y, M, D); Result:=EncodeDate(Y, FHMonth.BCD2Byte, FHDate.BCD2Byte); end; procedure THolyday.SetDate(Value: TDate); var Y,M,D: Word; begin DecodeDate(Value, Y, M, D); if (M<>FHMonth.BCD2Byte) then FHMonth.SetByte(M); if (D<>FHDate.BCD2Byte) then FHDate.SetByte(D); end; // TAccessGroup. constructor TAccessGroup.Create(Value: Integer); begin inherited Create; FId:=Value; end; destructor TAccessGroup.Destroy; begin inherited Destroy; end; procedure TAccessGroup.SetAz12(Value: Byte); begin if Value<>FAz12 then FAz12:=Value; end; function TAccessGroup.GetAz12: Byte; begin Result:=FAz12; end; procedure TAccessGroup.SetAz34(Value: Byte); begin if Value<>FAz34 then FAz34:=Value; end; function TAccessGroup.GetAz34: Byte; begin Result:=FAz34; end; procedure TAccessGroup.SetAz56(Value: Byte); begin if Value<>FAz56 then FAz56:=Value; end; function TAccessGroup.GetAz56: Byte; begin Result:=FAz56; end; procedure TAccessGroup.SetAz78(Value: Byte); begin if Value<>FAz78 then FAz78:=Value; end; function TAccessGroup.GetAz78: Byte; begin Result:=FAz78; end; procedure TAccessGroup.SetAz(No: Integer; Value: Byte); begin if Value<16 then begin case No of 1: FAz12:=(FAz12 and $0F) or (Value shl 4); 2: FAz12:=(FAz12 and $F0) or Value; 3: FAz34:=(FAz34 and $0F) or (Value shl 4); 4: FAz34:=(FAz34 and $F0) or Value; 5: FAz56:=(FAz56 and $0F) or (Value shl 4); 6: FAz56:=(FAz56 and $F0) or Value; 7: FAz78:=(FAz78 and $0F) or (Value shl 4); 8: FAz78:=(FAz78 and $F0) or Value; end; end else HKError.MsgFmt('SetAz Invalid Value %d > 15',[Value]); end; function TAccessGroup.GetAZ(No: Integer): Byte; begin Result:=0; case No of 1: Result:=FAz12 shr 4; 2: Result:=FAz12 and $0F; 3: Result:=FAz34 shr 4; 4: Result:=FAz34 and $0F; 5: Result:=FAz56 shr 4; 6: Result:=FAz56 and $0F; 7: Result:=FAz78 shr 4; 8: Result:=FAz78 and $0F; end; end; // TName. constructor TName.Create(Value: Integer); begin inherited Create; FId:=Value; end; destructor TName.Destroy; begin inherited Destroy; end; procedure TName.SetCardNo(Value: string); begin if Value<>FCardNo then FCardNo:=Value; end; procedure TName.SetName(Value: string); begin if Value<>FName then FName:=Value; end; procedure TName.SetAG(Value: Byte); begin if FAG<>Value then if Value>p_MAX_AG then HKError.MsgFmt('SetAg Value %d > %d',[Value,p_MAX_AG]) else FAG:=Value; end; // TStatus. constructor TStatus.Create(Value: TDevice); begin inherited Create; Owner:=Value; FProcess:=1; FProcess2:=0; FState:=0; FTimeOut:=False; FNewDev:=False; FRefState:=INIT_REF_STATE; FNoTimeOut:=0; WaitForCmd:=False; end; destructor TStatus.Destroy; begin FreeList(Rekordi); inherited Destroy; end; function TStatus.RecCommand(var Cmd: TCommand; TOut: Boolean): Boolean; begin Result:=False; if (Cmd.dev=Owner.DevNo) or (Tout) then begin case Process of 0: case Process2 of 0: case State of 1: RProcess0001(Cmd, TOut); 3: RProcess0003(Cmd, TOut); 5: RProcess0005(Cmd, TOut); else HKError.MsgFmt('RecCommand Invalid State %d',[State]); end; 1: case State of 0: RProcess0100(Cmd, TOut); 1: RProcess0101(Cmd, TOut); 3: RProcess0103(Cmd, TOut); else HKError.MsgFmt('RecCommand Invalid State %d',[State]); end; 2: case State of 0: RProcess0200(Cmd, TOut); 1: RProcess0201(Cmd, TOut); 3: RProcess0203(Cmd, TOut); else HKError.MsgFmt('RecCommand Invalid State %d',[State]); end; 3: case State of 0: RProcess0300(Cmd, TOut); 1: RProcess0301(Cmd, TOut); 3: RProcess0303(Cmd, TOut); else HKError.MsgFmt('RecCommand Invalid State %d',[State]); end; 4: case State of 1: RProcess0401(Cmd, TOut); 3: RProcess0403(Cmd, TOut); 5: RProcess0405(Cmd, TOut); else HKError.MsgFmt('RecCommand Invalid State %d',[State]); end; else HKError.MsgFmt('RecCommand Invalid Process2 %d',[Process2]); end; 1: case State of 0: Result:=RProcess100(Cmd, TOut); 1: Result:=RProcess101(Cmd, TOut); 3: Result:=RProcess103(Cmd, TOut); 6: Result:=RProcess106(Cmd, TOut); 10: Result:=RProcess110(Cmd, TOut); end; else HKError.MsgFmt('RecCommand Invalid State %d',[State]); end; end; end; function TStatus.RProcess100(var Cmd: TCommand; TOut: Boolean): Boolean; begin Result:=False; NewDev:=False; NextState; end; function TStatus.RProcess101(var Cmd: TCommand; TOut: Boolean): Boolean; begin Result:=False; State:=1; Process:=1; NewDev:=True; if not TOut then begin if Cmd.cmd=9 then begin FT1:=0; FT1:=(ord(Cmd.body[2]) shl 8) or (ord(Cmd.body[1])); Process:=1; if FT1>0 then begin State:=3; NewDev:=False; FreeList(Rekordi); Rekordi:=TList.Create; end else begin Result:=RProcess110(Cmd,TOut); end; end else HKError.Msg:='RP101 Not CMD9'; end else NextState; end; function TStatus.RProcess103(var Cmd: TCommand; TOut: Boolean): Boolean; var i,j: Integer; begin Result:=False; State:=1; Process:=1; NewDev:=True; if not TOut then begin if FT1>0 then begin if Cmd.cmd=10 then begin i:=Rekordi.Add(TRekord.Create); with TRekord(Rekordi.Items[i]) do begin CardNo:=''; for j:=1 to 7 do CardNo:=CardNo+BCDByte2String(ord(Cmd.body[j])); ivent:=BCDByte2Byte(ord(Cmd.body[8])); SetVreme(ord(Cmd.body[9]),ord(Cmd.body[10]),ord(Cmd.body[12]),ord(Cmd.body[13]),ord(Cmd.body[14])); end; Process:=1; State:=3; NewDev:=False; Dec(FT1); end else HKError.Msg:='RP103 Not CMD10'; end else begin if Cmd.cmd=14 then begin Process:=1; State:=6; NewDev:=False; Result:=False; end else HKError.Msg:='RP103 Not CMD14'; end; end; end; function TStatus.RProcess106(var Cmd: TCommand; TOut: Boolean): Boolean; begin Result:=False; State:=6; Process:=1; NewDev:=False; Inc(FT1); if not TOut then begin if (Cmd.cmd=$F3) then begin RProcess110(Cmd,TOut); Result:=True; end else begin if FT1>3 then begin Result:=RProcess110(Cmd,TOut); end; HKError.Msg:='RP106 Not ACK'; end; end else begin if FT1>3 then begin Result:=RProcess110(Cmd,TOut); end; end; end; function TStatus.RProcess110(var Cmd: TCommand; TOut: Boolean): Boolean; begin Result:=False; NextState; end; procedure TStatus.RProcess0001(var Cmd: TCommand; TOut: Boolean); var cas, min, sec, den, mes, god: Word; sega: TDateTime; dev_sega: TDateTime; begin RefState:=(RefState and (not REF_DEV)); if not TOut then begin if (Cmd.cmd=16) then begin sega:=Now; cas:=BCDByte2Byte(ord(Cmd.body[1])); min:=BCDByte2Byte(ord(Cmd.body[2])); sec:=BCDByte2Byte(ord(Cmd.body[3])); den:=BCDByte2Byte(ord(Cmd.body[5])); mes:=BCDByte2Byte(ord(Cmd.body[6])); god:=BCDByte2Byte(ord(Cmd.body[7])); if god>80 then god:=god+1900 else god:=god+2000; dev_sega:=EncodeDate(god, mes, den)+EncodeTime(cas,min,sec,0); if Trunc(abs(sega-dev_sega)*86400)>p_MAX_TIME_DIFF then begin State:=3; Process:=0; Process2:=0; NewDev:=False; end else begin State:=5; Process:=0; Process2:=0; NewDev:=False; end; end else begin HKError.Msg:='RP0001 Not CMD16'; State:=1; Process:=0; Process2:=0; NewDev:=False; end; end else begin State:=1; Process:=0; Process2:=0; NewDev:=True; end; end; procedure TStatus.RProcess0003(var Cmd: TCommand; TOut: Boolean); begin if not TOut then begin if not (Cmd.cmd=$F3) then HKError.Msg:='RP0003 Not ACK'; end else begin HKError.Msg:='RP0003 TimeOut'; end; State:=1; Process:=0; Process2:=0; NewDev:=True; end; procedure TStatus.RProcess0005(var Cmd: TCommand; TOut: Boolean); begin if not TOut then begin if not (Cmd.cmd=$F3) then begin State:=5; Process:=0; Process2:=0; NewDev:=True; HKError.Msg:='RP0005 Not ACK'; end else begin NextState; end; end else begin State:=5; Process:=0; Process2:=0; NewDev:=True; HKError.Msg:='RP0005 TimeOut'; end; end; procedure TStatus.RProcess0100(var Cmd: TCommand; TOut: Boolean); begin NewDev:=True; Process:=0; Process2:=1; State:=1; FT1:=0; end; procedure TStatus.RProcess0101(var Cmd: TCommand; TOut: Boolean); begin RefState:=(RefState and (not REF_HOL)); if not TOut then begin if (Cmd.cmd=27) and (ord(Cmd.body[1])=FT1+1) then begin if (ord(Cmd.body[2])=THolyday(owner.FHolyday.Items[FT1]).HDate) and (ord(Cmd.body[3])=THolyday(owner.FHolyday.Items[FT1]).HMonth) then begin if FT1=p_MAX_HOL-1 then begin NextState; end else begin Inc(FT1); State:=1; Process:=0; Process2:=1; NewDev:=False; end; end else begin State:=3; Process:=0; Process2:=1; NewDev:=False; end; end else begin State:=1; Process:=0; Process2:=1; NewDev:=False; HKError.Msg:='RP0101 Not CMD27'; end; end else begin State:=1; Process:=0; Process2:=1; NewDev:=True; end; end; procedure TStatus.RProcess0103(var Cmd: TCommand; TOut: Boolean); begin if not TOut then begin if not (Cmd.cmd=$F3) then HKError.Msg:='RP0103 Not ACK'; end else begin HKError.Msg:='RP0103 TimeOut'; end; State:=1; Process:=0; Process2:=1; NewDev:=False; end; procedure TStatus.RProcess0200(var Cmd: TCommand; TOut: Boolean); begin NewDev:=True; Process:=0; Process2:=2; State:=1; FT1:=0; end; procedure TStatus.RProcess0201(var Cmd: TCommand; TOut: Boolean); begin RefState:=(RefState and (not REF_TZ)); if not TOut then begin if (Cmd.cmd=25) and (ord(Cmd.body[1])=FT1+1) then begin if (ord(Cmd.body[2])=TTimeZone(owner.FTimeZone.Items[FT1]).OnHour) and (ord(Cmd.body[3])=TTimeZone(owner.FTimeZone.Items[FT1]).OnMin) and (ord(Cmd.body[4])=TTimeZone(owner.FTimeZone.Items[FT1]).OffHour) and (ord(Cmd.body[5])=TTimeZone(owner.FTimeZone.Items[FT1]).OffMin) and (ord(Cmd.body[6])=TTimeZone(owner.FTimeZone.Items[FT1]).ZoneDays) then begin if FT1=p_MAX_TZ-1 then begin NextState; end else begin Inc(FT1); State:=1; Process:=0; Process2:=2; NewDev:=False; end; end else begin State:=3; Process:=0; Process2:=2; NewDev:=False; end; end else begin State:=1; Process:=0; Process2:=2; NewDev:=False; HKError.Msg:='RP0201 Not CMD25'; end; end else begin State:=1; Process:=0; Process2:=2; NewDev:=True; end; end; procedure TStatus.RProcess0203(var Cmd: TCommand; TOut: Boolean); begin if not TOut then begin if not (Cmd.cmd=$F3) then HKError.Msg:='RP0203 Not ACK'; end else begin HKError.Msg:='RP0203 TimeOut'; end; State:=1; Process:=0; Process2:=2; NewDev:=False; end; procedure TStatus.RProcess0300(var Cmd: TCommand; TOut: Boolean); begin NewDev:=True; Process:=0; Process2:=3; State:=1; FT1:=0; end; procedure TStatus.RProcess0301(var Cmd: TCommand; TOut: Boolean); begin RefState:=(RefState and (not REF_AG)); if not TOut then begin if (Cmd.cmd=26) and (ord(Cmd.body[1])=FT1+1) then begin {$ifdef debug} HKError.Msg:=Format('dev12=%x dev34=%x dev56=%x dev78=%x my12=%x my34=%x my56=%x my78=%x', [ord(Cmd.body[2]),ord(Cmd.body[3]),ord(Cmd.body[4]),ord(Cmd.body[5]),TAccessGroup(owner.FAccessGroup.Items[FT1]).Az12, TAccessGroup(owner.FAccessGroup.Items[FT1]).Az34,TAccessGroup(owner.FAccessGroup.Items[FT1]).Az56, TAccessGroup(owner.FAccessGroup.Items[FT1]).Az78]); {$endif} if (ord(Cmd.body[2])=TAccessGroup(owner.FAccessGroup.Items[FT1]).Az12) and (ord(Cmd.body[3])=TAccessGroup(owner.FAccessGroup.Items[FT1]).Az34) and (ord(Cmd.body[4])=TAccessGroup(owner.FAccessGroup.Items[FT1]).Az56) and (ord(Cmd.body[5])=TAccessGroup(owner.FAccessGroup.Items[FT1]).Az78) then begin if FT1=p_MAX_AG-1 then begin NextState; end else begin Inc(FT1); State:=1; Process:=0; Process2:=3; NewDev:=False; end; end else begin State:=3; Process:=0; Process2:=3; NewDev:=False; end; end else begin State:=1; Process:=0; Process2:=3; NewDev:=False; HKError.Msg:='RP0301 Not CMD26'; end; end else begin State:=1; Process:=0; Process2:=3; NewDev:=True; end; end; procedure TStatus.RProcess0303(var Cmd: TCommand; TOut: Boolean); begin if not TOut then begin if not (Cmd.cmd=$F3) then HKError.Msg:='RP0303 Not ACK'; end else begin HKError.Msg:='RP0303 TimeOut'; end; State:=1; Process:=0; Process2:=3; NewDev:=False; end; procedure TStatus.RProcess0401(var Cmd: TCommand; TOut: Boolean); begin RefState:=(RefState and (not REF_NAME)); if not TOut then begin if (Cmd.cmd=$F3) then begin FT1:=0; State:=3; Process:=0; Process2:=4; NewDev:=False; end else begin State:=1; Process:=0; Process2:=4; NewDev:=True; HKError.Msg:='RP0401 Not ACK'; end; end else begin State:=1; Process:=0; Process2:=4; NewDev:=True; HKError.Msg:='RP0401 TimeOut'; end; end; procedure TStatus.RProcess0403(var Cmd: TCommand; TOut: Boolean); begin if not TOut then begin if (Cmd.cmd=$F3) then begin if (FT1+1) < Owner.FName.Count then begin Inc(FT1); State:=3; Process:=0; Process2:=4; NewDev:=False; end else begin State:=5; Process:=0; Process2:=4; NewDev:=False; end; end else begin State:=1; Process:=0; Process2:=4; NewDev:=True; HKError.Msg:='RP0403 Not ACK'; end; end else begin State:=1; Process:=0; Process2:=4; NewDev:=True; HKError.Msg:='RP0403 TimeOut'; end; end; procedure TStatus.RProcess0405(var Cmd: TCommand; TOut: Boolean); begin if not TOut then begin if (Cmd.cmd=$F3) then begin NextState; end else begin State:=1; Process:=0; Process2:=4; NewDev:=True; HKError.Msg:='RP0405 Not ACK'; end; end else begin State:=1; Process:=0; Process2:=4; NewDev:=True; HKError.Msg:='RP0405 TimeOut'; end; end; procedure TStatus.NextState; begin if (RefState and REF_DEV)<>0 then begin State:=1; Process:=0; Process2:=0; FT1:=0; NewDev:=True; end else if (RefState and REF_HOL)<>0 then begin State:=1; Process:=0; Process2:=1; FT1:=0; NewDev:=True; end else if (RefState and REF_TZ)<>0 then begin State:=1; Process:=0; Process2:=2; FT1:=0; NewDev:=True; end else if (RefState and REF_AG)<>0 then begin State:=1; Process:=0; Process2:=3; FT1:=0; NewDev:=True; end else if (RefState and REF_NAME)<>0 then begin State:=1; Process:=0; Process2:=4; FT1:=0; NewDev:=True; end else begin FT1:=0; State:=1; Process:=1; Process2:=0; NewDev:=True; end; end; function TStatus.NextCommand(var Cmd: TCommand): Boolean; begin Result:=True; case Process of 0: case Process2 of 0: case State of 0: SCmd16(Cmd); 1: SCmd16(Cmd); 3: SCmd15(Cmd); 5: SCmd22(Cmd); else begin Result:=False; HKError.MsgFmt('NextCommand State=%d',[State]); end; end; 1: case State of 0: SCmd27(Cmd); 1: SCmd27(Cmd); 3: SCmd19(Cmd); else begin Result:=False; HKError.MsgFmt('NextCommand State=%d',[State]); end; end; 2: case State of 0: SCmd25(Cmd); 1: SCmd25(Cmd); 3: SCmd17(Cmd); else begin Result:=False; HKError.MsgFmt('NextCommand State=%d',[State]); end; end; 3: case State of 0: SCmd26(Cmd); 1: SCmd26(Cmd); 3: SCmd18(Cmd); else begin Result:=False; HKError.MsgFmt('NextCommand State=%d',[State]); end; end; 4: case State of 1: SCmd12(Cmd); 3: SCmd13(Cmd); 5: SCmd14(Cmd); else begin Result:=False; HKError.MsgFmt('NextCommand State=%d',[State]); end; end; else begin Result:=False; HKError.MsgFmt('NextCommand Process2=%d',[Process2]); end; end; 1: case State of 0: SCmd9(Cmd); 1: SCmd9(Cmd); 3: SACK(Cmd); 6: SCmd11(Cmd); 10: SCmd9(Cmd); end; else begin Result:=False; HKError.MsgFmt('NextCommand State=%d',[State]); end; end; end; function TStatus.SCmd9(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=9; Cmd.dev:=Owner.DevNo; Cmd.body:=''; CalcBCC(Cmd); end; function TStatus.SCmd12(var Cmd: TCommand): Boolean; var temp: Word; begin Result:=True; Cmd.cmd:=12; Cmd.dev:=Owner.DevNo; temp:=Owner.FName.Count; Cmd.body:=chr(Byte(temp and $00FF))+chr(Byte(temp shl 8)); CalcBCC(Cmd); end; function TStatus.SCmd13(var Cmd: TCommand): Boolean; var temp: string; ime: TName; begin Result:=True; Cmd.cmd:=13; Cmd.dev:=Owner.DevNo; Cmd.body:=''; ime:=TName(Owner.FName.Items[FT1]); if Length(ime.CardNo)<14 then begin Result:=False; HKError.Msg:='Bad CardNo'; end else begin Cmd.body:=chr(Str2BCDByte(ime.CardNo,1,2))+chr(Str2BCDByte(ime.CardNo,3,4))+ chr(Str2BCDByte(ime.CardNo,5,6))+chr(Str2BCDByte(ime.CardNo,7,8))+ chr(Str2BCDByte(ime.CardNo,9,10))+chr(Str2BCDByte(ime.CardNo,11,12))+ chr(Str2BCDByte(ime.CardNo,13,14))+#$0F; temp:=Copy(ime.Name,1,16); while Length(temp)<16 do temp:=temp+' '; Cmd.body:=Cmd.body+#0+chr(Ime.AG)+temp+#$FF; end; CalcBCC(Cmd); end; function TStatus.SCmd14(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=14; Cmd.dev:=Owner.DevNo; Cmd.body:=''; CalcBCC(Cmd); end; function TStatus.SCmd15(var Cmd: TCommand): Boolean; var vrs: string; vreme: TDateTime; dw: Integer; begin Result:=True; Cmd.cmd:=15; Cmd.dev:=Owner.DevNo; vreme:=Now; vrs:=FormatDateTime('hhnnssddmmyy',vreme); Cmd.body:=chr(Byte2BCDByte(StrToInt(Copy(vrs,1,2)))); Cmd.body:=Cmd.body+chr(Byte2BCDByte(StrToInt(Copy(vrs,3,2)))); Cmd.body:=Cmd.body+chr(Byte2BCDByte(StrToInt(Copy(vrs,5,2)))); dw:=DayOfWeek(vreme); if dw=1 then dw:=7 else Dec(dw); Cmd.body:=Cmd.body+chr(Byte2BCDByte(dw)); Cmd.body:=Cmd.body+chr(Byte2BCDByte(StrToInt(Copy(vrs,7,2)))); Cmd.body:=Cmd.body+chr(Byte2BCDByte(StrToInt(Copy(vrs,9,2)))); Cmd.body:=Cmd.body+chr(Byte2BCDByte(StrToInt(Copy(vrs,11,2)))); CalcBCC(Cmd); end; function TStatus.SCmd16(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=16; Cmd.dev:=Owner.DevNo; Cmd.body:=''; CalcBCC(Cmd); end; function TStatus.SCmd17(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=17; Cmd.dev:=Owner.DevNo; Cmd.body:=chr(FT1+1); if owner.FTimeZone.Count > FT1 then begin with TTimeZone(owner.FTimeZone.Items[FT1]) do begin Cmd.body:=Cmd.body+chr(OnHour); Cmd.body:=Cmd.body+chr(OnMin); Cmd.body:=Cmd.body+chr(OffHour); Cmd.body:=Cmd.body+chr(OffMin); Cmd.body:=Cmd.body+chr(ZoneDays); end; end else begin Cmd.body:=Cmd.body+chr(0); Cmd.body:=Cmd.body+chr(0); Cmd.body:=Cmd.body+chr(0); Cmd.body:=Cmd.body+chr(0); Cmd.body:=Cmd.body+chr(0); end; CalcBCC(Cmd); end; function TStatus.SCmd18(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=18; Cmd.dev:=Owner.DevNo; Cmd.body:=chr(FT1+1); if owner.FAccessGroup.Count > FT1 then begin with TAccessGroup(owner.FAccessGroup.Items[FT1]) do begin Cmd.body:=Cmd.body+chr(Az12); Cmd.body:=Cmd.body+chr(Az34); Cmd.body:=Cmd.body+chr(Az56); Cmd.body:=Cmd.body+chr(Az78); end; end else Cmd.body:=Cmd.body+chr(0)+chr(0)+chr(0)+chr(0); CalcBCC(Cmd); end; function TStatus.SCmd19(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=19; Cmd.dev:=Owner.DevNo; Cmd.body:=chr(FT1+1); if owner.FHolyday.Count > FT1 then begin with THolyday(owner.FHolyday.Items[FT1]) do begin Cmd.body:=Cmd.body+chr(HDate); Cmd.body:=Cmd.body+chr(HMonth); end; end else Cmd.body:=Cmd.body+chr(0)+chr(0); CalcBCC(Cmd); end; function TStatus.SCmd22(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=22; Cmd.dev:=Owner.DevNo; Cmd.body:=chr(owner.DoorTime); CalcBCC(Cmd); end; function TStatus.SCmd25(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=25; Cmd.dev:=Owner.DevNo; Cmd.body:=chr(FT1+1); CalcBCC(Cmd); end; function TStatus.SCmd26(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=26; Cmd.dev:=Owner.DevNo; Cmd.body:=chr(FT1+1); CalcBCC(Cmd); end; function TStatus.SCmd27(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=27; Cmd.dev:=Owner.DevNo; Cmd.body:=chr(FT1+1); CalcBCC(Cmd); end; function TStatus.SNACK(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=$F6; Cmd.dev:=Owner.DevNo; Cmd.body:=''; CalcBCC(Cmd); end; function TStatus.SACK(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=$F3; Cmd.dev:=Owner.DevNo; Cmd.body:=''; CalcBCC(Cmd); end; function TStatus.SCmd11(var Cmd: TCommand): Boolean; begin Result:=True; Cmd.cmd:=11; Cmd.dev:=Owner.DevNo; Cmd.body:=''; CalcBCC(Cmd); end; procedure TStatus.CalcBCC(var Cmd: TCommand); var i: Integer; begin Cmd.bcc:=Cmd.cmd xor Cmd.dev; for i:=1 to Length(Cmd.body) do Cmd.bcc:=Cmd.bcc xor ord(Cmd.body[i]); end; // TRekord. constructor TRekord.Create; begin inherited Create; end; procedure TRekord.SetVreme(hh, min, dd, mm, yy: Byte); var i: Word; begin try i:=BCDByte2Byte(yy); if i>80 then i:=i+1900 else i:=i+2000; Fvreme:=EncodeDate(i,BCDByte2Byte(mm),BCDByte2Byte(dd))+ EncodeTime(BCDByte2Byte(hh),BCDByte2Byte(min),0,0); except FVreme:=Now; end; end; // TDevice constructor TDevice.Create(Value: Integer); begin inherited Create; FTimeZone:=TList.Create; FHolyday:=TList.Create; FAccessGroup:=TList.Create; FName:=TList.Create; FComCode1:=TBCD.Create; FComCode2:=TBCD.Create; Status:=TStatus.Create(self); FId:=Value; end; destructor TDevice.Destroy; begin Status.Free; FComCode2.Free; FComCode1.Free; FreeList(FName); FreeList(FAccessGroup); FreeList(FHolyday); FreeList(FTimeZone); inherited Destroy; end; procedure TDevice.SetComCode1(Value: Byte); begin if Value<>FComCode1.HiLo then FComCode1.HiLo:=Value; end; function TDevice.GetComCode1: Byte; begin Result:=FComCode1.HiLo; end; procedure TDevice.SetComCode2(Value: Byte); begin if Value<>FComCode2.HiLo then FComCode2.HiLo:=Value; end; function TDevice.GetComCode2: Byte; begin Result:=FComCode2.HiLo; end; function TDevice.GetSComCode: string; begin Result:=Format('%2d%2d',[FComCode1.BCD2Byte, FComCode2.BCD2Byte]); end; procedure TDevice.SetSComCode(Value: string); var temp1, temp2: BCD; begin Value:=Trim(Value); if Length(Value)=4 then begin temp1.Create; temp2.Create; try try temp1.Hi:=StrToInt(Value[1]); temp1.Lo:=StrToInt(Value[2]); temp2.Hi:=StrToInt(Value[3]); temp2.Lo:=StrToInt(Value[4]); FComCode1.HiLo:=temp1.HiLo; FComCode2.HiLo:=temp2.HiLo; except HKError.Msg:='SetSComCode Error'; end; finally temp1.Free; temp2.Free; end; end; end; procedure TDevice.DoorBlock; begin // end; procedure TDevice.DoorOpen; begin // end; // Misc function BCDByte2Byte(Value: Byte): Byte; begin Result:=(Value shr 4)*10+(Value and $0F); end; function BCDByte2String(Value: Byte): String; begin Result:=IntToStr(ord(Value shr 4))+IntToStr(ord(Value and $0F));; end; function Str2BCDByte(Value: string; prv, vtor: Integer): Byte; var tmp: string; begin Result:=0; try tmp:=Value[prv]+Value[vtor]; Result:=Byte2BCDByte(StrToInt(tmp)); except HKError.MsgFmt('Str2BCDByte Invalid Value %s Prv %d Vtor $d',[Value,prv,vtor]); end; end; function Byte2BCDByte(Value: Byte): Byte; begin Result:=0; if Value<100 then Result:=((Value div 10) shl 4) or (Value mod 10) else HKError.MsgFmt('Byte2BCDByte Invalid Value %d',[Value]); end; procedure FreeList(Value: TList); var i: Integer; begin if Value<>nil then begin i:=Value.Count; while i>0 do begin TObject(Value.Items[Value.Count-1]).Free; Value.Delete(Value.Count-1); i:=Value.Count; end; Value.Free; end; end; procedure EHKError.SetMsg(const Value: string); begin if FMsg<>Value then begin FMsg:=Copy(Value,1,$FFFF); if FMsg<>'' then if Assigned(OnMsg) then OnMsg(self); end; end; procedure EHKError.MsgFmt(const Fmt: string; const Args: array of const); begin Msg:=Format(Fmt,Args); end; procedure EHKError.LogComm(Lab: String; p_comm: TCommand); var tmp: string; i: Integer; begin tmp:=Lab+' cmd='+IntToStr(p_comm.cmd)+' dev='+IntToStr(p_comm.dev)+' bcc='+IntToStr(p_comm.bcc); for i:=1 to Length(p_comm.body) do tmp:=tmp+Format(' %x',[ord(p_comm.body[i])]); Msg:=tmp; end; end.
Back
|
About - Business - Experience
- Projects Copyright © 2001 Halkyon Development Team Ltd. |