Skip to content

Instantly share code, notes, and snippets.

@ravnx
Created September 23, 2024 16:38
Show Gist options
  • Select an option

  • Save ravnx/bc3b4572cf4c7836cf2899b0d86e7e07 to your computer and use it in GitHub Desktop.

Select an option

Save ravnx/bc3b4572cf4c7836cf2899b0d86e7e07 to your computer and use it in GitHub Desktop.
Parse PJSIP channels, looking for calls over an hour, alert the admin, cancel some conference bridged Sangoma app calls
#!/usr/bin/perl -w
# This script will run and parse the command pjsip show channels and check for stale calls that are more than an hour old
# and print to the console the channel number and the time the call has been up for, this is mostly a fix for Sangoma App,
# which has a bug when "bridging" a call, since there is no attended transfer, the call will stay up forever if the conference
# bug hits. Hopefully sangoma will fix this, but for now, to save money on long distance calls, we'll just hang up the call if it
# meets criteria. This script will also email the admin if a call is found to be stale, and not ignored. The script will also
# disconnect a conference call. We had a customer mostly conferencing in a CC processor, so we match on the route being specific to
# the conference bridge, that way we can auto cancel it. Otherwise we'll just alert the admin.
use strict;
use MIME::Lite;
# Email settings
my $emailFrom = '"PBX Admin" <[email protected]>';
my $emailTo = '[email protected]';
# Get the list of channels
my @list = `/usr/sbin/asterisk -rx 'pjsip show channels'`;
# Init the report hash.
my $report;
# Debug level, 0 = no output, 1 = output
my $debug = $ARGV[0] || 0;
# If 0, dont email, set to 1 later if long call exists, this flag gets flagged if we find a long call
my $email = 0;
# init the html string for output
my $html;
$html .= "Checking for stale calls.\n\n";
for my $l (@list) {
next if ($l !~ /PJSIP/);
# Channel string is Channel: PJSIP/9137-0000cf8c/AppDial Up 00:01:04
# we want to match the channel number between the / characters
my ($channel) = $l =~ /(PJSIP\/[\w-]+)\//;
# We want to match the time the call has been up for
my ($time) = $l =~ /\b(\d+:\d+:\d+)/;
$report->{$channel}->{time} = $time;
}
my $count = 0;
for my $c (keys %$report) {
my $time = $report->{$c}->{time};
my ($hour) = $time =~ /(\d+):\d+:\d+/;
if ($hour > 0) {
$html .= "\n\t** ==> Channel $c has been up for $time! [ channel request hangup $c ]\n\n";
$email = 1;
my ($cid,$out) = GetCallerID($c);
if ($c =~ m/pbx-out-IVR-dtmf/) {
$html .= "Channel is detected to be a stale DTMF call, taking matters into our own hands and hanging it up";
system "/usr/sbin/asterisk -rx 'channel request hangup $c'";
}
# CID and OUT are flipped, since the call will show as both legs. We'll just search for both.
# in the future, need to add logic, for example, if the inbound is an 800 number and the outbound is long distance,
# it would get ignored here. This could happen if someone called in from an 800, and forwarded the call, or if someone
# has their caller ID set to an 800 number.
if ($cid =~ /866|855|844|833|800|888|877/) {
# This is a toll free number, we should ignore it
$email = 0;
}
if ($out =~ /\^866|\^855|\^844|\^833|\^800|\^888|\^877/) {
# This is a toll free number, we should ignore it
$email = 0;
}
}
else {
$html .= "Channel $c has been up for $time\n";
}
$count++;
}
$html .= "\nCall count: $count\n";
print $html if $debug > 0;
if ($email > 0) {
my $msg = MIME::Lite->new(
From => $emailFrom,
To => $emailTo,
Subject => "Channels existing",
Type => 'text/html',
Data => $html,
);
$msg->send('smtp','localhost', Debug=>0 );
}
# ---------------------------------------------------------------------- #
# Get Caller ID for a channel #
# ---------------------------------------------------------------------- #
sub GetCallerID {
my $channel = shift;
my $channelline = `/usr/sbin/asterisk -rx 'core show channels concise' | grep $channel`;
chomp($channelline);
my @chandetails = split(/\!/, $channelline);
my $cid = $chandetails[7];
my $out = $chandetails[6];
return $cid,$out;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment