[ helper("../crc16.h") ] interface secip { typedef [public,enum8bit] enum { SECIP_ERR_SUCCESS = 0x00, SECIP_ERR_ACKNOWLEDGE = 0x01, SECIP_ERR_NEGATIVE_ACKNOWLEDGE = 0x02, SECIP_ERR_ARC_COULD_NOT_PROCESS_MESSAGE = 0x03, SECIP_ERR_PROTOCOL_ID_NOT_SUPPORTED = 0x04, SECIP_ERR_PROTOCOL_VERSION_NOT_SUPPORTED = 0x05, SECIP_ERR_PPK_BLOCK_VERSION_NOT_SUPPORTED = 0x06, SECIP_ERR_CRC_MODE_NOT_SUPPORTED = 0x07, SECIP_ERR_ACCOUNT_CODE_NOT_ALLOWED = 0x08, SECIP_ERR_CONNECTION_NOT_ALLOWED = 0x0D, SECIP_ERR_SUPERVISION_NOT_SUPPORTED = 0x09, SECIP_ERR_SUPERVISION_REQUEST_TOO_FAST = 0x0A, SECIP_ERR_SUPERVISION_REQUEST_TOO_SLOW = 0x0B, SECIP_ERR_PATHCHECK_NOT_SUPPORTED = 0x0C, SECIP_ERR_REESTABLISH_CONNECTION = 0x80, SECIP_ERR_UNKNOWN_ERROR = 0xFF } secip_error; typedef [public,enum8bit] enum { SECIP_MSG_ATE_ENC = 0x01, SECIP_MSG_ARC_ENC = 0x81, SECIP_MSG_PPK_COM = 0x02, SECIP_MSG_PPK_REP = 0x82, SECIP_MSG_PATH_SUPERVISION_REQUEST = 0x10, SECIP_MSG_PATH_SUPERVISION_RESPONSE = 0x90, SECIP_MSG_PATH_CHECK_REQUEST = 0x20, SECIP_MSG_PATH_CHECK_RESPONSE = 0xA0, SECIP_MSG_POLL_MESSAGE = 0x11, SECIP_MSG_POLL_ACKNOWLEDGE = 0x91, SECIP_MSG_ALARM = 0x30, SECIP_MSG_ALARM_ACKNOWLEDGE = 0xB0 } secip_message; typedef [public,enum8bit] enum { SECIP_PROTO_SIA = 0x01, SECIP_PROTO_CONTACTID = 0x02, SECIP_PROTO_SCANCOM = 0x03, SECIP_PROTO_SIAHS = 0x04 } secip_protocol; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { [value(0)] uint16 session_id; uint8 padding[202]; } secip_ate_enc; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { [value(0)] uint16 session_id; uint8 rsa_key[128]; uint8 padding[74]; } secip_ppk_com; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { [value(1)] uint8 version; uint8 aes_key[16]; } secip_key_message_block; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { [value(1)] uint8 protocol_version; uint8 manufacturer[20]; uint8 panel_type[12]; uint8 panel_version[8]; uint8 account_code[6]; uint8 crc_mode; uint16 session_id; secip_key_message_block key_block; uint8 padding[136]; } secip_ppk_rep; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { secip_error error_code; uint16 session_id; uint8 padding[231]; } secip_arc_enc; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { uint16 path_id; uint32 interval_seconds; uint8 padding[70]; } secip_psup_req; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { secip_error error_code; uint16 path_id; uint32 interval_seconds; uint8 padding[69]; } secip_psup_resp; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { uint8 padding[76]; } secip_pathcheck_req; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { secip_error error_code; uint8 path_check_id; uint8 padding[74]; } secip_pathcheck_resp; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { secip_protocol protocol_identifier; [range(0,97)] uint8 length; int8 message[length]; } secip_alarm; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { secip_error error_code; uint8 padding[75]; } secip_alarm_ack; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { uint16 path_check_id; uint8 padding[74]; } secip_poll_message; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { secip_error error_code; uint16 path_check_id; uint8 padding[73]; } secip_poll_ack; typedef [nodiscriminant,public,flag(LIBNDR_FLAG_NOALIGN)] union { [case(SECIP_MSG_ATE_ENC)] secip_ate_enc ate_enc; [case(SECIP_MSG_PPK_COM)] secip_ppk_com ppk_com; [case(SECIP_MSG_PPK_REP)] secip_ppk_rep ppk_rep; [case(SECIP_MSG_ARC_ENC)] secip_arc_enc arc_enc; [case(SECIP_MSG_PATH_SUPERVISION_REQUEST)] secip_psup_req psup_req; [case(SECIP_MSG_PATH_SUPERVISION_RESPONSE)] secip_psup_resp psup_resp; [case(SECIP_MSG_PATH_CHECK_REQUEST)] secip_pathcheck_req pathcheck_req; [case(SECIP_MSG_PATH_CHECK_RESPONSE)] secip_pathcheck_resp pathcheck_resp; [case(SECIP_MSG_ALARM)] secip_alarm alarm; [case(SECIP_MSG_ALARM_ACKNOWLEDGE)] secip_alarm_ack alarm_ack; [case(SECIP_MSG_POLL_MESSAGE)] secip_poll_message poll_message; [case(SECIP_MSG_POLL_ACKNOWLEDGE)] secip_poll_ack poll_ack; } secip_msg_union; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { uint16 connection_id; /* 0xffff is unassigned */ uint8 pad; /* This is a fix for a broken spec. This is necessary because there is no secure cryptographic padding and you can't encrypt a 128-byte block with a 1024-bit public key. */ secip_message message_id; uint16 sequence_number; char device_id[16]; [switch_is(message_id)] secip_msg_union msg; } secip_packet; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { uint8 raw_packet[226]; uint8 padding[30]; [value(calculate_crc(raw_packet, 256))] uint16 crc; } secip_setup_packet; typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { uint8 raw_packet[98]; uint8 padding[30]; [value(calculate_crc(raw_packet, 128))] uint16 crc; } secip_comm_packet; };