unit Unit1;
//Pause entweder mit SLEEP oder GetTickCount realisieren
{$DEFINE GetTickCount}
//nur zeitlich begrenzte Benutzung erlauben
//{$DEFINE TIMELOCK}
interface
uses
StrUtils,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AfComPort, StdCtrls, AfDataDispatcher, ExtCtrls, Buttons, DateUtils,
ComCtrls;
{$IFDEF TIMELOCK}
const
//Sperr Datum
LockDate: String='03.02.2006';
//maximale Gültigkeit in Monaten gerechnet vom Kompilierungsdatum an
MaxLockMonth: Integer=2;
{$ENDIF}
type
TForm1 = class(TForm)
AfComPort1: TAfComPort;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Button1: TButton;
ProgressBar1: TProgressBar;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
procedure CloseControls;
procedure OpenControls;
procedure Status(Status: String);
procedure Status2(Status: String);
procedure Modus(Modus: String);
procedure About; stdcall;
function Version (): ShortString; stdcall;
function GetVersion(Datei: string): string;
{$IFDEF TIMELOCK}
function CheckTimer(): Boolean;
{$ENDIF}
function Split(const fText: String; const fSep: Char; fTrim: Boolean=false; fQuotes: Boolean=false):TStringList;
function GetPaket(buffer: String): String;
function MakePaket(Paket: String):String;
function CalcPaketChksum(Paket: String): Integer;
function GetSeriesFromReceiver(COM: Integer): Integer; stdcall;
function GetModelFromReceiver(COM: Integer): ShortString; stdcall;
function GetModelFromFile(SettingsFile: ShortString): ShortString; stdcall;
function Upload(SettingsFile: ShortString; COM: Integer; Series: Integer): Boolean; stdcall;
function Download(SettingsFile: ShortString; COM: Integer; Series: Integer): Boolean; stdcall;
function AutoUpload(SettingsFile: ShortString; COM: Integer; IgnoreHardwareCheck: Boolean): Boolean; stdcall;
function AutoDownload(SettingsFile: ShortString; COM: Integer): Boolean; stdcall;
function Convert(Settings: ShortString; Settings_old: ShortString): Boolean; stdcall;
function XML(Settings: ShortString; Settings_xml: ShortString): Boolean; stdcall;
function CSV(Settings: ShortString; Settings_csv: ShortString): Boolean; stdcall;
procedure FlashReset(COM: Integer); stdcall;
function PortExists(COM: Integer): Boolean; stdcall
function GetImageLinkTimeStamp(const FileName: string): DWORD;
var
Form1: TForm1;
GlobalBreak: Boolean;
implementation
{$R *.dfm}
{$IFDEF TIMELOCK}
function CheckTimer(): Boolean;
var
actualDate : TDateTime;
begin
//actualDate := StrToDate('13.12.2005');
actualDate:=Date;
//Aktuelles Datum nach Sperrdatum -> Lock aktiv
//Aktuelles Datum vor Erstellungsdatum -> gefaktes PC Datum
if (StrToDate(DateToStr(actualDate))>StrToDate(LockDate))
or (StrToDate(DateToStr(actualDate))<StrToDate(DateToStr(UnixToDateTime(GetImageLinkTimeStamp('TSAPI.dll')))))
or (StrToDate(LockDate)>IncMonth(StrToDate(DateToStr(UnixToDateTime(GetImageLinkTimeStamp('TSAPI.dll')))),MaxLockMonth))
then
CheckTimer:=true
else
CheckTimer:=false;
end;
{$ENDIF}
procedure Delay(ATime:Integer);
//Pause
{$IFDEF GetTickCount}
var
Start : Integer;
begin
Start:=GetTickCount;
repeat
Application.ProcessMessages;
{$WARNINGS OFF}
until GetTickCount-Start > ATime;
{$WARNINGS ON}
{$ELSE}
begin
sleep(ATime);
{$ENDIF}
end;
function GetImageLinkTimeStamp(const FileName: string): DWORD;
// Get the 'link time stamp' of an portable executable image file (PE32)
const
INVALID_SET_FILE_POINTER = DWORD(-1);
BorlandMagicTimeStamp = $2A425E19; // Delphi 4-6 (and above?)
FileTime1970: TFileTime = (dwLowDateTime:$D53E8000; dwHighDateTime:$019DB1DE);
type
PImageSectionHeaders = ^TImageSectionHeaders;
TImageSectionHeaders = array [Word] of TImageSectionHeader;
type
PImageResourceDirectory = ^TImageResourceDirectory;
TImageResourceDirectory = packed record
Characteristics: DWORD;
TimeDateStamp: DWORD;
MajorVersion: Word;
MinorVersion: Word;
NumberOfNamedEntries: Word;
NumberOfIdEntries: Word;
end;
var
FileHandle: THandle;
BytesRead: DWORD;
ImageDosHeader: TImageDosHeader;
ImageNtHeaders: TImageNtHeaders;
SectionHeaders: PImageSectionHeaders;
Section: Word;
ResDirRVA: DWORD;
ResDirSize: DWORD;
ResDirRaw: DWORD;
ResDirTable: TImageResourceDirectory;
FileTime: TFileTime;
begin
Result := 0;
// Open file for read access
FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, 0, 0);
if (FileHandle <> INVALID_HANDLE_VALUE) then
try
// Read MS-DOS header to get the offset of the PE32 header
// (not required on WinNT based systems - but mostly available)
if not ReadFile(FileHandle, ImageDosHeader, SizeOf(TImageDosHeader),
BytesRead, nil) or (BytesRead <> SizeOf(TImageDosHeader)) or
(ImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE) then
begin
ImageDosHeader._lfanew := 0;
end;
// Read PE32 header (including optional header
if (SetFilePointer(FileHandle, ImageDosHeader._lfanew, nil, FILE_BEGIN) =
INVALID_SET_FILE_POINTER) then
begin
Exit;
end;
if not(ReadFile(FileHandle, ImageNtHeaders, SizeOf(TImageNtHeaders),
BytesRead, nil) and (BytesRead = SizeOf(TImageNtHeaders))) then
begin
Exit;
end;
// Validate PE32 image header
if (ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE) then
begin
Exit;
end;
// Seconds since 1970 (UTC)
Result := ImageNtHeaders.FileHeader.TimeDateStamp;
// Check for Borland's magic value for the link time stamp
// (we take the time stamp from the resource directory table)
if (ImageNtHeaders.FileHeader.TimeDateStamp = BorlandMagicTimeStamp) then
with ImageNtHeaders, FileHeader, OptionalHeader do
begin
// Validate Optional header
if (SizeOfOptionalHeader < IMAGE_SIZEOF_NT_OPTIONAL_HEADER) or
(Magic <> IMAGE_NT_OPTIONAL_HDR_MAGIC) then
begin
Exit;
end;
// Read section headers
SectionHeaders :=
GetMemory(NumberOfSections * SizeOf(TImageSectionHeader));
if Assigned(SectionHeaders) then
try
if (SetFilePointer(FileHandle,
SizeOfOptionalHeader - IMAGE_SIZEOF_NT_OPTIONAL_HEADER, nil,
FILE_CURRENT) = INVALID_SET_FILE_POINTER) then
begin
Exit;
end;
if not(ReadFile(FileHandle, SectionHeaders^, NumberOfSections *
SizeOf(TImageSectionHeader), BytesRead, nil) and (BytesRead =
NumberOfSections * SizeOf(TImageSectionHeader))) then
begin
Exit;
end;
// Get RVA and size of the resource directory
with DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] do
begin
ResDirRVA := VirtualAddress;
ResDirSize := Size;
end;
// Search for section which contains the resource directory
ResDirRaw := 0;
for Section := 0 to NumberOfSections - 1 do
with SectionHeaders[Section] do
if (VirtualAddress <= ResDirRVA) and
(VirtualAddress + SizeOfRawData >= ResDirRVA + ResDirSize) then
begin
ResDirRaw := PointerToRawData - (VirtualAddress - ResDirRVA);
Break;
end;
// Resource directory table found?
if (ResDirRaw = 0) then
begin
Exit;
end;
// Read resource directory table
if (SetFilePointer(FileHandle, ResDirRaw, nil, FILE_BEGIN) =
INVALID_SET_FILE_POINTER) then
begin
Exit;
end;
if not(ReadFile(FileHandle, ResDirTable,
SizeOf(TImageResourceDirectory), BytesRead, nil) and
(BytesRead = SizeOf(TImageResourceDirectory))) then
begin
Exit;
end;
// Convert from DosDateTime to SecondsSince1970
if DosDateTimeToFileTime(HiWord(ResDirTable.TimeDateStamp),
LoWord(ResDirTable.TimeDateStamp), FileTime) then
begin
// FIXME: Borland's linker uses the local system time
// of the user who linked the executable image file.
// (is that information anywhere?)
Result := (ULARGE_INTEGER(FileTime).QuadPart -
ULARGE_INTEGER(FileTime1970).QuadPart) div 10000000;
end;
finally
FreeMemory(SectionHeaders);
end;
end;
finally
CloseHandle(FileHandle);
end;
end;
function PortExists(COM: Integer): Boolean; stdcall
//COM Port Existenz überprüfen
var
DeviceHandle: THandle;
begin
DeviceHandle:=0;
try
DeviceHandle := CreateFile(PChar('COM'+IntToStr(COM)), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);
if DeviceHandle = INVALID_HANDLE_VALUE then
PortExists:=false
else
PortExists:=true;
finally
CloseHandle(DeviceHandle);
end;
end;
procedure About; stdcall;
var
Backup: String;
begin
CloseControls;
//Status
Modus('TS API Info');
Status('© 2004-2006 by Lostech');
//Status2('www.lostech.de.vu');
{$IFDEF TIMELOCK}
Status2('Version : '+Version+' Datum: '+DateTimeToStr(UnixToDateTime(GetImageLinkTimeStamp('TSAPI.dll'))));
{$ELSE}
Status2('Version: '+Version+' Datum: '+DateTimeToStr(UnixToDateTime(GetImageLinkTimeStamp('TSAPI.dll'))));
{$ENDIF}
Backup:=Form1.Button1.Caption;
Form1.Button1.Caption:='OK';
Form1.Label1.Alignment:=taCenter;
Form1.Label2.Alignment:=taCenter;
while GlobalBreak=false do
Application.ProcessMessages;
Form1.Button1.Caption:=Backup;
Form1.Label1.Alignment:=taLeftJustify;
Form1.Label2.Alignment:=taLeftJustify;
GlobalBreak:=false;
OpenControls;
end;
procedure Modus(Modus: String);
//Statusanzeige Modus
begin
Form1.Label3.Caption:=Modus;
Form1.Label3.Refresh;
end;
procedure Status(Status: String);
//Statusanzeige
begin
Form1.Label1.Caption:=Status;
Form1.Label1.Refresh;
end;
procedure Status2(Status: String);
//Statusanzeige 2
begin
Status:=StringReplace(Status,#10,'',[rfReplaceAll, rfIgnoreCase]);
Status:=StringReplace(Status,#13,'',[rfReplaceAll, rfIgnoreCase]);
//Form1.BringToFront;
Form1.Label2.Caption:=Status;
Form1.Label2.Refresh;
end;
function GetVersion(Datei: string): string;
//Dateiversion aus EXE auslesen
var aFileName: array [0..MAX_PATH] of Char;
pdwHandle: DWORD;
nInfoSize: DWORD;
pFileInfo: Pointer;
pFixFInfo: PVSFixedFileInfo;
nFixFInfo: DWORD;
begin
//Gibt Versionsnummer zurück
StrPCopy(aFileName,Datei);
pdwHandle := 0;
nInfoSize := GetFileVersionInfoSize(aFileName, pdwHandle);
result:='0';
if nInfoSize <> 0 then
pFileInfo := GetMemory(nInfoSize)
else
pFileInfo := nil;
if Assigned(pFileInfo) then
begin
try
if GetFileVersionInfo(aFileName, pdwHandle, nInfoSize, pFileInfo) then
begin
pFixFInfo := nil;
nFixFInfo := 0;
if VerQueryValue(pFileInfo, '\', Pointer(pFixFInfo), nFixFInfo) then
begin
{
result := Format('%d.%d.%d.%d',[HiWord(pFixFInfo^.dwFileVersionMS),
LoWord(pFixFInfo^.dwFileVersionMS),HiWord(pFixFInfo^.dwFileVersionLS),
LoWord(pFixFInfo^.dwFileVersionLS)]);
}
result := Format('%d.%d',[HiWord(pFixFInfo^.dwFileVersionMS),LoWord(pFixFInfo^.dwFileVersionLS)]);
end;
end;
finally
FreeMemory(pFileInfo);
end;
end;
end;
procedure FlashReset(COM: Integer); stdcall;
//Reset
begin
//Bedienung sperren
CloseControls;
//Modus Status
Modus('FlashReset COM'+IntToStr(COM));
//Status
Status('Bitte warten...');
//COM Port setzen
Form1.AfComPort1.ComNumber:=COM;
Form1.Button1.Visible:=false;
//Reset ohne Parität senden
Form1.AfComPort1.Parity:=paNone;
Application.ProcessMessages;
Form1.AfComPort1.Open;
Form1.AfComPort1.WriteString('dbinvlimg');
Form1.AfComPort1.Close;
delay(1000);
//Reset mit Parität senden
Form1.AfComPort1.Parity:=paEven;
Application.ProcessMessages;
Form1.AfComPort1.Open;
Form1.AfComPort1.WriteString('dbinvlimg');
Form1.AfComPort1.Close;
delay(1000);
//Bedienung freigeben
Form1.Button1.Visible:=true;
OpenControls;
end;
function GetModelFromReceiver(COM: Integer): ShortString; stdcall;
//Receivermodell aus Gerät auslesen
var
Paket: AnsiString;
Receiver: String;
buffer: String;
Counter: Integer;
InBufferUsed: Integer;
CheckSum1: String;
CheckSum2: String;
BasicSettings: Boolean;
begin
//Bedienung sperren
CloseControls;
//Modus Status
Modus('Suche Receivertyp an COM'+IntToStr(COM));
//Grundeinstellungen setzen
Counter:=0;
GlobalBreak:=false;
//Receiver Serie ermitteln für COM Port Einstellung
if GetSeriesFromReceiver(COM)=1 then
Form1.AfComPort1.Parity:=paEven
else
Form1.AfComPort1.Parity:=paNone;
//COM Port setzen
Form1.AfComPort1.ComNumber:=COM;
//COM Port definiert öffnen
Form1.AfComPort1.Close;
Form1.AfComPort1.Open;
//COM Port Puffer leeren
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
//Datenbank auslesen
Form1.AfComPort1.WriteString('dbdump');
//[database] Abschnitt finden
while (Counter<100) and (GlobalBreak=false) do
begin
delay(5);
Application.ProcessMessages;
buffer:=Form1.AfComPort1.ReadString;
Paket:=Paket+buffer;
if AnsiPos('[database]',GetPaket(Paket))>0 then
break
else
Counter:=Counter+1;
end;
//bei Fehler oder Abbruch Funktion verlassen
if (Counter>99) or (GlobalBreak=true) then
begin
Form1.AfComPort1.Close;
GetModelFromReceiver:='';
OpenControls;
exit;
end;
//COM Port Puffer leeren
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
//nächstes Paket anfordern
BasicSettings:=false;
Counter:=0;
Receiver:='';
Form1.AfComPort1.WriteString(#1);
while (Counter<100) and (GlobalBreak=false) do
begin
delay(1);
InBufferUsed:=0;
buffer:='';
//warten bis Empfangspuffer sich nicht mehr füllt
while Form1.AfComPort1.InBufUsed<>InBufferUsed do
begin
InBufferUsed:=Form1.AfComPort1.InBufUsed;
delay(1)
end;
Application.ProcessMessages;
buffer:=Form1.AfComPort1.ReadString;
//wenn Receiver die Übertragung beendet Schleife verlassen
if buffer=#85+#85+#0+#0 then break;
//Puffer Checksummen festlegen
//Checksumme 1 -> IST Checksumme des Paketes
//Checksumme 2 -> SOLL Checksumme des Paketes
if Length(buffer)>0 then
begin
//Sonderfall wenn 2 x 0A Bytes gesendet werden -> Checksumme SOLL = 10
if AnsiPos(#10+#10,buffer)>0 then
begin
{
if AnsiPos('UU',buffer)>0 then
begin
CheckSum1:=MidStr(buffer,AnsiPos('UU',buffer)+3,length(buffer)-AnsiPos('UU',buffer)-4);
end
else
CheckSum1:=MidStr(buffer,4,length(buffer)-3);
CheckSum1:=LeftStr(CheckSum1,AnsiPos(#10,CheckSum1));
CheckSum1:=IntToHex(CalcPaketChkSum(CheckSum1)+10,1);
CheckSum2:='0A';
}
CheckSum1:='0A';
CheckSum2:='0A';
end
//Normalfall
else
begin
CheckSum1:=IntToHex(CalcPaketChkSum(AnsiMidStr(buffer,AnsiPos('UU',buffer)+3,LastDelimiter(Chr(10),buffer)-(AnsiPos('UU',buffer)+3)))+10,1);
CheckSum2:=IntToHex(Ord(AnsiMidStr(buffer,LastDelimiter(Chr(10),buffer)+1,1)[1]),1);
end;
end
else //Fehler bei der Checksummenberechnung mit 2 unterschiedlichen Checksummen quittieren
begin
CheckSum1:='01';
CheckSum2:='02';
end;
//Checksummen formatieren
CheckSum1:=RightStr(CheckSum1,2);
CheckSum2:=RightStr(CheckSum2,2);
CheckSum1:=StringOfChar('0',2-Length(CheckSum1))+CheckSum1;
CheckSum2:=StringOfChar('0',2-Length(CheckSum2))+CheckSum2;
//COM Port Puffer leeren
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
//Checksumme des Pakets überprüfen
if CheckSum1=CheckSum2 then //korrektes Paket
begin
//innerhalb [0x6 basicSettings] das Receiver Modell raussuchen
if AnsiPos('[0x6',buffer)>0 then BasicSettings:=true;
if BasicSettings=true then
begin
if LeftStr(GetPaket(buffer),3)='R0=' then
begin
Receiver:=Split(buffer,#9)[4];
Receiver:=StringReplace(Receiver,'"','',[rfReplaceAll, rfIgnoreCase]);
break;
end;
end;
Form1.AfComPort1.WriteString(#1);
Counter:=0;
end
else //fehlerhaftes Paket
begin
Form1.AfComPort1.WriteString(#0);
Counter:=Counter+1;
end;
end;
//Status
Status('Receivertyp: '+Receiver);
//Receiver Modell melden
GetModelFromReceiver:=Receiver;
//COM Port schließen
Form1.AfComPort1.Close;
//Bedienung entsperren
OpenControls;
end;
function GetSeriesFromReceiver(COM: Integer): Integer; stdcall;
//Receiverserie aus Gerät auslesen
var
buffer: String;
Counter: Integer;
ReceiverSeries: Integer;
label
Series;
begin
//Bedienung sperren
CloseControls;
//Modus Status
Modus('Receiver Serie an COM'+IntToStr(COM));
//Grundeinstellungen setzen
GlobalBreak:=false;
ReceiverSeries:=0;
//COM Einstellungen setzen
Form1.AfComPort1.ComNumber:=COM;
//mit verschiedenen COM Port Einstellungen versuchen
//den [database] Abschnitt zu lesen und somit
//die Receiverserie ermitteln
//
//Mögliche Receiverserien:
//0 = DigiBox / DIGIT / Digital / DigiCorder / DigiPal Serie
//1 = Digity Serie
Series: //Sprungpunkt um die Schleife ein noch einmal für die nächste Receiverserie ablaufen zu lassen
Counter:=0;
if (ReceiverSeries=0) then
Form1.AfComPort1.Parity:=paNone;
if (ReceiverSeries=1) then
Form1.AfComPort1.Parity:=paEven;
while (Counter<75) and (GlobalBreak=false) do
begin
Application.ProcessMessages;
delay(5);
//Port öffnen und Receiver auslesen
Form1.AfComPort1.Close;
Form1.AfComPort1.Open;
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
Form1.AfComPort1.WriteString('dbdump');
Application.ProcessMessages;
delay(100);
buffer:='';
buffer:=Form1.AfComPort1.ReadString;
//Form1.AfComPort1.WriteString('dbdump');
//Stop-Signal schicken
Form1.AfComPort1.WriteString(#85+#85+#0+#0);
Form1.AfComPort1.WriteString(#85+#85+#0+#0);
Form1.AfComPort1.WriteString(#85+#85+#0+#0);
Form1.AfComPort1.WriteString(#85+#85+#0+#0);
Form1.AfComPort1.WriteString(#85+#85+#0+#0);
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
Form1.AfComPort1.Close;
//empfangenes Paket auf verwertbaren [database] Text auswerten
if (AnsiContainsStr(buffer, '[database]')=true) then
break
else
inc(Counter);
end;
//Ermittelte Receiverserie festlegen
{
if (AnsiContainsStr(buffer, '[database]')=true) then
GetSeriesFromReceiver:=ReceiverSeries
else
begin
inc(ReceiverSeries);
if (ReceiverSeries=1) then goto Series;
GetSeriesFromReceiver:=-1;
end;
}
if (AnsiContainsStr(buffer, '[database]')=false) then
begin
inc(ReceiverSeries);
if (ReceiverSeries=1) then goto Series;
ReceiverSeries:=-1;
end;
//Fehler abfangen
if (ReceiverSeries>1) then ReceiverSeries:=0;
//Status
if ReceiverSeries=0 then
begin
Status('DigiBox/Digit/DigiCorder/DigiPal + kompatible STB');
Status2('COM'+IntToStr(COM)+' -> 115200/8/N/1 Bitte warten...');
end;
if ReceiverSeries=1 then
begin
Status('DigiBox/Digity + kompatible STB');
Status2('COM'+IntToStr(COM)+' -> 115200/8/E/1 Bitte warten...');
end;
{*
Status('Receiver Serie '+IntToStr(ReceiverSeries));
if ReceiverSeries=0 then
Status2('DigiBox/Digit/DigiCorder/DigiPal + kompatible STB');
if ReceiverSeries=1 then
Status2('DigiBox/Digity + kompatible STB');
*}
//Sicherheitspause
if ((GlobalBreak=false) and (ReceiverSeries >-1)) then
begin
counter:=0;
while (Counter<70) do
begin
Application.ProcessMessages;
delay(300);
if GlobalBreak=true then break;
inc(Counter);
end;
end;
//GlobalBreak abfangen
if (GlobalBreak=true) then
ReceiverSeries:=-1;
GetSeriesFromReceiver:=ReceiverSeries;
//Bedienung wieder freigeben
OpenControls;
end;
procedure OpenControls;
begin
Form1.ProgressBar1.Visible:=false;
Form1.Hide;
Application.ProcessMessages;
end;
procedure CloseControls;
begin
if Form1=nil then
begin
Form1:=TForm1.Create(nil);
Form1.Caption:=Form1.Caption+' Version '+Version;
end;
Form1.Label1.Caption:='';
Form1.Label2.Caption:='';
Form1.Show;
Application.ProcessMessages;
end;
function GetPaket(buffer: String): String;
//Paket aus Lesepuffer ausschneiden
var
Paket: String;
Paketstart: Integer;
begin
Paket:='';
//Paketanfang ermitteln
Paketstart:=AnsiPos('UU',buffer);
if Paketstart=0 then
begin
GetPaket:='';
exit;
end;
Paket:=RightStr(buffer,length(buffer)-Paketstart-2);
if (AnsiContainsStr(Paket, #10)=true) then
begin
Paket:=AnsiMidStr(Paket,1,LastDelimiter(Chr(10),Paket));
Paket:=StringReplace(Paket,#10#10,#10,[rfReplaceAll, rfIgnoreCase]);
Paket:=StringReplace(Paket,#10,#13#10,[rfReplaceAll, rfIgnoreCase]);
//Sonderzeichen rausfiltern
Paket:=StringReplace(Paket,#5,'',[rfReplaceAll, rfIgnoreCase]);
if (AnsiContainsStr(Paket, '=')=true) and (AnsiContainsStr(Paket, 'Version')=false) then
begin
if (AnsiContainsStr(Paket, '[')=false) and (AnsiContainsStr(Paket, ']')=false) then
if (LeftStr(Paket,1)<>'R') and (LeftStr(Paket,1)<>'I') then Paket:='R'+Paket;
end;
GetPaket:=Paket;
end
else
GetPaket:='';
end;
function CalcPaketChksum(Paket: String): Integer;
//Checksumme eines empfangenen Pakets berechnen
var
Pos: Integer;
CheckSum: Integer;
HexCheckSum: String;
begin
//Summen-Checksumme berechnen
Checksum:=0;
for Pos:=1 to Length(Paket) do
begin
CheckSum:=CheckSum+Ord(MidStr(Paket,Pos,1)[1]);
end;
//Checksumme nur für 8Bit/1Byte berechnen berechnen
HexCheckSum:=RightStr(IntToHex(CheckSum,2),2);
//Ergebnis
CalcPaketChksum:=StrToInt('$'+HexChecksum);
end;
function MakePaket(Paket: String):String;
//Sendepaket erstellen
var
buffer: String;
ZeichenBuffer: Char;
Checksumme: Integer;
Pos: Integer;
begin
if (Length(Paket)=0) then exit;
Checksumme:=0;
buffer:='UU'+Chr(Length(Paket)+1)+Paket+#10;
for Pos:=4 to Length(buffer) do
begin
//Zeichen:=AnsiMidStr(buffer,Pos,1);
ZeichenBuffer:=AnsiMidStr(buffer,Pos,1)[1];//Zeichen[1];
Checksumme:=Checksumme+Ord(ZeichenBuffer);
//ZeichenBuffer:=#0;
end;
Checksumme:=StrToInt('$'+RightStr(IntToHex(Checksumme,4),2));
buffer:=buffer+Chr(StrToInt('$'+RightStr(IntToHex(Checksumme,4),2))); //Checksumme);
MakePaket:=buffer;
end;
function Split(const fText: String; const fSep: Char; fTrim: Boolean=false; fQuotes: Boolean=false):TStringList;
//String Split Funktion
var vI: Integer;
vBuffer: String;
vOn: Boolean;
begin
Result:=TStringList.Create;
vBuffer:='';
vOn:=true;
for vI:=1 to Length(fText) do
begin
if (fQuotes and(fText[vI]=fSep)and vOn)or(Not(fQuotes) and (fText[vI]=fSep)) then
begin
if fTrim then vBuffer:=Trim(vBuffer);
if vBuffer[1]=fSep then
vBuffer:=Copy(vBuffer,2,Length(vBuffer));
Result.Add(vBuffer);
vBuffer:='';
end;
if fQuotes then
begin
if fText[vI]='"' then
begin
vOn:=Not(vOn);
Continue;
end;
if (fText[vI]<>fSep)or((fText[vI]=fSep)and(vOn=false)) then
vBuffer:=vBuffer+fText[vI];
end else
if fText[vI]<>fSep then
vBuffer:=vBuffer+fText[vI];
end;
if vBuffer<>'' then
begin
if fTrim then vBuffer:=Trim(vBuffer);
Result.Add(vBuffer);
end;
end;
function CSV(Settings: ShortString; Settings_csv: ShortString): Boolean; stdcall;
//Settings (SET/Dump) in CSV Datei konvertieren
var
SettingsIn: Text;
SettingsOut: Text;
BufferIn: String;
begin
//Pfadangaben überprüfen
if (Settings='') or (Settings_csv='') or (Settings=Settings_csv) or (FileExists(Settings)=false) then
begin
CSV:=false;
exit;
end;
//Bedienung sperren
CloseControls;
Form1.Button1.Visible:=false;
//Modus Status
Modus('CSV Settings Konverter');
//Status
Status('Konvertiere "'+ExtractFileName(Settings)+'" in CSV Datei');
Status2('Bitte warten...');
//Settings einlesen
assign(SettingsIn,Settings);
reset(SettingsIn);
//CSV Datei erzeugen
assign(SettingsOut,Settings_csv);
rewrite(SettingsOut);
//Settings einlesen und als CSV formatiert wieder ausgeben
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
BufferIn:=StringReplace(BufferIn,#9,';',[rfReplaceAll, rfIgnoreCase]);
writeln(SettingsOut,BufferIn);
end;
//CSV Dokument abschliessen
close(SettingsIn);
close(SettingsOut);
//Rückgabewert der Funktion
if FileExists(Settings_csv) then
CSV:=true
else
CSV:=false;
//Bedienung freigeben
Form1.Button1.Visible:=true;
OpenControls;
end;
function XML(Settings: ShortString; Settings_xml: ShortString): Boolean; stdcall;
//Settings (SET/Dump) in XML Datei konvertieren
var
SettingsIn: Text;
SettingsOut: Text;
BufferIn: String;
Section: String;
Item: String;
begin
//Pfadangaben überprüfen
if (Settings='') or (Settings_xml='') or (Settings=Settings_xml) or (FileExists(Settings)=false) then
begin
XML:=false;
exit;
end;
//Bedienung sperren
CloseControls;
Form1.Button1.Visible:=false;
//Modus Status
Modus('XML Settings Konverter');
//Status
Status('Konvertiere "'+ExtractFileName(Settings)+'" in XML Datei');
Status2('Bitte warten...');
//Settings einlesen
assign(SettingsIn,Settings);
reset(SettingsIn);
//XML Datei erzeugen
assign(SettingsOut,Settings_xml);
rewrite(SettingsOut);
//XML Header schreiben
writeln(SettingsOut,'<?xml version="1.0" encoding="ISO-8859-1"?>');
writeln(SettingsOut,'<settings>');
//Settings einlesen und als XML formatiert weider ausgeben
Section:='';
Item:='';
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
//Sektionen schreiben
if (LeftStr(BufferIn,1)='[') then
begin
if Section<>BufferIn then
begin
if (Section<>'') then
writeln(SettingsOut,'</section>');
writeln(SettingsOut,'<section>');
//Daten maskieren
Section:='<![CDATA['+BufferIn+']]>';
writeln(SettingsOut,'<name>'+Section+'</name>');
end;
end
//Items schreiben
else
begin
Item:='<![CDATA['+BufferIn+']]>';
writeln(SettingsOut,'<item>'+Item+'</item>');
end;
end;
//XML Dokument abschliessen
writeln(SettingsOut,'</section>');
writeln(SettingsOut,'</settings>');
close(SettingsIn);
close(SettingsOut);
//Rückgabewert der Funktion
if FileExists(Settings_xml) then
XML:=true
else
XML:=false;
//Bedienung freigeben
Form1.Button1.Visible:=true;
OpenControls;
end;
function Convert(Settings: ShortString; Settings_old: ShortString): Boolean; stdcall;
//Settings (SET/Dump) in das alte Technisat Programmlistenformat (DAT/TXT) konvertieren
var
SettingsIn: Text;
SettingsOut: Text;
SettingsTemp: Text;
SettingsTemp2: Text;
SettingsTemp3: Text;
BufferIn: String;
BufferOut: String;
Buffer: String;
Satellit: String;
Programmname: String;
Frequenz: String;
Symbolrate: String;
FEC: String;
Polaritaet: String;
ServiceID: String;
PCRPID: String;
AudioPID: String;
VideoPID: String;
SFI: String;
ProvID: String;
Prov: String;
Service: TStringList;
Transponder: TStringList;
Sat: TStringList;
Schleife: Integer;
FTA: Boolean;
SFI_Marker: Boolean;
Antwort: Integer;
begin
//Pfadangaben überprüfen
if (Settings='') or (Settings_old='') or (Settings=Settings_old) or (FileExists(Settings)=false) then
begin
convert:=false;
exit;
end;
//Bedienung sperren
CloseControls;
Form1.Button1.Visible:=false;
//Modus Status
Modus('Settings Konverter');
//Status
Status('Konvertiere "'+ExtractFileName(Settings)+'"');
Status2('Bitte warten...');
//MessageBox in den Vordergrund bringen
Application.NormalizeTopMosts;
//FTA Filter
Antwort:=Application.MessageBox(PChar('Filter für Programme verwenden, die als verschlüsselt markiert sind?'+#13+#10+#13+#10+'(Wählen Sie "ja" damit die API versucht nur freie FTA Programme zu konvertieren - wählen Sie "nein" um alle Programme zu konvertieren)'),PChar('Info'),4);
if (Antwort=7) then
FTA:=false
else
FTA:=true;
//SFI Marker Filter
Antwort:=Application.MessageBox(PChar('Sollen vorhandene EPG/SFI Marker konvertiert werden?'+#13+#10+#13+#10+'(Wählen Sie "ja" damit alle EPG/SFI Marker übernommen werden - wählen Sie "nein" wenn keines der konvertierten Programme einen EPG/SFI Marker erhalten soll)'),PChar('Info'),4);
if (Antwort=7) then
SFI_Marker:=false
else
SFI_Marker:=true;
//Formulare wieder in den Vordergrund bringen
Application.RestoreTopMosts;
Application.ProcessMessages;
try
//[0x1 SATELLITE] Satellitenliste in temporäre Datei auslagern
assign(SettingsIn,Settings);
reset(SettingsIn);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (BufferIn='[0x1 SATELLITE]') then
begin
assign(SettingsTemp,ExtractFilePath(Application.ExeName)+'/sat.tmp');
rewrite(SettingsTemp);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (LeftStr(BufferIn,1)='R') then
begin
writeln(SettingsTemp,BufferIn);
end;
if (LeftStr(BufferIn,1)='[') then
begin
BufferIn:='';
break;
end;
end;
close(SettingsTemp);
end;
if (BufferIn='') then break;
end;
close(SettingsIn);
//[0x2 transportStream] Transponderliste in temporäre Datei auslagern
assign(SettingsIn,Settings);
reset(SettingsIn);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (BufferIn='[0x2 transportStream]') then
begin
assign(SettingsTemp,ExtractFilePath(Application.ExeName)+'/tp.tmp');
rewrite(SettingsTemp);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (LeftStr(BufferIn,1)='R') then
begin
writeln(SettingsTemp,BufferIn);
end;
if (LeftStr(BufferIn,1)='[') then
begin
BufferIn:='';
break;
end;
end;
close(SettingsTemp);
end;
if (BufferIn='') then break;
end;
close(SettingsIn);
//[0x3 serviceList] Serviceliste in temporäre Datei auslagern
assign(SettingsIn,Settings);
reset(SettingsIn);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (BufferIn='[0x3 serviceList]') then
begin
assign(SettingsTemp,ExtractFilePath(Application.ExeName)+'/srv.tmp');
rewrite(SettingsTemp);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (LeftStr(BufferIn,1)='R') then
begin
writeln(SettingsTemp,BufferIn);
end;
if (LeftStr(BufferIn,1)='[') then
begin
BufferIn:='';
break;
end;
end;
close(SettingsTemp);
end;
if (BufferIn='') then break;
end;
close(SettingsIn);
//[0x10005 <!1>] TV Favoriten in temporäre Datei auslagern
assign(SettingsIn,Settings);
reset(SettingsIn);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (BufferIn='[0x10005 <!1>]') then
begin
assign(SettingsTemp,ExtractFilePath(Application.ExeName)+'/tv.tmp');
rewrite(SettingsTemp);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (LeftStr(BufferIn,1)='R') then
begin
writeln(SettingsTemp,BufferIn);
end;
if (LeftStr(BufferIn,1)='[') then
begin
BufferIn:='';
break;
end;
end;
close(SettingsTemp);
end;
if (BufferIn='') then break;
end;
close(SettingsIn);
//[0x5 <!0>] Radio Favoriten in temporäre Datei auslagern
assign(SettingsIn,Settings);
reset(SettingsIn);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (BufferIn='[0x5 <!0>]') then
begin
assign(SettingsTemp,ExtractFilePath(Application.ExeName)+'/rad.tmp');
rewrite(SettingsTemp);
while not EOF(SettingsIn) do
begin
readln(SettingsIn,BufferIn);
if (LeftStr(BufferIn,1)='R') then
begin
writeln(SettingsTemp,BufferIn);
end;
if (LeftStr(BufferIn,1)='[') then
begin
BufferIn:='';
break;
end;
end;
close(SettingsTemp);
end;
if (BufferIn='') then break;
end;
close(SettingsIn);
//Ausgabe Datei anlegen
assign(SettingsOut,Settings_old);
rewrite(SettingsOut);
//Favoritenlisten öffnen und TV Favoriten zuerst auslesen
for Schleife:=0 to 1 do
begin
If (Schleife=0) then
begin
assign(SettingsTemp,ExtractFilePath(Application.ExeName)+'/tv.tmp');
reset(SettingsTemp);
end
else
begin
assign(SettingsTemp,ExtractFilePath(Application.ExeName)+'/rad.tmp');
reset(SettingsTemp);
end;
while not EOF(SettingsTemp) do
begin
//Favoriten der Reihe nach auslesen
readln(SettingsTemp,BufferIn);
Buffer:=RightStr(BufferIn,Length(BufferIn)-AnsiPos('=',BufferIn));
//Programmdaten eines Programmes auslesen
assign(SettingsTemp2,ExtractFilePath(Application.ExeName)+'/srv.tmp');
reset(SettingsTemp2);
while not EOF(SettingsTemp2) do
begin
readln(SettingsTemp2,BufferIn);
if (AnsiContainsStr(BufferIn,'='+Buffer)=true) then
begin
Service:=Split(BufferIn,#9);
//Programmname
Programmname:=Service[1];
//Ungewollte Steuerzeichen aus Programmnamen ausfiltern
Programmname:=StringReplace(Programmname,#5,'',[rfReplaceAll, rfIgnoreCase]);
Programmname:=StringReplace(Programmname,'"','',[rfReplaceAll, rfIgnoreCase]);
//Shareware Hinweis
//if (Registration=false) then Programmname:='"GammaLoader unregistered"';
//Anführungszeichen gezielt nur am Anfang und Ende des Namens setzen
Programmname:='"'+Programmname+'"';
//wenn nur FTA verschlüsselte Services löschen
if (Service[10]='1') and (FTA=true) then
Programmname:='';
//Service ID
ServiceID:=IntToStr(StrToInt('$'+StringReplace(Service[4],'0x','',[rfReplaceAll, rfIgnoreCase])));
//PCR PID
PCRPID:=IntToStr(StrToInt('$'+StringReplace(Service[5],'0x','',[rfReplaceAll, rfIgnoreCase])));;
//Audio PId
AudioPID:=IntToStr(StrToInt('$'+StringReplace(Service[6],'0x','',[rfReplaceAll, rfIgnoreCase])));;
//Video PID
VideoPID:=IntToStr(StrToInt('$'+StringReplace(Service[7],'0x','',[rfReplaceAll, rfIgnoreCase])));;
//SFI Marker
SFI:=Service[8];
if(SFI_Marker=false) then
SFI:='0';
//Transponderdaten auslesen
assign(SettingsTemp3,ExtractFilePath(Application.ExeName)+'/tp.tmp');
reset(SettingsTemp3);
while not EOF(SettingsTemp3) do
begin
readln(SettingsTemp3,BufferIn);
if (AnsiContainsStr(BufferIn,'='+Service[2])=true) then
begin
Transponder:=Split(BufferIn,#9);
//Frequenz
Frequenz:=Transponder[5];
//Symbolrate
Symbolrate:=Transponder[6];
//Polarität
if (Transponder[7]='0') then
Polaritaet:='v'
else
Polaritaet:='h';
//FEC
FEC:=Transponder[8];
//Satellit Eintrag zwischenspeichern
buffer:=Transponder[10];
break;
end;
end;
Close(SettingsTemp3);
//Satellitendaten auslesen
assign(SettingsTemp3,ExtractFilePath(Application.ExeName)+'/sat.tmp');
reset(SettingsTemp3);
while not EOF(SettingsTemp3) do
begin
readln(SettingsTemp3,BufferIn);
if (AnsiContainsStr(BufferIn,'='+buffer)=true) then
begin
Sat:=Split(BufferIn,#9);
Satellit:='';
//42,0° Ost
if (Sat[2]='0x8420') then
Satellit:='Türksat 8420';
//36,0° Ost
if (Sat[2]='0x8360') then
Satellit:='EutelSat 8360';
//31,3° Ost
if (Sat[2]='0x8313') then
Satellit:='Türksat 8313';
//28,2° Ost
if (Sat[2]='0x8282') then
Satellit:='ASTRA/Eubird 8282';
//23,5° Ost
if (Sat[2]='0x8235') then
Satellit:='Kopernikus 8235';
//19,2° Ost
if (Sat[2]='0x8192') then
Satellit:='ASTRA 8192';
//16,0°Ost
if (Sat[2]='0x8160') then
Satellit:='EutelSat 8160';
//13,0° Ost
if (Sat[2]='0x8130') then
Satellit:='EutelSat 8130';
//10,0° Ost
if (Sat[2]='0x8100') then
Satellit:='EutelSat 8100';
//5,0° Ost
if (Sat[2]='0x8050') then
Satellit:='Sirius 8050';
//1,0° West
if (Sat[2]='0x10') then
Satellit:='Thor/Intelsat 10';
//4,0° West
if (Sat[2]='0x40') then
Satellit:='Amos 40';
//5,0° West
if (Sat[2]='0x50') then
Satellit:='Telecom 50';
//7,0° West
if (Sat[2]='0x70') then
Satellit:='Nilesat 70';
//30,0° West
if (Sat[2]='0x300') then
Satellit:='Hispasat 300';
//37,5° West
if (Sat[2]='0x375') then
Satellit:='Orion 375';
//43,0° West
if (Sat[2]='0x430') then
Satellit:='PanamSat 430';
//User1
if (Sat[2]='"User 1"') then
Satellit:='User-1 ffffffff';
//User2
if (Sat[2]='"User 2"') then
Satellit:='User-2 ffffffff';
//User3
if (Sat[2]='"User 3"') then
Satellit:='User-3 ffffffff';
//User4
if (Sat[2]='"User 4"') then
Satellit:='User-4 ffffffff';
//User5
if (Sat[2]='"User 5"') then
Satellit:='User-5 ffffffff';
//User6
if (Sat[2]='"User 6"') then
Satellit:='User-6 ffffffff';
//User7
if (Sat[2]='"User 7"') then
Satellit:='User-7 ffffffff';
//User8
if (Sat[2]='"User 8"') then
Satellit:='User-8 ffffffff';
//User9
if (Sat[2]='"User 9"') then
Satellit:='User-9 ffffffff';
//User10
if (Sat[2]='"User10"') then
Satellit:='User10 ffffffff';
//User11
if (Sat[2]='"User11"') then
Satellit:='User11 ffffffff';
//User12
if (Sat[2]='"User12"') then
Satellit:='User12 ffffffff';
//User13
if (Sat[2]='"User13"') then
Satellit:='User13 ffffffff';
//User14
if (Sat[2]='"User14"') then
Satellit:='User14 ffffffff';
//User15
if (Sat[2]='"User15"') then
Satellit:='User15 ffffffff';
//User1 falls keine Sat Position zugeordnet werden konnte
if (Satellit='') then
Satellit:='User-1 ffffffff';
break;
end;
end;
Close(SettingsTemp3);
//Shareware Hinweis
{
if (Registration=false) then
begin
ProvID:='1';
Prov:='"Unregistered"';
end
else
begin
ProvID:='0';
Prov:='""';
end;
}
ProvID:='0';
Prov:='""';
//Neue Programmdatenzeile zusammensetzen und in Datei schreiben
if (Programmname<>'') then
begin
BufferOut:=Satellit+' '+Frequenz+'000 '+Polaritaet;
BufferOut:=BufferOut+StringOfChar(' ',6-Length(Symbolrate))+Symbolrate+' '+FEC;
BufferOut:=BufferOut+StringOfChar(' ',6-Length(ServiceID))+ServiceID;
BufferOut:=BufferOut+StringOfChar(' ',6-Length(PCRPID))+PCRPID;
BufferOut:=BufferOut+StringOfChar(' ',6-Length(AudioPID))+AudioPID;
BufferOut:=BufferOut+StringOfChar(' ',6-Length(VideoPID))+VideoPID;
BufferOut:=BufferOut+' 1 '+SFI+' '+Programmname+' '+ProvID+' '+Prov;
writeln(SettingsOut,BufferOut);
if (Satellit='ASTRA/Eubird 8282') then
begin
BufferOut:=StringReplace(BufferOut,Satellit,'ASTRA 8282',[rfReplaceAll, rfIgnoreCase]);
writeln(SettingsOut,BufferOut);
end;
end;
Application.ProcessMessages;
break;
end;
end;
close(SettingsTemp2);
end;
close(SettingsTemp);
end;
//Ausgabedatei schließen
close(SettingsOut);
convert:=true;
except
convert:=false;
end;
//Temporäre Dateien löschen
if (FileExists(ExtractFilePath(Application.ExeName)+'/sat.tmp')=true) then DeleteFile(ExtractFilePath(Application.ExeName)+'/sat.tmp');
if (FileExists(ExtractFilePath(Application.ExeName)+'/tv.tmp')=true) then DeleteFile(ExtractFilePath(Application.ExeName)+'/tv.tmp');
if (FileExists(ExtractFilePath(Application.ExeName)+'/tp.tmp')=true) then DeleteFile(ExtractFilePath(Application.ExeName)+'/tp.tmp');
if (FileExists(ExtractFilePath(Application.ExeName)+'/rad.tmp')=true) then DeleteFile(ExtractFilePath(Application.ExeName)+'/rad.tmp');
if (FileExists(ExtractFilePath(Application.ExeName)+'/srv.tmp')=true) then DeleteFile(ExtractFilePath(Application.ExeName)+'/srv.tmp');
//Bedienung freigeben
Form1.Button1.Visible:=true;
OpenControls;
end;
function Version (): ShortString; stdcall;
begin
// Version:=GetVersion(Application.ExeName);
Version:=GetVersion('TSAPI.DLL');
end;
function GetModelFromFile(SettingsFile: ShortString): ShortString; stdcall;
//Receivermodell aus Settingsdatei auslesen
var
Datei: TextFile;
buffer: String;
Receiver: String;
BasicSettings: Boolean;
begin
//Pfadangabe überprüfen
if (SettingsFile='') or (FileExists(SettingsFile)=false) then
begin
GetModelFromFile:='';
exit;
end;
//Grundeinstellungen setzen
GlobalBreak:=false;
BasicSettings:=false;
//Bedienung sperren
CloseControls;
//Modus Status
Modus('Suche Receivertyp in "'+ExtractFileName(SettingsFile)+'"');
//Settings Datei öffnen
Assign(Datei, SettingsFile);
Reset(Datei);
//Settings nach Receivermodell auswerten
Application.ProcessMessages;
while not EOF(Datei) or (GlobalBreak=true) do
begin
buffer:='';
readln(Datei,buffer);
//[0x6 basicSettings] Abschnitt auswerten
if (AnsiContainsStr(buffer, '[0x6 basic')=true) then BasicSettings:=true;
//Receivernamen in Abschnitt [0x6 basicSettings] rausfiltern
if (BasicSettings=true) then
begin
if (AnsiContainsStr(buffer, '"')=true) then
begin
Receiver:=MidStr(buffer,AnsiPos('"',buffer)+1,LastDelimiter('"',buffer)-AnsiPos('"',buffer)-1);
break;
end;
//Abbruch wenn nachfolgender Abschnitt erreicht ist
if (AnsiContainsStr(buffer, '[0x')=true) then
end;
end;
//Settingsdatei schließen
Close(Datei);
//Status
Status('Receivertyp: '+Receiver);
//Bedienung wieder entriegeln
OpenControls;
//Receivertyp zurückmelden
GetModelFromFile:=Receiver;
end;
function AutoDownload(SettingsFile: ShortString; COM: Integer): Boolean; stdcall;
//Download mit automatischer Bestimmung der Receiver Serie
var
Series: Integer;
begin
if PortExists(COM)=false then
begin
AutoDownload:=false;
exit;
end;
Series:=GetSeriesFromReceiver(COM);
if ((GlobalBreak=true) or (Series<0)) then
begin
GlobalBreak:=false;
AutoDownload:=false;
exit;
end;
delay(1000);
AutoDownload:=Download(SettingsFile,COM,Series);
end;
function AutoUpload(SettingsFile: ShortString; COM: Integer; IgnoreHardwareCheck: Boolean): Boolean; stdcall;
var
Series: Integer;
ModelFromFile: String;
ModelFromReceiver: String;
begin
if PortExists(COM)=false then
begin
AutoUpload:=false;
exit;
end;
Series:=0;
if IgnoreHardwareCheck=true then
begin
Series:=GetSeriesFromReceiver(COM);
Application.ProcessMessages;
if Series<0 then
begin
AutoUpload:=false;
exit;
end;
end
else
begin
ModelFromReceiver:=GetModelFromReceiver(COM);
Application.ProcessMessages;
if GlobalBreak=true then
begin
GlobalBreak:=false;
AutoUpload:=false;
exit;
end;
ModelFromFile:=GetModelFromFile(SettingsFile);
Application.ProcessMessages;
if GlobalBreak=true then
begin
GlobalBreak:=false;
AutoUpload:=false;
exit;
end;
if ModelFromReceiver<>ModelFromFile then
begin
AutoUpload:=false;
exit;
end;
end;
if GlobalBreak=true then
begin
GlobalBreak:=false;
AutoUpload:=false;
exit;
end;
Application.ProcessMessages;
delay(1000);
Application.ProcessMessages;
AutoUpload:=Upload(SettingsFile,COM,Series);
end;
function Upload(SettingsFile: ShortString; COM: Integer; Series: Integer): Boolean; stdcall;
//Settings von PC in Receiver einspielen
var
buffer: String;
buffer2: String;
Counter: Integer;
Counter2: Integer;
Counter3: Integer;
dbload: Boolean;
Datei: Textfile;
DataBase: Boolean;
begin
{$IFDEF TIMELOCK}
if CheckTimer=true then
begin
upload:=false;
exit;
end;
{$ENDIF}
//Pfadangabe überprüfen
if (SettingsFile='') or (FileExists(SettingsFile)=false) then
begin
Upload:=false;
exit;
end;
//Grundeinstellungen definiert setzen
GlobalBreak:=false;
DataBase:=false;
//COM Port Einstellungen übernehmen
//COM Schnittstelle
if (COM>0) then
begin
Form1.AfComPort1.ComNumber:=COM;
end
else
begin
upload:=false;
exit;
end;
//Parity
if (Series=1)then
Form1.AfComPort1.Parity:=paEven
else
Form1.AfComPort1.Parity:=paNone;
//Bedienung sperren
CloseControls;
//ProgressBar einblenden
Form1.ProgressBar1.Visible:=true;
Form1.ProgressBar1.Max:=0;
//Modus
Modus('Upload COM'+IntToStr(COM));
//COM Port öffnen
Form1.AfComPort1.Close;
Form1.AfComPort1.Open;
//Settings Datei öffnen
//FileMode := fmOpenRead;
Assign(Datei,SettingsFile);
Reset(Datei);
//Startzeit:=Time;
Counter:=0;
while (Counter<100) and (GlobalBreak=false) do
begin
Application.ProcessMessages;
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
Form1.AfComPort1.WriteString('dbload');
delay(100);
buffer2:='';
buffer2:=Form1.AfComPort1.ReadString;
if (LeftStr(buffer2,1)=#1) then
begin
Counter:=0;
break;
end
else
Counter:=Counter+1;
end;
//Statusanzeige
Status('[database]');
while (GlobalBreak=false) and (Counter<100) do
begin
//Zeile aus Datenbank einlesen und Sendepaket erzeugen
buffer:='';
readln(Datei,buffer);
if length(buffer)=0 then break;
// if (AnsiContainsStr(buffer, '[0x')=true) and (AnsiContainsStr(buffer, ']')=true) and (AnsiContainsStr(buffer, '0x')=true) or (AnsiContainsStr(buffer, '[database]')=true) then
//Form1.JvStatusBar1.Panels[0].Text:=MidStr(buffer,AnsiPos('[',buffer)+1,AnsiPos(']',buffer)-AnsiPos('[',buffer)-1);
//Form1.Caption:=MidStr(buffer,AnsiPos('[',buffer)+1,AnsiPos(']',buffer)-AnsiPos('[',buffer)-1);
buffer:=StringReplace(buffer,#10,'',[rfReplaceAll, rfIgnoreCase]);
buffer:=StringReplace(buffer,#13,'',[rfReplaceAll, rfIgnoreCase]);
//DigiCorder S2 Anpassung für Abschnitt [0x6 basicSettings] Eintrag RF0=
if LeftStr(buffer,2)='RF' then
buffer:=StringReplace(buffer,'RF','F',[]);
//[database] Abschnitt Auswertung
if (LeftStr(buffer,1)='[') and (DataBase=true) then
begin
DataBase:=false;
end;
if LeftStr(buffer,10)='[database]' then
DataBase:=true;
if (DataBase=true) and (LeftStr(buffer,1)='I') then
begin
try
Form1.ProgressBar1.Max:=Form1.ProgressBar1.Max+1+StrToInt(MidStr(buffer,LastDelimiter('=',buffer)+1,Length(buffer)-LastDelimiter('=',buffer)));
if Form1.ProgressBar1.Position<Form1.ProgressBar1.Max then
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+1;
finally
//
end;
end;
//Abschnitte zählen
if (LeftStr(buffer,1)='R') and (DataBase=false) and (Form1.ProgressBar1.Position<Form1.ProgressBar1.Max) then
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+1;
//Statusanzeige
if AnsiPos('[0x',buffer)>0 then
begin
Status(MidStr(buffer,AnsiPos('[',buffer),AnsiPos(']',buffer)-AnsiPos('[',buffer)+1));
end;
Status2(buffer);
buffer:=MakePaket(buffer);
//Paket senden
Form1.AfComPort1.WriteString(buffer);
buffer2:='';
while Counter<100 do
begin
//Antwort von Receiver empfangen
//delay(50);
buffer2:=buffer2+Form1.AfComPort1.ReadString;
Application.ProcessMessages;
if GlobalBreak=true then break;
if EOF(Datei) then break;
//Paket von Receiver bestätigt
if ((RightStr(buffer2,1)=#1) or (RightStr(buffer2,1)=#3)) then
begin
buffer2:='';
Counter:=0;
break;
end
else
begin
delay(5);
Counter:=Counter+1;
end;
end;
end;
//Stop-Signal schicken
Status('Beende Verbindung an COM'+IntToStr(COM)+'...');
Status2('');
Counter3:=0;
for Counter2:=1 to 7 do
begin
while (Counter3<100) and (GlobalBreak=false) do
begin
Application.ProcessMessages;
delay(25);
buffer2:='';
buffer2:=Form1.AfComPort1.ReadString;
if (LeftStr(buffer2,1)=#1) then
begin
Counter3:=0;
break;
end
else
Counter3:=Counter3+1;
end;
while (Counter3<100) and (GlobalBreak=false) do
begin
Application.ProcessMessages;
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
Form1.AfComPort1.WriteString(#85+#85+#0+#0);
delay(25);
buffer2:='';
buffer2:=Form1.AfComPort1.ReadString;
if (LeftStr(buffer2,1)=#1) then
begin
Form1.AfComPort1.WriteString(#1);
Counter3:=0;
break;
end
else
Counter3:=Counter3+1;
end;
end;
//Datei und COM Port schließen
Form1.AfComPort1.Close;
close(Datei);
//Auswertung ob der Upload erfolgreich war
if (GlobalBreak=true) or (Counter>99) then
dbload:=false
else
dbload:=true;
//Rückgabewert der Funktion setzen
Upload:=dbload;
//Bedienung freigeben
OpenControls;
end;
function Download(SettingsFile: ShortString; COM: Integer; Series: Integer): Boolean; stdcall;
//Settings aus Gerät auslesen
var
Paket: AnsiString;
buffer: String;
Counter: Integer;
InBufferUsed: Integer;
CheckSum1: String;
CheckSum2: String;
Settings: Text;
DataBase: Boolean;
begin
{$IFDEF TIMELOCK}
if CheckTimer=true then
begin
Download:=false;
exit;
end;
{$ENDIF}
//Bedienung sperren
CloseControls;
//Modus Status
Modus('Download COM'+IntToStr(COM));
//Grundeinstellungen setzen
Counter:=0;
GlobalBreak:=false;
DataBase:=false;
Form1.ProgressBar1.Position:=0;
Form1.ProgressBar1.Visible:=true;
//Anhand von Receiver Serie COM Port Einstellung setzen
if Series=1 then
Form1.AfComPort1.Parity:=paEven
else
Form1.AfComPort1.Parity:=paNone;
//COM Port setzen
Form1.AfComPort1.ComNumber:=COM;
//COM Port definiert öffnen
Form1.AfComPort1.Close;
Form1.AfComPort1.Open;
//Settings Datei erzeugen
if (FileExists(SettingsFile)=true) then DeleteFile(SettingsFile);
assign(Settings,SettingsFile);
rewrite(Settings);
//COM Port Puffer leeren
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
//Datenbank auslesen
Form1.AfComPort1.WriteString('dbdump');
//[database] Abschnitt finden
while (Counter<200) and (GlobalBreak=false) do
begin
delay(25);
Application.ProcessMessages;
buffer:=Form1.AfComPort1.ReadString;
Paket:=Paket+buffer;
if AnsiPos('[database]',GetPaket(Paket))>0 then
begin
Status('[database]');
//markieren das Schleife in [database] Abschnitt ist
DataBase:=true;
if GetPaket(buffer)='' then
begin
buffer:=LeftStr(Buffer,Length(buffer)-1);
buffer:=RightStr(Buffer,Length(buffer)-4);
buffer:=StringReplace(buffer,#10,#13+#10,[rfReplaceAll, rfIgnoreCase]);
end
else
buffer:=GetPaket(buffer);
if Length(RightStr(Buffer,Length(buffer)-LastDelimiter('[',buffer)+1))>0 then
buffer:=RightStr(Buffer,Length(buffer)-LastDelimiter('[',buffer)+1);
//Application.MessageBox(PChar(buffer),PChar('DEBUG'));
//if ((AnsiPos('[database]',buffer)=1) and (AnsiPos('FrontEnd',buffer)>1))then
if (AnsiPos('[database]',buffer)=1)then
begin
write(Settings,buffer);
break;
end
else
begin
Counter:=Counter+1;
buffer:='';
end;
end
else
Counter:=Counter+1;
end;
//bei Fehler oder Abbruch Funktion verlassen
if (Counter>199) or (GlobalBreak=true) then
begin
Form1.AfComPort1.Close;
OpenControls;
Close(Settings);
Download:=false;
exit;
end;
//COM Port Puffer leeren
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
//nächstes Paket anfordern
Counter:=0;
Form1.AfComPort1.WriteString(#1);
while (Counter<200) and (GlobalBreak=false) do
begin
delay(3);
InBufferUsed:=0;
buffer:='';
//warten bis Empfangspuffer sich nicht mehr füllt
while Form1.AfComPort1.InBufUsed<>InBufferUsed do
begin
InBufferUsed:=Form1.AfComPort1.InBufUsed;
delay(3)
end;
Application.ProcessMessages;
buffer:=Form1.AfComPort1.ReadString;
//wenn Receiver die Übertragung beendet Schleife verlassen
if buffer=#85+#85+#0+#0 then break;
//Puffer Checksummen festlegen
//Checksumme 1 -> IST Checksumme des Paketes
//Checksumme 2 -> SOLL Checksumme des Paketes
if buffer<>'' then
begin
//Sonderfall wenn 2 x 0A Bytes gesendet werden -> Checksumme SOLL = 10
if AnsiPos(#10+#10,buffer)>0 then
begin
{
if AnsiPos('UU',buffer)>0 then
begin
CheckSum1:=MidStr(buffer,AnsiPos('UU',buffer)+3,length(buffer)-AnsiPos('UU',buffer)-4);
end
else
CheckSum1:=MidStr(buffer,4,length(buffer)-3);
CheckSum1:=LeftStr(CheckSum1,AnsiPos(#10,CheckSum1));
//CheckSum1:=IntToHex(CalcPaketChkSum(CheckSum1)+10,1);
}
CheckSum1:='0A';
CheckSum2:='0A';
end
//Normalfall
else
begin
CheckSum1:=IntToHex(CalcPaketChkSum(AnsiMidStr(buffer,AnsiPos('UU',buffer)+3,LastDelimiter(Chr(10),buffer)-(AnsiPos('UU',buffer)+3)))+10,1);
CheckSum2:=IntToHex(Ord(AnsiMidStr(buffer,LastDelimiter(Chr(10),buffer)+1,1)[1]),1);
end;
end
else //Fehler bei der Checksummenberechnung mit 2 unterschiedlichen Checksummen quittieren
begin
CheckSum1:='01';
CheckSum2:='02';
end;
//Checksummen formatieren
CheckSum1:=RightStr(CheckSum1,2);
CheckSum2:=RightStr(CheckSum2,2);
CheckSum1:=StringOfChar('0',2-Length(CheckSum1))+CheckSum1;
CheckSum2:=StringOfChar('0',2-Length(CheckSum2))+CheckSum2;
//COM Port Puffer leeren
Form1.AfComPort1.PurgeRX;
Form1.AfComPort1.PurgeTX;
//Statusanzeige
//Paket:=StringReplace(Paket,#5,'',[rfReplaceAll, rfIgnoreCase]);
try
if AnsiPos('[0x',buffer)>0 then
begin
Status(StringReplace(MidStr(buffer,AnsiPos('[',buffer),AnsiPos(']',buffer)-AnsiPos('[',buffer)+1),#5,'',[rfReplaceAll, rfIgnoreCase]));
end;
Status2(GetPaket(buffer));
finally
//
end;
//Checksumme des Pakets überprüfen
if CheckSum1=CheckSum2 then //korrektes Paket
begin
//DigiCorder S2 Anpassung für Abschnitt [0x6 basicSettings] Eintrag RF0=
buffer:=GetPaket(buffer);
if LeftStr(buffer,2)='RF' then
buffer:=StringReplace(buffer,'RF','F',[]);
//[database] Abschnitt Auswertung
if (LeftStr(buffer,2)='[0') and (DataBase=true) then
begin
DataBase:=false;
end;
if (DataBase=true) and (LeftStr(buffer,1)='I') then
begin
try
if (LeftStr(buffer,1)='2') then
ShowMessage('"'+MidStr(buffer,LastDelimiter('=',buffer)+1,Length(buffer)-2-Pos('=',buffer))+'"');
Form1.ProgressBar1.Max:=Form1.ProgressBar1.Max+1+StrToInt(MidStr(buffer,LastDelimiter('=',buffer)+1,Length(buffer)-2-LastDelimiter('=',buffer)));
if Form1.ProgressBar1.Position<Form1.ProgressBar1.Max then
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+1;
finally
//
end;
end;
//Abschnitte zählen
if (LeftStr(buffer,1)='R') and (DataBase=false) and (Form1.ProgressBar1.Position<Form1.ProgressBar1.Max) then
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+1;
write(Settings,buffer);
//write(Settings,GetPaket(buffer));
Form1.AfComPort1.WriteString(#1);
Counter:=0;
end
else //fehlerhaftes Paket
begin
//write(Settings,'-->'+CheckSum1+' '+CheckSum2+#13+#10+'-->'+buffer+'<--'+#13+#10);
Form1.AfComPort1.WriteString(#0);
Counter:=Counter+1;
end;
end;
//Settings Datei schließen
Close(Settings);
//COM Port schließen
Form1.AfComPort1.Close;
//Erfolg melden
if ((GlobalBreak=false) and (Counter<200)) then
Download:=true
else
Download:=false;
//Bedienung entsperren
//Application.MessageBox(PChar(IntToStr(Counter)+' '+BoolToStr(GlobalBreak)),PChar('DEBUG'));
OpenControls;
end;
exports
Version,
About,
Convert,
XML,
CSV,
GetSeriesFromReceiver,
GetModelFromFile,
GetModelFromReceiver,
Download,
Upload,
AutoDownload,
AutoUpload,
FlashReset,
PortExists;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
Self.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
//API Formular immer im Vordergrund halten
begin
with Self do {Form1,...}
SetWindowPos(Handle, // handle to window
HWND_TOP, // placement-order handle {*}
Left, // horizontal position
Top, // vertical position
Width,
Height,
// window-positioning options
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
{* Other Values:
HWND_BOTTOM Places the window at the bottom of the Z order.
HWND_NOTOPMOST Places the window above all non-topmost windows
HWND_TOP Places the window at the top of the Z order.
HWND_TOPMOST Places the window above all non-topmost windows.
The window maintains its topmost position even when it is deactivated.
}
end;
procedure TForm1.Button1Click(Sender: TObject);
//Abbruch
begin
GlobalBreak:=true;
end;
{$IFDEF TIMELOCK}
initialization
if CheckTimer=true then halt;
finalization
{$ENDIF}
end.