So, hier mal was ich bis jetzt habe:
Hier gibt es eine brauchbare Beschreibung zum Protokoll und Aufbau der ACK Message:
https://www.securityindustry.org/SiteAssets/Standards/Intrusion%20Subcommittee/DC-09%20Preparing%20for%20ANSI%20Public%20Review.pdf
- Im Symcon einen Server-Socket aufsetzten und auf den Port auf den die Secvest Konfiguriert ist einstellen
- RegisterVariable auf den Server-IO verweisen und als Action-Script:
<?
if ($_IPS['SENDER'] != "RegisterVariable")
return false;
$data = RegVar_GetBuffer($_IPS['INSTANCE']);
$data .= $_IPS['VALUE'];
// Ein einfacher Check. Die Strings haben immer die gleiche Länge (53)
if(strlen($data) != 53)
return false;
// Relevanten Teil ausschneiden, alles andere wird ignoriert
// Eine Prüfung des Protokols und des Absenders findet nicht statt
$cut = substr ($data, 40, 11);
SetValueString(27901 /*[EigeneProgramme\Alarmanlage\Secvest_CID_Receiver\CID_raw]*/, $cut);
$message = substr($data, 18, -22); // -1 is for the invisible <CR>
$messageACK = '"ACK"'.$message.'[]';
$crc = strtoupper(crc16($messageACK));
$len = "00".dechex(strlen($messageACK));
$output = "
".$crc.$len.$messageACK."\r";
// Ack senden (enpfangenen Datensatz echoen):
RegVar_SendPacket(42884 /*[EigeneProgramme\Alarmanlage\Secvest_ContactID_Buffer]*/, $output, "192.168.1.23", 1792);
// -------------------------------------------------------------
// CRC-16_ARC with the following parameter:
// Poly = 0x8005; Init = 0x0000; Xor = 0x0000
// Refin = True; Refout = True; Output in Hex
function crc16($data) {
$crc = 0x0000; // Init
$len = strlen($data);
$i = 0;
while ($len--) {
$crc ^= reversebyte(ord($data[$i++])) << 8;
$crc &= 0xffff;
for ($j = 0; $j < 8; $j++){
$crc = ($crc & 0x8000) ? ($crc << 1) ^ 0x8005 : $crc << 1;
$crc &= 0xffff;
}
}
// $crc ^= 0x0000; // Final XOR
$crc = reversebits($crc);
$crc = dechex($crc);
return $crc;
}
function reversebyte($byte) {
$ob = 0;
$b = (1 << 7);
for ($i = 0; $i <= 7; $i++) {
if (($byte & $b) !== 0) {
$ob |= (1 << $i);
}
$b >>= 1;
}
return $ob;
}
function reversebits($cc) {
$ob = 0;
$b = (1 << 15);
for ($i = 0; $i <= 15; $i++) {
if (($cc & $b) !== 0) {
$ob |= (1 << $i);
}
$b >>= 1;
}
return $ob;
}
// -------------------------------------------------------------
?>
- Das Decoder-Script auf die Symcon-Variable mit der Message triggern:
<?
/* ---------------------------------------------------------
Ademco Contact-ID Message Composition:
The form of the message is: ACCT MT QXYZ GG CCC S
ACCT = 4 Digit Account Number
MT = Message Type (18 = Contat ID) also possible 98
Q = Evant Qualifier
XYZ = Event Code
GG = Group/Partition Number (Teilbereich)
CCC = Zone Number or User Number!
(C) 2017, Stefan Frank, Version V0.02 (18-04-2017)
-------------------------------------------------------------- */
$CIDcodes = array(
100 => array('Medizinischer Alarm', 'Medizin. Alarm'),
101 => array('Pflege-Notfall', 'Medizin. Alarm'),
110 => array('Feueralarm', 'Feuer'),
120 => array('Ueberfall (Panik) Zone, Still, Tastatur, Funk-Bedienteil', 'Ueberfallalarm'),
121 => array('Bedrohungscode Alarm', 'Ueberfallalarm'),
129 => array('Ueberfall (Panik) bestaetigt', 'Ueberfallalarm'),
130 => array('Einbruchalarm', 'Einbruchalarm'),
137 => array('Sabotage Zentrale Gehaeusefront, Tastatur, Melder, Bedienteil, Schallgeber, Funk-Bedienteil, Externe Sirenen, UVM, Tuerschloss', 'Sabotagen'),
139 => array('Alarm Bestaetigung', 'Einbruchalarm'),
150 => array('Technischer Alarm', 'Technik'),
// 150 => array('Schluesselkasten Offen oder Geschlossen', 'Schluesselkasten'), // weitere Bedingung auswerten!
300 => array('Stoerung Aux 12V, System 12V', 'Stoerungen'),
301 => array('Stoerung A/C Stromnetz', 'Stoerungen'),
302 => array('Akku Zentrale Leer/Stoerung', 'Stoerungen'),
305 => array('System oder Teilbereich zurueckgesetzt', 'Info'),
311 => array('Akku Zentrale/Extern Leer/Fehlt', 'Stoerungen'),
320 => array('Stoerung Zone Externer Signalgeber, UVM Stoerung', 'Stoerungen'),
337 => array('Rauchwarnmelder/UVM (externe)PSU Stoerung', 'Stoerungen'),
338 => array('Externe Sirene/UVM leere Batterie/Akku Stoerung', 'Stoerungen'),
338 => array('Externe PSU niedrige Spannung via Zone n', 'Stoerungen'),
342 => array('Externe PSU AC Stoerung', 'Stoerungen'),
344 => array('RF Jamming Stoerung', 'Stoerungen'),
351 => array('Kommunikationsweg Stoerung', 'Stoerungen'),
373 => array('Rauchwarnmelder Stoerung', 'Stoerungen'),
375 => array('Zone Ueberfallkomponente Stoerung', 'Stoerungen'),
381 => array('Supervision Stoerung Zone, Funk-Bedienteil, Externe Sirene, UVM, Tuerschloesser', 'Stoerungen'),
384 => array('Zone leere Batterie Stoerung', 'Stoerungen'),
401 => array('System oder Teilbereich aktiviert und deaktiviert', 'Aktiv./Deaktiv.'), // weitere Bedingung auswerten!
// 401 => array('System oder Teilbereich intern aktiviert', 'Intern Aktiv'), // weitere Bedingung auswerten!
406 => array('Alarmabbruch', 'Einbruchalarm'),
409 => array('System oder Teilbereich mit Schluesselschalter aktiviert und deaktiviert', 'Aktiv./Deaktiv.'), // weitere Bedingung auswerten!
// 409 => array('System oder Teilbereich mit Schluesselschalter intern aktiviert', 'Intern Aktiv'), // weitere Bedingung auswerten!
412 => array('Herunterladen erfolgreich', 'Herunterladen'),
457 => array('Ausgang Zeitueberschreitung', 'Info'),
461 => array('Eingabe von 4 falschen Benutzercodes hintereinander', 'Sabotagen'),
573 => array('Benutzer/System Zone ausgeblendet, Zone eingeblendet', 'Info'),
601 => array('Manuelles Ausloesen Test Report', 'Test'),
602 => array('Periodischer/Automatischer Test Report', 'Test'),
625 => array('Zeit und Datum neu eingestellt', 'Info'),
627 => array('Errichtermodus Start Zentrale (Web)', 'Info'),
628 => array('Errichtermodus Ende Zentrale (Web)', 'Info'),
);
$EVENTcodes = array(
1 => 'Alarm neu (Event)',
2 => 'Zustand offen/deaktiviert',
3 => 'Alarm aus (Restore)',
4 => 'Zustand geschlossen/aktiviert',
5 => 'kein Alarm',
6 => 'Alarm Status (Update)',
);
$ZONEcodes = array(
'000' => 'Errichter oder undefiniert', // Users starting here
'001' => 'User1 (Admin)',
'002' => 'User2',
'003' => 'User3',
'051' => 'Schnell Aktiv',
'052' => 'Level 4 Benutzer',
'053' => 'System',
'054' => 'Schluesselschalter',
'055' => 'Fernzugriff AES/NSL',
'056' => 'Downloader',
'057' => 'Virtuelles Bedienteil',
'058' => 'RF Prozess',
'059' => 'Ausgangsruf Zentrale',
'060' => 'IP-Finder',
'061' => 'ABUS-Server DDNS Client',
'101' => 'Melder XXX (Draht)', // Zones staring here
'201' => 'Kontakt Kueche Fenster (Funk)',
'203' => 'Kontakt Wohnzimmer Terassentueren (Funk)',
'301' => 'Kontakt Haustuer',
);
$PARTITIONcodes = array(
0 => 'undefiniert',
1 => 'Haus',
2 => 'Bereich 2',
3 => 'Bereich 3',
3 => 'Bereich 3',
);
// Start decodierung:
$event = '-unknown-';
$cidLong = '-unknown-';
$cidGroup = '-unknown-';
$partition = '-unknown-';
$zone = '-unknown-';
$raw = GetValueString(27901 /*[EigeneProgramme\Alarmanlage\Secvest_CID_Receiver\CID_raw]*/);
echo $raw."<br>";
$eventCODE = substr($raw, 1, 1);
$event = $EVENTcodes[$eventCODE];
SetValueString(52355 /*[EigeneProgramme\Alarmanlage\Secvest_CID_Decoder\EventTyp]*/, $event);
echo $eventCODE.':'.$event."<br>";;
$CIDcode = substr($raw, 1, 3);
$cidLong = $CIDcodes[$CIDcode][0];
$cidGroup = $CIDcodes[$CIDcode][1];
SetValueString(39107 /*[EigeneProgramme\Alarmanlage\Secvest_CID_Decoder\Meldung]*/, $cidLong);
SetValueString(56191 /*[EigeneProgramme\Alarmanlage\Secvest_CID_Decoder\MeldungGruppe]*/, $cidGroup);
echo $CIDcode.':'.$cidLong.' - '.$cidGroup."<br>";;
$partitionCODE = substr($raw, 6, 1);
$partition = $PARTITIONcodes[$partitionCODE];
SetValueString(22173 /*[EigeneProgramme\Alarmanlage\Secvest_CID_Decoder\Teilbereich]*/, $partition);
echo $partitionCODE.':'.$partition."<br>";;
$zoneCODE = substr($raw, 8, 3);
$zone = $ZONEcodes[$zoneCODE];
SetValueString(48644 /*[EigeneProgramme\Alarmanlage\Secvest_CID_Decoder\ZoneUser]*/, $zone);
echo $zoneCODE.':'.$zone."<br>";
$now = date("d.m.Y H:i");
$longTEXT = $now.': '.$event.':'.$cidLong.':'.$partition.':'.$zone;
SetValueString(49306 /*[EigeneProgramme\Alarmanlage\Secvest_CID_Decoder\LongStatusText]*/, $longTEXT);
?>
Leider scheint die Anlage immer noch nicht die ACK Message zu verarbeiten. In der Folge wird die erste Message endlos wiederholt und keine weitere gesendet.
So sieht der Trace aus:
RECEIVED [192.168.1.23:9999] <LF>D3A6002B"ADM-CID"0001L0#224401[#224401|1628 01 000]<CR>
TRANSMIT [192.168.1.23:1792] <LF>C9760014"ACK"0001L0#224401<CR>
Hat jemand eine Idee warum beim Debug der RegVariable Port 9999 angezeigt wird, obwohl der Socket nur 1792 öffnet?
Received Message: "ADM-CID"0001L0#224401[#224401|1628 01 000]
Length = 002Bh; CRC16: D3A6h
Transmitted Message: "ACK"0001L0#224401
Length = 0014h; CRC16: C976h
Ich habe die CRC Berechnung hier geprüft:
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
Da ich hiermit die Empfangene CRC immer korrekt nachrechnen kann, gehe ich davon aus, dass die CRC auch bei meiner selbst berechneten Transmit-Message korrekt ist, weil meine Funktion auf das gleiche Ergebnis kommt.