Initial commit for SIA HS Daemon.

This commit is contained in:
Wilco Baan Hofman 2012-07-28 21:44:09 +02:00
commit 9d49055b90
10 changed files with 2478 additions and 0 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
*.o
*.d
siahsd
tryouts/crc_validate

38
Makefile Normal file
View file

@ -0,0 +1,38 @@
CC := gcc
# Enable for debug
CFLAGS := -g -ggdb -std=c99 -Wall -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wstrict-prototypes -Werror
INCLUDES := -I.
siahsd_LIB := -ltalloc
siahsd_OBJ := sia.o siahsd.o
OBJ := $(siahsd_OBJ)
binaries := siahsd
all: $(binaries)
clean:
rm -f $(binaries)
rm -f $(OBJ)
rm -f $(OBJ:.o=.d)
distclean: clean
rm -f tags
siahsd: $(siahsd_OBJ)
@echo Linking $@
@$(CC) $(siahsd_OBJ) $(siahsd_LIB) -o siahsd
ctags:
ctags `find -name \*.[ch]`
%.o: %.c
@echo Compiling $*.c
@$(CC) -c $(CFLAGS) $(INCLUDES) -o $*.o $<
@$(CC) -MM $(CFLAGS) -MT $*.o $(INCLUDES) -o $*.d $<
-include $(OBJ:.o=.d)

646
sia.c Normal file
View file

@ -0,0 +1,646 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "sia.h"
const struct {
const char *code;
const char *string;
const char *description;
} sia_codes[] = {
{ "AA", "Alarm panel substitution",
"An attempt to substitute an alternate alarm panel for a secure panel has been made" },
{ "AB", "User Abort",
"An event message was not sent due to User action" },
{ "AN", "Analog Restore",
"An analog fire sensor has been restored to normal operation" },
{ "AR", "AC Restore",
"AC Power has been restored" },
{ "AS", "Analog Service",
"An analog fire sensor needs to be cleaned or calibrated" },
{ "AT", "AC Trouble",
"AC power has been failed" },
{ "BA", "Burglary Alarm",
"Burglary zone has been violated while armed" },
{ "BB", "Burglary Bypass",
"Burglary zone has been bypassed" },
{ "BC", "Burglary Cancel",
"Alarm has been cancelled by authorized user" },
{ "BD", "Swinger Trouble",
"A non-fire zone has been violated after a Swinger Shutdown on the zone" },
{ "BE", "Swinger Trouble restore",
"A non-fire zone restores to normal from a Swinger Trouble state" },
{ "BG", "Unverified Event - Burglary",
"A point assigned to a Cross Point group has gone into alarm but the Cross Point remained normal" },
{ "BH", "Burglary Alarm restore",
"Burglary Alarm condition eliminated" },
{ "BJ", "Burglary Trouble restore",
"Burglary Trouble condition eliminated" },
{ "BM", "Burglary Alarm cross point",
"Burglary alarm w/cross point also in alarm - alarm verified" },
{ "BR", "Burglary Restore",
"Alarm/trouble condition has been eliminated" },
{ "BS", "Burglary Supervisory",
"Unsafe intrusion detection system condition" },
{ "BT", "Burglary Trouble",
"Burglary zone disabled by fault" },
{ "BU", "Burglary Unbypass",
"Zone bypass has been removed" },
{ "BV", "Burglary Verified",
"A burglary alarm has occurred and been verified within programmed conditions. (zone or point not sent)" },
{ "BX", "Burglary Test",
"Burglary zone activated during testing" },
{ "BZ", "Missing Supervision",
"A non-fire Supervisory point has gone missing" },
{ "CA", "Automatic Closing",
"System armed automatically" },
{ "CD", "Closing delinquent",
"The system has not been armed for a programmed amount of time" },
{ "CE", "Closing extend",
"Extend closing time" },
{ "CF", "Forced Closing",
"System armed, some zones not ready" },
{ "CG", "Close Area",
"System has been partially armed" },
{ "CI", "Fail to Close",
"An area has not been armed at the end of the closing window" },
{ "CL", "Late Close",
"An area was armed after the closing window" },
{ "CK", "Early Close",
"An area was armed before the closing window" },
{ "CL", "Closing Report",
"System armed, normal" },
{ "CM", "Missing Alarm - Recent Closing",
"A point has gone missing within 2 minutes of closing" },
{ "CO", "Command Sent",
"A command has been sent to an expansion/peripheral device" },
{ "CP", "Automatic Closing",
"System armed automatically" },
{ "CQ", "Remote Closing",
"The system was armed from a remote location" },
{ "CS", "Closing Keyswitch",
"Account has been armed by keyswitch" },
{ "CT", "Late to Open",
"System was not disarmed on time" },
{ "CW", "Was Force Armed",
"Header for a force armed session, forced point msgs may follow" },
{ "CX", "Custom Function Executed",
"The panel has executed a preprogrammed set of instructions" },
{ "CZ", "Point Closing",
"A point, as opposed to a whole area or account, has closed" },
{ "DA", "Card Assigned",
"An access ID has been added to the controller" },
{ "DB", "Card Deleted",
"An access ID has been deleted from the controller" },
{ "DC", "Access Closed",
"Access to all users prohibited" },
{ "DD", "Access Denied",
"Access denied, unknown code" },
{ "DE", "Request to Enter",
"An access point was opened via a Request to Enter device" },
{ "DF", "Door Forced",
"Door opened without access request" },
{ "DG", "Access Granted",
"Door access granted" },
{ "DH", "Door Left Open - Restoral",
"An access point in a Door Left Open state has restored" },
{ "DI", "Access Denied - Passback",
"Access denied because credential has not exited area before attempting to re-enter same area" },
{ "DJ", "Door Forced - Trouble",
"An access point has been forced open in an unarmed area" },
{ "DK", "Access Lockout",
"Access denied, known code" },
{ "DL", "Door Left Open - Alarm",
"An open access point when open time expired in an armed area" },
{ "DM", "Door Left Open - Trouble",
"An open access point when open time expired in an unarmed area" },
{ "DN", "Door Left Open",
"An access point was open when the door cycle time expired" },
{ "DO", "Access Open",
"Access to authorized users allowed" },
{ "DP", "Access Denied - Unauthorized Time",
"An access request was denied because the request is occurring outside the users authorized time window(s)" },
{ "DQ", "Access Denied - Unauthorized Arming State",
"An access request was denied because the user was not authorized in this area when the area was armed" },
{ "DR", "Door Restoral",
"Access alarm/trouble condition eliminated" },
{ "DS", "Door Station",
"Identifies door for next report" },
{ "DT", "Access Trouble",
"Access system trouble" },
{ "DU", "Dealer ID",
"Dealer ID number" },
{ "DV", "Access Denied - Unauthorized Entry Level",
"An access request was denied because the user is not authorized in this area" },
{ "DW", "Access Denied - Interlock",
"An access request was denied because the doors associated interlock point is open" },
{ "DX", "Request to Exit",
"An access point was opened via a Request to Exit device" },
{ "DY", "Door Locked",
"The doors lock has been engaged" },
{ "DZ", "Access Denied - Door Secured",
"An access request was denied because the door has been placed in an Access Closed state" },
{ "EA", "Exit Alarm",
"An exit zone remained violated at the end of the exit delay period" },
{ "EE", "Exit Error",
"An exit zone remained violated at the end of the exit delay period ?! Trouble?" },
{ "EJ", "Expansion Tamper Restore",
"Expansion device tamper restoral" },
{ "EM", "Expansion Device Missing",
"Expansion device missing" },
{ "EN", "Expansion Missing Restore",
"Expansion device communications re-established" },
{ "ER", "Expansion Restoral",
"Expansion device trouble eliminated" },
{ "ES", "Expansion Device Tamper",
"Expansion device enclosure tamper" },
{ "ET", "Expansion Trouble",
"Expansion device trouble" },
{ "EX", "External Device Condition",
"A specific reportable condition is detected on an external device" },
{ "EZ", "Missing Alarm - Exit Error",
"A point remained missing at the end of the exit delay period" },
{ "FA", "Fire Alarm",
"Fire condition detected" },
{ "FB", "Fire Bypass",
"Fire zone has been bypassed" },
{ "FC", "Fire Cancel",
"A Fire Alarm has been cancelled by an authorized person" },
{ "FG", "Unverified Event - Fire",
"A point assigned to a Cross Point group has gone into alarm but the Cross Point remained normal" },
{ "FH", "Fire Alarm Restore",
"Fire alarm condition eliminated" },
{ "FI", "Fire Test Begin",
"The transmitter area's fire test has begun" },
{ "FJ", "Fire Trouble Restore",
"Fire trouble condition eliminated" },
{ "FK", "Fire Test End",
"The transmitter area's fire test has ended" },
{ "FL", "Fire Alarm Silenced",
"The fire panels sounder was silenced by command" },
{ "FM", "Fire Alarm - Cross point",
"Fire Alarm with Cross Point also in alarm verifying the Fire Alarm" },
{ "FQ", "Fire Supervisory Trouble Restore",
"A fire supervisory zone that was in trouble condition has now restored to normal" },
{ "FR", "Fire Restoral",
"A fire supervisory zone that was in trouble condition has now restored to normal" },
{ "FS", "Fire Supervisory",
"Unsafe fire detection system condition" },
{ "FT", "Fire Trouble",
"Fire Zone disabled by fault" },
{ "FU", "Fire Unbypass",
"Fire Bypass has been removed" },
{ "FV", "Fire Supervision Restore",
"A fire supervision zone that was in alarm has restored to normal" },
{ "FW", "Fire Supervisory Trouble",
"A fire supervisory zone is now in a trouble condition" },
{ "FX", "Fire Test",
"Fire zone activated during test" },
{ "FY", "Missing Fire Trouble",
"A fire point is now logically missing" },
{ "FZ", "Missing Fire Supervision",
"A Fire Supervisory point has gone missing" },
{ "GA", "Gas Alarm",
"Gas alarm condition detected" },
{ "GB", "Gas Bypass",
"Gas zone has been bypassed" },
{ "GH", "Gas Alarm Restore",
"Gas alarm condition eliminated" },
{ "GJ", "Gas Trouble Restore",
"Gas trouble condition eliminated" },
{ "GR", "Gas Restore",
"Gas alarm/trouble condition has been eliminated" },
{ "GS", "Gas Supervisory",
"Unsafe gas detection system condition" },
{ "GT", "Gas Trouble",
"Gas zone disabled by fault" },
{ "GU", "Gas Unbypass",
"Gas bypass has been removed" },
{ "GX", "Gas Test",
"Gas zone activated during test" },
{ "HA", "Holdup Alarm",
"Silent alarm, user under duress" },
{ "HB", "Holdup Bypass",
"Holdup zone has been bypassed" },
{ "HH", "Holdup Alarm Restore",
"Holdup alarm condition eliminated" },
{ "HJ", "Holdup Trouble Restore",
"Holdup trouble condition eliminated" },
{ "HR", "Holdup Restoral",
"Holdup alarm/trouble condition has been eliminated" },
{ "HS", "Holdup Supervisory",
"Unsafe holdup system condition" },
{ "HT", "Holdup Trouble",
"Holdup zone disabled by fault" },
{ "HU", "Holdup Unbypass",
"Holdup bypass has been removed" },
{ "IA", "Equipment Failure Condition",
"A specific, reportable condition is detected on a device" },
{ "IR", "Equipment Fail - Restoral",
"The equipment condition has been restored to normal" },
{ "JA", "User Code Tamper",
"Too many unsuccessful attempts have been made to enter a user ID" },
{ "JD", "Date Changed",
"The date was changed in the transmitter/receiver" },
{ "JH", "Holiday Changed",
"The transmitter's holiday schedule has been changed" },
{ "JK", "Latchkey Alert",
"A designated user passcode has not been entered during a scheduled time window" },
{ "JL", "Log Treshold",
"The transmitter's log memory has reached its threshold level" },
{ "JO", "Log Overflow",
"The transmitter's log memory has overflowed" },
{ "JP", "User on Premises",
"A designated user passcode has been used to gain access to the premises." },
{ "JR", "Schedule Executed",
"An automatic scheduled event was executed" },
{ "JS", "Schedule Changed",
"An automatic schedule was changed" },
{ "JT", "Time Changed",
"The time was changed in the transmitter/receiver" },
{ "JV", "User Code Changed",
"A user's code has been changed" },
{ "JX", "User Code Deleted",
"A user's code has been removed" },
{ "JY", "User Code Added",
"A users code has been added" },
{ "JZ", "User Level Set",
"A user's authority level has been set" },
{ "KA", "Heat Alarm",
"High temperature detected on premise" },
{ "KB", "Heat Bypass",
"Heat zone has been bypassed" },
{ "KH", "Heat Alarm Restore",
"Heat alarm condition eliminated" },
{ "KJ", "Heat Trouble Restore",
"Heat trouble condition eliminated" },
{ "KR", "Heat Restoral",
"Heat alarm/trouble condition eliminated" },
{ "KS", "Heat Supervisory",
"Unsafe heat detection system condition" },
{ "KT", "Heat Trouble",
"Heat zone disabled by fault" },
{ "KU", "Heat Unbypass",
"Heat zone bypass has been removed" },
{ "LB", "Local Program",
"Begin local programming" },
{ "LD", "Local Program Denied",
"Local program access code incorrect" },
{ "LE", "Listen-in Ended",
"The listen-in session has been terminated" },
{ "LF", "Listen-In Begin",
"The listen-in session with the RECEIVER has begun" },
{ "LR", "Phone Line Restoral",
"Phone line restored to service" },
{ "LS", "Local Program Success",
"Local programming successful" },
{ "LT", "Phone Line Trouble",
"Phone line trouble report" },
{ "LU", "Local Program Fail",
"Local programming unsuccessful" },
{ "LX", "Local Program Ended",
"A local programming session has been terminated" },
{ "MA", "Medical Alarm",
"Emergency assistance request" },
{ "MB", "Medical Bypass",
"Medical zone has been bypassed" },
{ "MH", "Medical Alarm Restore",
"Medical alarm condition eliminated" },
{ "MI", "Message",
"A canned message is being sent? Say What?" },
{ "MJ", "Medical Trouble Restore",
"Medical Trouble condition eliminated" },
{ "MR", "Medical Restoral",
"Medical alarm/trouble condition has been eliminated" },
{ "MS", "Medical Supervisory",
"Unsafe medical system condition exists" },
{ "MT", "Medical Trouble",
"Medical zone disabled by fault" },
{ "MU", "Medical Unbypass",
"Medical bypass has been removed" },
{ "NA", "No Activity",
"There has been no zone activity for a programmed amount of time" },
{ "NC", "Network Condition",
"A communications network has a specific reportable condition" },
{ "NF", "Forced Perimeter Alarm",
"Some zones/points not ready" },
{ "NL", "Perimeter Armed",
"An area has been perimeter armed" },
{ "NM", "Perimeter Armed - User Defined",
"A user defined area has been perimeter armed" },
{ "NR", "Network Restoral",
"A communications network has returned to normal operation" },
{ "NS", "Activity Resumed",
"A zone has detected activity after an alert" },
{ "NT", "Network Failure",
"A communications network has failed" },
{ "OA", "Automatic Opening",
"System has disarmed automatically" },
{ "OC", "Cancel Report",
"Untyped zone cancel" },
{ "OG", "Open Area",
"System has been partially disarmed" },
{ "OH", "Early to Open from Alarm",
"An area in alarm was disarmed before the opening window" },
{ "OI", "Fail to Open",
"An area has not been armed at the end of the opening window" },
{ "OJ", "Late Open",
"An area was disarmed after the opening window" },
{ "OK", "Early Open",
"An area was disarmed before the opening window" },
{ "OL", "Late to Open from Alarm",
"An area in alarm was disarmed after the opening window" },
{ "OP", "Opening Report",
"Account was disarmed" },
{ "OQ", "Remote Opening",
"The system was disarmed from a remote location" },
{ "OR", "Disarm From Alarm",
"Account in alarm was reset/disarmed" },
{ "OS", "Opening Keyswitch",
"Account has been disarmed by keyswitch" },
{ "OT", "Late to Close",
"System was not armed on time" },
{ "OU", "Output State - Trouble",
"An output on a peripheral device or NAC is not functioning" },
{ "OV", "Output State - Restore",
"An output on a peripheral device or NAC is back to normal operation" },
{ "OZ", "Point Opening",
"A point, rather than a full area or account, disarmed" },
{ "PA", "Panic Alarm",
"Panic emergency assistance request, manually activated" },
{ "PB", "Panic Bypass",
"Panic zone has been bypassed" },
{ "PH", "Panic Alarm Restore",
"Panic alarm condition eliminated" },
{ "PJ", "Panic Trouble Restore",
"Panic trouble condition eliminated" },
{ "PR", "Panic Restoral",
"Panic alarm/trouble condition eliminated" },
{ "PS", "Panic Supervisory",
"Unsafe panic system condition exists" },
{ "PT", "Panic Trouble",
"Panic zone disabled by fault" },
{ "PU", "Panic Unbypass",
"Panic zone bypass has been removed" },
{ "QA", "Emergency Alarm",
"Emergency assistance request" },
{ "QB", "Emergency Bypass",
"Emergency zone has been bypassed" },
{ "QH", "Emergency Alarm Restore",
"Emergency alarm condition eliminated" },
{ "QJ", "Emergency Trouble Restore",
"Emergency trouble condition eliminated" },
{ "QR", "Emergency Restoral",
"Emergency alarm/trouble condition eliminated" },
{ "QS", "Emergency Supervisory",
"Unsafe emergency system condition exists" },
{ "QT", "Emergency Trouble",
"Emergency zone disabled by fault" },
{ "QU", "Panic Unbypass",
"Emergency zone bypass has been removed" },
{ "RA", "Remote Programmer Call Failed",
"Transmitter failed to communicate with the remote programmer" },
{ "RB", "Remote Program Begin",
"Remote programming session initiated " },
{ "RC", "Relay Close",
"A relay has energized" },
{ "RD", "Remote Program Denied",
"Remote Program access passcode incorrect" },
{ "RN", "Remote Reset",
"A TRANSMITTER was reset via a remote programmer" },
{ "RP", "Automatic Test",
"Automatic communication test report" },
{ "RR", "Power Up",
"System lost power, is now restored" },
{ "RS", "Remote Program Success",
"Remote programming successful" },
{ "RT", "Data Lost",
"Dialer data lost, transmission error" },
{ "RU", "Remote Program Fail",
"Remote programming unsuccessful" },
{ "RX", "Manual Test",
"Manual communication test report" },
{ "RY", "Test Off Normal",
"Test signal(s) indicates abnormal condition(s) exist" },
{ "SA", "Sprinkler Alarm",
"Sprinkler flow condition exists" },
{ "SB", "Sprinkler Bypass",
"Sprinkler zone has been bypassed" },
{ "SC", "Change of State",
"An expansion/peripheral device is reporting a new condition or state change" },
{ "SH", "Sprinkler Alarm Restore",
"Sprinkler alarm condition eliminated" },
{ "SJ", "Sprinkler Trouble Restore",
"Sprinkler trouble condition eliminated" },
{ "SR", "Sprinkler Restoral",
"Sprinkler alarm/trouble condition eliminated" },
{ "SS", "Sprinkler Supervisory",
"Unsafe sprinkler system condition exists" },
{ "ST", "Sprinkler Trouble",
"Sprinkler zone disabled by fault" },
{ "SU", "Sprinkler Unbypass",
"Sprinkler zone bypass has been removed" },
{ "TA", "Tamper Alarm",
"Alarm equipment enclosure opened" },
{ "TB", "Tamper Bypass",
"Tamper detection has been bypassed" },
{ "TC", "All Points Tested",
"All points tested" },
{ "TE", "Test End",
"Communicator restored to operation" },
{ "TH", "Tamper Alarm Restore",
"An Expansion Devices tamper switch restores to normal from an Alarm state" },
{ "TJ", "Tamper Trouble Restore",
"An Expansion Devices tamper switch restores to normal from a Trouble state" },
{ "TP", "Walk Test Point",
"This point was tested during a Walk Test" },
{ "TR", "Tamper Restoral",
"Alarm equipment enclosure has been closed" },
{ "TS", "Test Start",
"Communicator taken out of operation" },
{ "TT", "Tamper trouble",
"Equipment enclosure opened in disarmed state" },
{ "TU", "Tamper Unbypass",
"Tamper detection bypass has been removed" },
{ "TW", "Area Watch Start",
"Area watch feature has been activated" },
{ "TX", "Test Report",
"An unspecified (manual or automatic) communicator test" },
{ "TZ", "Area Watch End",
"Area watch feature has been deactivated" },
{ "UA", "Untyped Zone Alarm",
"Untyped zone has been violated while armed" },
{ "UB", "Untyped Zone Bypass",
"Untyped zone has been bypassed" },
{ "UG", "Unverified Event - Untyped",
"A point assigned to a Cross Point group has gone into alarm but the Cross Point remained normal" },
{ "UH", "Untyped Zone Alarm Restore",
"Untyped Alarm condition eliminated" },
{ "UJ", "Untyped Zone Trouble restore",
"Untyped Trouble condition eliminated" },
{ "UM", "Untyped ZoneAlarm cross point",
"Untyped alarm w/cross point also in alarm - alarm verified" },
{ "UR", "Untyped Zone Restore",
"Untyped Alarm/trouble condition has been eliminated" },
{ "US", "Untyped Zone Supervisory",
"Unsafe untyped zone system condition" },
{ "UT", "Untyped Zone Trouble",
"Untyped zone disabled by fault" },
{ "UU", "Untyped Zone Unbypass",
"Untyped zone bypass has been removed" },
{ "UX", "Undefined",
"An undefined alarm condition has occurred" },
{ "UY", "Untyped Missing Trouble",
"A point or device which was not armed is now logically missing" },
{ "UZ", "Untyped Missing Alarm",
"A point or device which was armed is now logically missing" },
{ "VI", "Printer Paper In",
"TRANSMITTER or RECEIVER paper in" },
{ "VO", "Printer Paper Out",
"TRANSMITTER or RECEIVER paper out" },
{ "VR", "Printer Restore",
"TRANSMITTER or RECEIVER trouble restored" },
{ "VT", "Printer Trouble",
"TRANSMITTER or RECEIVER trouble" },
{ "VX", "Printer Test",
"TRANSMITTER or RECEIVER test" },
{ "VY", "Printer Online",
"RECEIVERS printer is now online" },
{ "VZ", "Printer Offline",
"RECEIVERS printer is now offline" },
{ "WA", "Water Alarm",
"Water detected at protected premises" },
{ "WB", "Water Bypass",
"Water detection has been bypassed" },
{ "WH", "Water Alarm Restore",
"Water alarm condition eliminated" },
{ "WJ", "Water Trouble Restore",
"Water trouble condition eliminated" },
{ "WR", "Water Restoral",
"Water alarm/trouble condition has been eliminated" },
{ "WS", "Water Supervisory",
"Water unsafe water detection system condition" },
{ "WT", "Water Trouble",
"Water zone disabled by fault" },
{ "WU", "Water Unbypass",
"Water detection bypass has been removed" },
{ "XA", "Extra Account Report",
"CS RECEIVER has received an event from a non-existent account" },
{ "XE", "Extra Point",
"Panel has sensed an extra point not specified for this site" },
{ "XF", "Extra RF Point",
"Panel has sensed an extra RF point not specified for this site" },
{ "XH", "RF Interference Restoral",
"A radio device is no longer detecting RF Interference" },
{ "XI", "Sensor Reset",
"A user has reset a sensor" },
{ "XJ", "RF Receiver Tamper Restoral",
"A Tamper condition at a premises RF Receiver has been restored" },
{ "XL", "Low Received Signal Strength",
"The RF signal strength of a reported event is below minimum level" },
{ "XM", "Missing Alarm - Cross point",
"Missing Alarm verified by Cross Point in Alarm (or missing)" },
{ "XQ", "RF Interference",
"A radio device is detecting RF Interference" },
{ "XR", "Transmitter Battery Restoral",
"Low battery has been corrected" },
{ "XS", "RF Receiver Tamper",
"A Tamper condition at a premises receiver is detected" },
{ "XT", "Transmitter Battery Trouble",
"Low battery in wireless transmitter" },
{ "XW", "Forced Point",
"A point was forced out of the system at arm time" },
{ "XX", "Fail to Test",
"A specific test from a panel was not received" },
{ "YA", "Bell Fault",
"A trouble condition has been detected on a Local Bell, Siren, or Annunciator" },
{ "YB", "Busy Seconds",
"Percent of time receiver's line card is on-line" },
{ "YC", "Communications Fail",
"RECEIVER and TRANSMITTER communicatie failure" },
{ "YD", "Receiver Line Card Trouble",
"A line card identified by the passed address is in trouble" },
{ "YE", "Receiver Line Card Restored",
"A line card identified by the passed address is restored" },
{ "YF", "Parameter Checksum Fail",
"System data corrupted" },
{ "YG", "Parameter Changed",
"A TRANSMITTERS parameters have been changed" },
{ "YH", "Bell Restored",
"A trouble condition has been restored on a Local Bell, Siren, or Annunciator" },
{ "YI", "Overcurrent Trouble",
"An Expansion Device has detected an overcurrent condition" },
{ "YJ", "Overcurrent Restore",
"An Expansion Device has restored from an overcurrent condition" },
{ "YK", "Communications Restoral",
"TRANSMITTER has resumed communication with a RECEIVER" },
{ "YM", "System Battery Missing",
"TRANSMITTER/RECEIVER battery is missing" },
{ "YN", "Invalid Report",
"TRANSMITTER has sent a packet with invalid data" },
{ "YO", "Unknown Message",
"An unknown message was received from automation or the printer" },
{ "YP", "Power Supply Trouble",
"TRANSMITTER/RECEIVER has a problem with the power supply" },
{ "YQ", "Power Supply Restored",
"TRANSMITTER'S/RECEIVERS'S power supply has been restored" },
{ "YR", "System Battery Restoral",
"Low battery has been corrected" },
{ "YS", "Communications Trouble",
"RECEIVER and TRANSMITTER fail to communicate" },
{ "YT", "System Battery Trouble",
"Low battery in control/communicator" },
{ "YU", "Diagnostic Error",
"An expansion/peripheral device is reporting a diagnostic error" },
{ "YW", "Watchdoc Reset",
"The TRANSMITTER created an internal reset" },
{ "YX", "Service Required",
"A TRANSMITTER/RECEIVER needs service" },
{ "YY", "Status Report",
"Account status report transmission" },
{ "YZ", "Service Completed",
"Required TRANSMITTER / RECEIVER service completed" },
{ "ZA", "Freeze Alarm",
"Freeze emergency assistance request, manually activated" },
{ "ZB", "Freeze Bypass",
"Freeze zone has been bypassed" },
{ "ZH", "Freeze Alarm Restore",
"Freeze alarm condition eliminated" },
{ "ZJ", "Freeze Trouble Restore",
"Freeze trouble condition eliminated" },
{ "ZR", "Freeze Restoral",
"Freeze alarm/trouble condition eliminated" },
{ "ZS", "Freeze Supervisory",
"Unsafe freeze system condition exists" },
{ "ZT", "Freeze Trouble",
"Freeze zone disabled by fault" },
{ "ZU", "Freeze Unbypass",
"Freeze zone bypass has been removed" },
{ NULL, NULL, NULL },
};
const char *sia_code_str(char *code) {
uint16_t i;
for (i = 0; sia_codes[i].code != NULL; i++) {
if (strncmp(code, sia_codes[i].code, 2) != 0) {
continue;
}
return sia_codes[i].string;
}
return NULL;
}
const char *sia_code_desc(char *code) {
uint16_t i;
for (i = 0; sia_codes[i].code != NULL; i++) {
if (strncmp(code, sia_codes[i].code, 2) != 0) {
continue;
}
return sia_codes[i].description;
}
return NULL;
}

3
sia.h Normal file
View file

@ -0,0 +1,3 @@
const char *sia_code_str(char *code);
const char *sia_code_desc(char *code);

18
siahs.h Normal file
View file

@ -0,0 +1,18 @@
struct packet {
uint32_t len;
char unknown1; /* 0x01 */
char unknown2; /* 0x01 */
uint16_t unknown3; /* '0xcfff' big endian */
/* From this point XOR encoded with either 0xB6 or 0x85 */
char *device;
uint16_t prom;
uint8_t unknown4; /* 0x01 */
uint8_t unknown5; /* 0x2C */
uint8_t unknown6; /* 0x01 */
char *message;
uint16_t checksum;
};

219
siahsd.c Normal file
View file

@ -0,0 +1,219 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <talloc.h>
#include "siahs.h"
#include "sia.h"
#define MY_DEVICE "RCIPv2.4"
/* TODO:
* - Make a load balancer that balances REGISTRATION REQUESTS to the proper port
* - Actually do something with the messages: Add to database, keep state, etc
*/
void parse_message(TALLOC_CTX *mem_ctx, struct packet *pkt) {
char *message = talloc_strdup(mem_ctx, pkt->message + strlen("MESSAGE "));
char *ptr = message;
char *prom = ptr;
char *code;
/* Grab the first part, the prom */
while (*ptr != '\0' && *ptr != 'N') {
ptr++;
}
*ptr++ = '\0';
/* Grab the second part, SIA code */
code = ptr;
while (*ptr != '\0' && *ptr != ',') {
ptr++;
}
if (*ptr != '\0') *ptr++ = '\0';
/* The remaining ptr contains the information string */
/* Ignore alive! messages */
if (strcmp(code, "alive!") == 0) {
return;
}
printf("%s %s %s -- %s: %s\n", prom, code, ptr, sia_code_str(code), sia_code_desc(code));
talloc_free(message);
}
void send_reply(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct packet *pkt, const char *string) {
int n;
uint8_t *reply;
int i;
uint16_t sum = 0;
uint32_t reply_len;
reply_len = strlen(string) + 36;
reply = talloc_zero_array(mem_ctx, uint8_t, reply_len);
if (reply == NULL) return;
/* Store the length as network ordered uint32_t */
*(uint32_t *)&reply[0] = htonl(reply_len - 4);
/* No clue what these are */
reply[4] = 0x01;
reply[5] = 0x01;
reply[6] = 0x80;
reply[7] = 0x80;
/* Add the device description */
memcpy(&reply[8], MY_DEVICE, strlen(MY_DEVICE));
/* Add the PROM code */
*(uint16_t *)&reply[21] = htons(pkt->prom);
/* No clue what these are */
reply[24] = 0x1E;
reply[25] = 0x03;
reply[26] = 0x84; /* Maybe unencoded 0x01? */
reply[27] = 0x03;
/* Add the message */
memcpy(&reply[34], string, strlen(string));
/* Encode with XOR 0x85 and calculate checksum */
for (i = 0; i < reply_len - 2; i++) {
if (i >= 8)
reply[i] ^= 0x85;
sum += reply[i];
}
/* Store the checksum */
*(uint16_t *)&reply[reply_len - 2] = htons(sum);
printf("Sending %s sum %04x len %d\n", string, sum, reply_len - 4);
n = sendto(sock, reply, reply_len, 0, (struct sockaddr *)&from, sizeof(from));
/* Cleanup */
talloc_free(reply);
}
int main(int argc, char **argv) {
int sock, n, i;
socklen_t fromlen;
struct sockaddr_in server;
struct sockaddr_in from;
TALLOC_CTX *mem_ctx;
/* Initialize a memory context */
mem_ctx = talloc_init("siahsd");
/*
* Open up a UDP socket on port 4000
*/
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
printf("Can not create socket in server\n");
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(4000);
server.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
printf("Can not bind to socket!\n");
exit(1);
}
/*
* Wait for packets
*/
fromlen = sizeof(struct sockaddr_in);
while (1) {
uint16_t src_port;
struct packet *pkt;
uint8_t *decoded;
char buf[1024]; /* Purposefully static length */
pkt = talloc_zero(mem_ctx, struct packet);
n = recvfrom(sock, &buf, sizeof(buf), 0, (struct sockaddr *) &from, &fromlen);
if (n < 0) {
printf("Error when receiving in server!\n");
talloc_free(pkt);
continue;
} else if (n == sizeof(buf)) {
printf("Maximum packet size exceeded!\n");
talloc_free(pkt);
continue;
}
src_port = ntohs(from.sin_port);
pkt->len = ntohl(*(uint32_t *)buf);
if (pkt->len > n-4) {
printf("Message length is longer than the packet (not possible!)\n");
talloc_free(pkt);
continue;
}
pkt->unknown1 = buf[4];
pkt->unknown2 = buf[5];
pkt->unknown3 = ntohs(*(uint16_t *)&buf[5]);
decoded = talloc_memdup(pkt, &buf[8], pkt->len - 6);
/* Decode with XOR 0xB6 */
for (i = 0;i < pkt->len - 6; i++) {
decoded[i] ^= 0xB6;
}
pkt->device = talloc_strndup(pkt, (char *)decoded, 12);
pkt->prom = ntohs(*(uint16_t *)&decoded[13]);
pkt->unknown4 = decoded[16];
pkt->unknown5 = decoded[17];
pkt->unknown6 = decoded[18];
pkt->message = talloc_strndup(pkt, (char *) &decoded[26], pkt->len-32);
printf("I have received device %s prom %x, message %s, from IP %s and port %u \n", pkt->device, pkt->prom, pkt->message, inet_ntoa(from.sin_addr), src_port);
/* Handle registrations, reconnects and messages */
if (strcmp(pkt->message, "REGISTRATION REQUEST") == 0) {
send_reply(pkt, sock, from, pkt, "REGISTRATION RENEWAL AT PORT 04000");
} else if (strcmp(pkt->message, "RECONNECT REQUEST") == 0) {
send_reply(pkt, sock, from, pkt, "RECONNECTED AT PORT 04000");
} else if (strncmp(pkt->message, "MESSAGE ", strlen("MESSAGE ")) == 0) {
send_reply(pkt, sock, from, pkt, "ACKNOWLEDGE MESSAGE");
parse_message(pkt, pkt);
} else {
printf("==============================================\n"
"ERROR: Could not parse this message\n"
"==============================================\n");
}
/* Clean up everything that's been attached to this packet */
talloc_free(pkt);
}
}

6
tryouts/Makefile Normal file
View file

@ -0,0 +1,6 @@
CFLAGS=-ggdb -g -Wall
all: crc_validate
clean:
rm -f *.o crc_validate

183
tryouts/crc_validate.c Normal file
View file

@ -0,0 +1,183 @@
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "packets.h"
char *bin(uint16_t x)
{
char *b = malloc(17);
b[0] = '\0';
uint16_t z;
for (z = 1 << 15; z > 0; z >>= 1) {
strcat(b, (x & z) ? "1" : "0");
}
return b;
}
void create_packet_array(const uint8_t *packets[2][40])
{
packets[0][0] = peer0_0;
packets[0][1] = peer0_1;
packets[0][2] = peer0_2;
packets[0][3] = peer0_3;
packets[0][4] = peer0_4;
packets[0][5] = peer0_5;
packets[0][6] = peer0_6;
packets[0][7] = peer0_7;
packets[0][8] = peer0_8;
packets[0][9] = peer0_9;
packets[0][10] = peer0_10;
packets[0][11] = peer0_11;
packets[0][12] = peer0_12;
packets[0][13] = peer0_13;
packets[0][14] = peer0_14;
packets[0][15] = peer0_15;
packets[0][16] = peer0_16;
packets[0][17] = peer0_17;
packets[0][18] = peer0_18;
packets[0][19] = peer0_19;
packets[0][20] = peer0_20;
packets[0][21] = peer0_21;
packets[0][22] = peer0_22;
packets[0][23] = peer0_23;
packets[0][24] = peer0_24;
packets[0][25] = peer0_25;
packets[0][26] = peer0_26;
packets[0][27] = peer0_27;
packets[0][28] = peer0_28;
packets[0][29] = peer0_29;
packets[0][30] = peer0_30;
packets[0][31] = peer0_31;
packets[0][32] = peer0_32;
packets[0][33] = peer0_33;
packets[0][34] = peer0_34;
packets[0][35] = peer0_35;
packets[0][36] = peer0_36;
packets[0][37] = peer0_37;
packets[0][38] = peer0_38;
packets[0][39] = peer0_39;
packets[1][0] = peer1_0;
packets[1][1] = peer1_1;
packets[1][2] = peer1_2;
packets[1][3] = peer1_3;
packets[1][4] = peer1_4;
packets[1][5] = peer1_5;
packets[1][6] = peer1_6;
packets[1][7] = peer1_7;
packets[1][8] = peer1_8;
packets[1][9] = peer1_9;
packets[1][10] = peer1_10;
packets[1][11] = peer1_11;
packets[1][12] = peer1_12;
packets[1][13] = peer1_13;
packets[1][14] = peer1_14;
packets[1][15] = peer1_15;
packets[1][16] = peer1_16;
packets[1][17] = peer1_17;
packets[1][18] = peer1_18;
packets[1][19] = peer1_19;
packets[1][20] = peer1_20;
packets[1][21] = peer1_21;
packets[1][22] = peer1_22;
packets[1][23] = peer1_23;
packets[1][24] = peer1_24;
packets[1][25] = peer1_25;
packets[1][26] = peer1_26;
packets[1][27] = peer1_27;
packets[1][28] = peer1_28;
packets[1][29] = peer1_29;
packets[1][30] = peer1_30;
packets[1][31] = peer1_31;
packets[1][32] = peer1_32;
packets[1][33] = peer1_33;
packets[1][34] = peer1_34;
packets[1][35] = peer1_35;
packets[1][36] = peer1_36;
packets[1][37] = peer1_37;
packets[1][38] = peer1_38;
packets[1][39] = peer1_39;
}
#define POLYNOMIAL 0x3FF0
#define WIDTH (16)
#define TOPBIT (1 << (WIDTH - 1))
uint16_t
crcSlow(uint8_t const message[], int nBytes)
{
uint16_t remainder = 0x10d0;
int byte;
uint8_t bit;
for (byte = 0; byte < nBytes; ++byte) {
remainder ^= message[byte];
for (bit = 0; bit < 8; bit++) {
if (remainder & 1) {
remainder = ((remainder >> 1) ^ POLYNOMIAL);
} else {
remainder = (remainder >> 1);
}
}
}
return (remainder);
} /* crcSlow() */
int main (int argc, char **argv)
{
int i,j;
const uint8_t *pkts[2][40];
uint8_t decode_xor;
create_packet_array(pkts);
for (j = 0; j < 40; j++) {
for (i = 0; i < 2; i++) {
if (i == 0)
decode_xor = 0xB6;
else
decode_xor = 0x85;
uint32_t len = ntohl(*(uint32_t*) pkts[i][j]);
uint8_t decoded[len - 5];
uint16_t crc, calc_crc, nondecoded_crc;
uint32_t k;
uint16_t sum = 0;
len = ntohl(*(uint32_t*) pkts[i][j]);
decoded[sizeof(decoded)-1] = '\0';
for (k = 0; k < len-6; k++) {
decoded[k] = pkts[i][j][k + 8] ^ decode_xor;
}
printf("%s\n", decoded+26);
for (k = 0; k < len+2; k++) {
sum += pkts[i][j][k];
}
crc = ntohs(*(uint16_t*)&decoded[len - 6]);
calc_crc = crcSlow(decoded, len - 6);
nondecoded_crc = ntohs(*(uint16_t*)&pkts[i][j][len+2]);
printf("%04x %04x peer %d len %x\n",
nondecoded_crc, sum, i, len);
}
}
return 0;
}

1360
tryouts/packets.h Normal file

File diff suppressed because it is too large Load diff

BIN
tryouts/sia.pcap Normal file

Binary file not shown.