Skip to content

Instantly share code, notes, and snippets.

@eriknylund
Forked from 667bdrm/dvr-alarm-server.pl
Last active April 14, 2017 10:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eriknylund/16c1a3bceaed4c43252ab4b36332ef86 to your computer and use it in GitHub Desktop.
Save eriknylund/16c1a3bceaed4c43252ab4b36332ef86 to your computer and use it in GitHub Desktop.
Chinese DVR Alarm Server
#!/usr/bin/perl
# Simple log/alarm server receiving and printing to console remote dvr/camera events.
# Output is in CSV format.
#
# Tested with:
#
# HandyKam DigiMiniCam HD camera HK101182
# http://www.handykam.com/Cameras-only/DigiMinicam-HD-camera/flypage.tpl.html
#
# Usage: perl dvr-alarm-server.pl | tee -a cam.csv
use IO::Socket;
use IO::Socket::INET;
use Sys::Syslog;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Sys::Syslog qw(:standard :macros);
use Time::Local;
use JSON;
use Data::Dumper;
setlogsock("console");
openlog("dvr-alarm-server", "cons,pid", LOG_USER);
sub BuildPacket {
my ($type, $params) = ($_[0], $_[1]);
my @pkt_prefix_1;
my @pkt_prefix_2;
my @pkt_type;
my $sid = 0;
my $json = JSON->new;
@pkt_prefix_1 = (0xff, 0x00, 0x00, 0x00);
@pkt_prefix_2 = (0x00, 0x00, 0x00, 0x00);
if ($type eq 'login') {
@pkt_type = (0x00, 0x00, 0xe8, 0x03);
} elsif ($type eq 'info') {
@pkt_type = (0x00, 0x00, 0xfc, 0x03);
}
$sid = hex($params->{'SessionID'});
my $pkt_prefix_data = pack('c*', @pkt_prefix_1) . pack('i', $sid) . pack('c*', @pkt_prefix_2). pack('c*', @pkt_type);
my $pkt_params_data = $json->encode($params);
my $pkt_data = $pkt_prefix_data . pack('i', length($pkt_params_data)) . $pkt_params_data;
return $pkt_data;
}
sub GetReplyHead {
my $sock = $_[0];
my @reply_head_array;
for (my $i = 0; $i < 5; $i++) {
$sock->recv($data, 4);
$reply_head[$i] = unpack('i', $data);
print OUT $data;
}
my $reply_head = {
Prefix1 => $reply_head[0],
Prefix2 => $reply_head[1],
Prefix3 => $reply_head[2],
Prefix4 => $reply_head[3],
Content_Length => $reply_head[4]
};
return $reply_head;
}
my $sock = new IO::Socket::INET(
LocalHost => '0.0.0.0',
LocalPort => '15002',
Proto => 'tcp',
Listen => 1,
Reuse => 1);
die "Could not create socket: $!\n" unless $sock;
while (my ($client,$clientaddr) = $sock->accept()) {
write_log("Connected from ".$client->peerhost());
$pid = fork();
die "Cannot fork: $!" unless defined($pid);
if ($pid == 0) {
# Child process
my $data = '';
my $reply = GetReplyHead($client);
# Client protocol detection
$client->recv($data, $reply->{'Content_Length'});
# Format CSV data
# timestamp, address, channel, serialid, event, starttime, status, type
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time());
my $timestamp = sprintf("%4d-%02d-%02d %02d:%02d:%02d",$year+1900,$mday,$mon+1,$hour,$min,$sec);
my $json = decode_json($data);
print "$timestamp,$json->{Address},$json->{Channel},$json->{SerialID},$json->{Event},$json->{StartTime},$json->{Status},$json->{Type}\n";
exit(0); # Child process exits when it is done.
}
}
close($sock);
sub write_log() {
#my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time());
#my $timestamp = sprintf("%02d.%02d.%4d %02d:%02d:%02d",$mday,$mon+1,$year+1900,$hour,$min,$sec);
#print "$timestamp dvr-alarm-server[] " . $_[0] ."\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment