#!/usr/bin/perl use strict; use warnings; use DBI; use Encode; use Net::SIP; use Net::SIP::Util qw(sip_hdrval2parts sip_uri2parts); my $addr = $ARGV[0]; my $port = $ARGV[1]; my $dbfile = $ARGV[2]; die "Usage: $0 listen_address listen_port database_file\n" unless $addr and $port and $dbfile; my $dbh = DBI->connect("DBI:SQLite:$dbfile", undef, undef, { PrintError => 0, RaiseError => 1, sqlite_unicode => 1 }); my $leg = Net::SIP::Leg->new(proto => 'udp', addr => $addr, port => $port) or die "Error: Cannot create leg: $!\n"; my $ua = Net::SIP::Simple->new(from => '', leg => $leg) or die "Error: Cannot create user agent: $!\n"; $dbh->do('CREATE TABLE IF NOT EXISTS messages(id INTEGER PRIMARY KEY AUTOINCREMENT, r INT NOT NULL DEFAULT 0, f TEXT NOT NULL, t TEXT NOT NULL, m TEXT NOT NULL)'); $dbh->do('CREATE INDEX IF NOT EXISTS idx ON messages(r, t)'); $ua->{endpoint}->set_application(sub { my ($endpoint, $ctx, $packet, $leg, $from_addr) = @_; return unless $packet->is_request; my $resp; if ($packet->method eq 'MESSAGE') { my (undef, $for, undef, $message) = $packet->as_parts; $message = decode('UTF-8', $message); my $for_user = (sip_uri2parts($for))[1]; my ($from) = $packet->get_header('from'); ($from) = sip_hdrval2parts(from => $from); print "Recevied message for user $for_user from uri: $from\n"; my $success = eval { $dbh->do('INSERT INTO messages(f, t, m) VALUES(?, ?, ?)', undef, $from, $for_user, $message) }; if ($success) { $resp = $packet->create_response('200', 'OK'); } else { $resp = $packet->create_response('500', $dbh->errstr); } } elsif ($packet->method eq 'OPTIONS') { $resp = $packet->create_response('200', 'OK'); } else { $resp = $packet->create_response('606', 'Not Acceptable'); } $resp->set_header('Allow' => 'OPTIONS, MESSAGE'); $endpoint->new_response($ctx, $resp, $leg, $from_addr); $endpoint->close_context($ctx); }); $ua->loop();