From 1c682a9fc77094133fced8dccb0f758b83bfd8bd Mon Sep 17 00:00:00 2001 From: mattf Date: Fri, 19 Apr 2013 00:07:00 +0000 Subject: [PATCH] Added Asterisk 1.8 compatibility for Sangoma CPD and the new SIP Hangup logging functions Added new cpd and sip hangup patch for Asterisk 1.8.21 git-svn-id: svn://192.168.202.10@1964 3d104415-ff17-0410-8863-d5cf3c621b8a --- agc_2-X/trunk/bin/AST_manager_listen.pl | 52 ++-- agc_2-X/trunk/extras/netboarder-cpd-1.8.patch | 223 ++++++++++++++++++ 2 files changed, 261 insertions(+), 14 deletions(-) create mode 100644 agc_2-X/trunk/extras/netboarder-cpd-1.8.patch diff --git a/agc_2-X/trunk/bin/AST_manager_listen.pl b/agc_2-X/trunk/bin/AST_manager_listen.pl index fa148375..c4130c7a 100644 --- a/agc_2-X/trunk/bin/AST_manager_listen.pl +++ b/agc_2-X/trunk/bin/AST_manager_listen.pl @@ -39,6 +39,7 @@ # 100903-0041 - Changed lead_id max length to 10 digits # 130108-1705 - Changes for Asterisk 1.8 compatibility # 130412-1216 - Added sip hangup cause logging from new patch AMI event +# 130418-1946 - Changed asterisk 1.8 compatibility for CPD and SIP Hangup # # constants @@ -1009,22 +1010,43 @@ while($one_day_interval > 0) # CallerIDName: V0202034729000030735 # Uniqueid: 1233564450.141 # Result: Answering-Machine - if ( ($command_line[2] =~ /^Channel: /i) && ($command_line[4] =~ /^Uniqueid: /i) ) + if ( ($command_line[3] =~ /^Channel: /i) && ($command_line[5] =~ /^Uniqueid: /i) ) { &get_time_now; - $channel = $command_line[2]; + $channel = $command_line[3]; $channel =~ s/Channel: |\s*$//gi; - $callid = $command_line[3]; + $callid = $command_line[4]; $callid =~ s/CallerIDName: |\s*$//gi; $callid =~ s/^\"//gi; # remove leading quotes $callid =~ s/\".*$//gi; # remove trailing quotes and anything else if ($callid =~ /\S\S\S\S\S\S\S\S\S\S\S\S\S\S\S\S\S\S/) {$callid =~ s/ .*//gi;} # remove everything after the space for Orex - $uniqueid = $command_line[4]; + $uniqueid = $command_line[5]; $uniqueid =~ s/Uniqueid: |\s*$//gi; - $result = $command_line[5]; - $result =~ s/Result: |\s*$//gi; - if (length($result)>0) + + # Pulled from the CPD-Result SIP Header + $cpd_result = $command_line[6]; + $cpd_result =~ s/CPDResult: |\s*$//gi; + + # Pulled from the X-Netborder-Detailed-CPD-Result-v2-0 SIP Header + $cpd_detailed_result = $command_line[7]; + $cpd_detailed_result =~ s/CPDDetailedResult: |\s*$//gi; + + # Pulled from the X-Netborder-Call-ID SIP Header + $cpd_call_id = $command_line[8]; + $cpd_call_id =~ s/CPDCallID: |\s*$//gi; + + # Pulled from the X-Netborder-Cpa-Reference-ID SIP Header + $cpd_ref_id = $command_line[9]; + $cpd_ref_id =~ s/CPDReferenceID: |\s*$//gi; + + # Pulled from the X-Netborder-Cpa-Campaign-Name SIP Header + $cpd_camp_name = $command_line[10]; + $cpd_camp_name =~ s/CPDCampaignName: |\s*$//gi; + + print STDERR "|cpd_result = $cpd_result|cpd_detailed_result = $cpd_detailed_result|cpd_call_id = $cpd_call_id|cpd_ref_id = $cpd_ref_id|cpd_camp_name = $cpd_camp_name|\n"; + + if (length($cpd_result)>0) { # 2011-03-22 13:22:12.123 (1277187888 123 456) # ALTER TABLE vicidial_cpd_log ADD hires_time VARCHAR(26) default ''; @@ -1043,8 +1065,10 @@ while($one_day_interval > 0) $lead_id = substr($callid, 10, 10); $lead_id = ($lead_id + 0); - # $stmtA = "INSERT INTO vicidial_cpd_log set channel='$channel', uniqueid='$uniqueid', callerid='$callid', server_ip='$server_ip', lead_id='$lead_id', event_date='$now_date', result='$result', hires_time='$HRnow_date';"; - $stmtA = "INSERT INTO vicidial_cpd_log set channel='$channel', uniqueid='$uniqueid', callerid='$callid', server_ip='$server_ip', lead_id='$lead_id', event_date='$now_date', result='$result';"; + # $stmtA = "INSERT INTO vicidial_cpd_log set channel='$channel', uniqueid='$uniqueid', callerid='$callid', server_ip='$server_ip', lead_id='$lead_id', event_date='$now_date', result='$cpd_result', hires_time='$HRnow_date';"; + + # TODO change the cpd log and this insert to include the new SIP Headers for 2.0 CPD + $stmtA = "INSERT INTO vicidial_cpd_log set channel='$channel', uniqueid='$uniqueid', callerid='$callid', server_ip='$server_ip', lead_id='$lead_id', event_date='$now_date', result='$cpd_result';"; print STDERR "|$stmtA|\n"; my $affected_rows = $dbhA->do($stmtA); if($DB){print "|$affected_rows CPD_log inserted|$HRnow_date|$s_hires|$usec|\n";} @@ -1060,19 +1084,19 @@ while($one_day_interval > 0) # CallerIDName: M4121149450000795193 # Uniqueid: 1233564450.141 # Result: 603 - if ( ($command_line[2] =~ /^Channel: /i) && ($command_line[4] =~ /^Uniqueid: /i) ) + if ( ($command_line[3] =~ /^Channel: /i) && ($command_line[5] =~ /^Uniqueid: /i) ) { &get_time_now; - $channel = $command_line[2]; + $channel = $command_line[3]; $channel =~ s/Channel: |\s*$//gi; - $callid = $command_line[3]; + $callid = $command_line[4]; $callid =~ s/CallerIDName: |\s*$//gi; $callid =~ s/^\"//gi; $callid =~ s/\".*$//gi; if ($callid =~ /\S\S\S\S\S\S\S\S\S\S\S\S\S\S\S\S\S\S/) {$callid =~ s/ .*//gi;} - $uniqueid = $command_line[4]; + $uniqueid = $command_line[5]; $uniqueid =~ s/Uniqueid: |\s*$//gi; - $result = $command_line[5]; + $result = $command_line[6]; $result =~ s/Result: |\s*$//gi; @result_details=split(/\|/, $result); if ( (length($result)>0) && ($result_details[0] !~ /^407/) ) diff --git a/agc_2-X/trunk/extras/netboarder-cpd-1.8.patch b/agc_2-X/trunk/extras/netboarder-cpd-1.8.patch new file mode 100644 index 00000000..fd268b89 --- /dev/null +++ b/agc_2-X/trunk/extras/netboarder-cpd-1.8.patch @@ -0,0 +1,223 @@ +diff -Naur asterisk-1.8.21.0.old//channels/chan_sip.c asterisk-1.8.21.0/channels/chan_sip.c +--- asterisk-1.8.21.0.old//channels/chan_sip.c 2013-04-18 08:18:19.000000000 -0400 ++++ asterisk-1.8.21.0/channels/chan_sip.c 2013-04-18 10:49:40.000000000 -0400 +@@ -1470,6 +1470,7 @@ + static int sip_reinvite_retry(const void *data); + + /*--- Parsing SIP requests and responses */ ++static int check_cpd_results(struct sip_pvt *p, struct sip_request *req); + static void append_date(struct sip_request *req); /* Append date to SIP packet */ + static int determine_firstline_parts(struct sip_request *req); + static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype); +@@ -5690,6 +5691,7 @@ + dialog->callgroup = peer->callgroup; + dialog->pickupgroup = peer->pickupgroup; + dialog->allowtransfer = peer->allowtransfer; ++ dialog->enable_netborder_cpd = peer->enable_netborder_cpd; + dialog->jointnoncodeccapability = dialog->noncodeccapability; + + /* Update dialog authorization credentials */ +@@ -7745,6 +7747,66 @@ + return _default; + } + ++/*! \brief Check for a CPD-Result ++ * This looks for a CPD-Result in the sip_request ++ * and throws a manager event if it finds one ++ */ ++static int check_cpd_results(struct sip_pvt *p, struct sip_request *req) { ++ const char *cpdr = get_header(req, "CPD-Result"); ++ const char *cpddr = get_header(req, "X-Netborder-Detailed-CPD-Result-v2-0"); ++ const char *cpdcid = get_header(req, "X-Netborder-Call-ID"); ++ const char *cpdrid = get_header(req, "X-Netborder-Cpa-Reference-ID"); ++ const char *cpdcamp = get_header(req, "X-Netborder-Cpa-Campaign-Name"); ++ /* See if NetBorder had anything to say */ ++ if (!(ast_strlen_zero(cpdr))) { ++ if (p->owner) { ++ /* If so throw a manager event with the result */ ++ manager_event( ++ EVENT_FLAG_SYSTEM, ++ "CPD-Result", ++ "Channeltype: SIP\r\n" ++ "Channel: %s\r\n" ++ "CallerIDName: %s\r\n" ++ "Uniqueid: %s\r\n" ++ "CPDResult: %s\r\n" ++ "CPDDetailedResult: %s\r\n" ++ "CPDCallID: %s\r\n" ++ "CPDReferenceID: %s\r\n" ++ "CPDCampaignName: %s\r\n", ++ p->owner->name, ++ S_COR(p->owner->caller.id.name.valid, p->owner->caller.id.name.str, ""), ++ p->owner->uniqueid, ++ cpdr, ++ S_OR(cpddr, ""), ++ S_OR(cpdcid, ""), ++ S_OR(cpdrid, ""), ++ S_OR(cpdcamp, "") ++ ); ++ } else { ++ /* Apparently we can have a CPD-Result and no owner, better not crash it though */ ++ manager_event( ++ EVENT_FLAG_SYSTEM, ++ "CPD-Result", ++ "Channeltype: SIP\r\n" ++ "Channel: UNKNOWN\r\n" ++ "CallerIDName: UNKNOWN\r\n" ++ "Uniqueid: UNKNOWN\r\n" ++ "CPDResult: %s\r\n" ++ "CPDDetailedResult: %s\r\n" ++ "CPDCallID: %s\r\n" ++ "CPDReferenceID: %s\r\n" ++ "CPDCampaignName: %s\r\n", ++ cpdr, ++ S_OR(cpddr, ""), ++ S_OR(cpdcid, ""), ++ S_OR(cpdrid, ""), ++ S_OR(cpdcamp, "") ++ ); ++ } ++ } ++ return 0; ++} ++ + static const char *__get_header(const struct sip_request *req, const char *name, int *start) + { + /* +@@ -8178,6 +8240,7 @@ + ast_string_field_set(p, mohsuggest, default_mohsuggest); + p->capability = sip_cfg.capability; + p->allowtransfer = sip_cfg.allowtransfer; ++ p->enable_netborder_cpd = sip_cfg.enable_netborder_cpd; + if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || + (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { + p->noncodeccapability |= AST_RTP_DTMF; +@@ -12422,6 +12485,7 @@ + const char *n = NULL; /* XXX what is this, exactly ? */ + const char *d = NULL; /* domain in from header */ + const char *urioptions = ""; ++ const char *netbordercpd = ";cpd=on"; /* string used to enable NetBorder's CPD */ + int ourport; + + if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { +@@ -12529,6 +12593,9 @@ + /* If custom URI options have been provided, append them */ + if (p->options && !ast_strlen_zero(p->options->uri_options)) + ast_str_append(&invite, 0, ";%s", p->options->uri_options); ++ ++ /* Tell NetBorder to enable CPD */ ++ if (p->enable_netborder_cpd) ast_str_append(&invite, 0, "%s", netbordercpd); + + /* This is the request URI, which is the next hop of the call + which may or may not be the destination of the call +@@ -18083,6 +18150,7 @@ + if (!ast_strlen_zero(peer->accountcode)) + ast_cli(fd, " Accountcode : %s\n", peer->accountcode); + ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); ++ ast_cli(fd, " Netborder CPD: %s\n", AST_CLI_YESNO(peer->enable_netborder_cpd)); + ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); + ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); + if (!ast_strlen_zero(peer->fromuser)) +@@ -18209,6 +18277,7 @@ + astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest); + peer_mailboxes_to_str(&mailbox_str, peer); + astman_append(s, "VoiceMailbox: %s\r\n", ast_str_buffer(mailbox_str)); ++ astman_append(s, "Netborder CPD: %s\n", AST_CLI_YESNO(peer->enable_netborder_cpd)); + astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); + astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); + astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards); +@@ -18360,6 +18429,7 @@ + if (!ast_strlen_zero(user->accountcode)) + ast_cli(a->fd, " Accountcode : %s\n", user->accountcode); + ast_cli(a->fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); ++ ast_cli(a->fd, " Netborder CPD: %s\n", AST_CLI_YESNO(user->enable_netborder_cpd)); + ast_cli(a->fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); + ast_cli(a->fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); + ast_cli(a->fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); +@@ -18816,6 +18886,7 @@ + sip_cfg.notifycid == IGNORE_CONTEXT ? " (Ignoring context)" : ""); + } + ast_cli(a->fd, " Notify hold state: %s\n", AST_CLI_YESNO(sip_cfg.notifyhold)); ++ ast_cli(a->fd, " Enable Netborder CPD: %s\n", AST_CLI_YESNO(sip_cfg.enable_netborder_cpd)); + ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(sip_cfg.allowtransfer)); + ast_cli(a->fd, " Max Call Bitrate: %d kbps\n", default_maxcallbitrate); + ast_cli(a->fd, " Auto-Framing: %s\n", AST_CLI_YESNO(global_autoframing)); +@@ -19208,6 +19279,7 @@ + ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); + ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa)); + ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv)); ++ ast_cli(a->fd, " Enable Netborder CPD: %s\n", AST_CLI_YESNO(cur->enable_netborder_cpd)); + ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); + ast_cli(a->fd, " Force rport: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT))); + if (ast_sockaddr_isnull(&cur->redirip)) { +@@ -21722,6 +21794,9 @@ + return; + } + ++ /* Check if NetBorder had anything to say */ ++ check_cpd_results(p, req); ++ + if (p->relatedpeer && sipmethod == SIP_OPTIONS) { + /* We don't really care what the response is, just that it replied back. + Well, as long as it's not a 100 response... since we might +@@ -27822,6 +27897,7 @@ + peer->rtpholdtimeout = global_rtpholdtimeout; + peer->rtpkeepalive = global_rtpkeepalive; + peer->allowtransfer = sip_cfg.allowtransfer; ++ peer->enable_netborder_cpd = sip_cfg.enable_netborder_cpd; + peer->autoframing = global_autoframing; + peer->t38_maxdatagram = global_t38_maxdatagram; + peer->qualifyfreq = global_qualifyfreq; +@@ -28247,6 +28323,8 @@ + peer->callgroup = ast_get_group(v->value); + } else if (!strcasecmp(v->name, "allowtransfer")) { + peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; ++ } else if (!strcasecmp(v->name, "enable-netborder-cpd")) { ++ peer->enable_netborder_cpd = ast_true(v->value); + } else if (!strcasecmp(v->name, "pickupgroup")) { + peer->pickupgroup = ast_get_group(v->value); + } else if (!strcasecmp(v->name, "allow")) { +@@ -28814,6 +28892,7 @@ + global_rtpholdtimeout = 0; + global_rtpkeepalive = DEFAULT_RTPKEEPALIVE; + sip_cfg.allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ ++ sip_cfg.enable_netborder_cpd = 0; /* Netborder CPD - Disable by default */ + sip_cfg.rtautoclear = 120; + ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for all devices: TRUE */ + ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP_YES); /* Default for all devices: Yes */ +@@ -28922,6 +29001,8 @@ + } + } else if (!strcasecmp(v->name, "allowtransfer")) { + sip_cfg.allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; ++ } else if (!strcasecmp(v->name, "enable-netborder-cpd")) { ++ sip_cfg.enable_netborder_cpd = ast_true(v->value); + } else if (!strcasecmp(v->name, "rtcachefriends")) { + ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); + } else if (!strcasecmp(v->name, "rtsavesysname")) { +diff -Naur asterisk-1.8.21.0.old//channels/sip/include/sip.h asterisk-1.8.21.0/channels/sip/include/sip.h +--- asterisk-1.8.21.0.old//channels/sip/include/sip.h 2013-03-27 13:36:42.000000000 -0400 ++++ asterisk-1.8.21.0/channels/sip/include/sip.h 2013-04-18 10:48:48.000000000 -0400 +@@ -705,6 +705,7 @@ + int notifyhold; /*!< Send notifications on hold */ + enum notifycid_setting notifycid; /*!< Send CID with ringing notifications */ + enum transfermodes allowtransfer; /*!< SIP Refer restriction scheme */ ++ int enable_netborder_cpd; /*!< Enable Sangoma Netborder CPD */ + int allowsubscribe; /*!< Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE + the global setting is in globals_flags[1] */ + char realm[MAXHOSTNAMELEN]; /*!< Default realm */ +@@ -1059,6 +1060,7 @@ + struct ast_sockaddr recv; /*!< Received as */ + struct ast_sockaddr ourip; /*!< Our IP (as seen from the outside) */ + enum transfermodes allowtransfer; /*!< REFER: restriction scheme */ ++ int enable_netborder_cpd; /*!< Enable Sangoma Netborder CPD */ + struct ast_channel *owner; /*!< Who owns us (if we have an owner) */ + struct sip_route *route; /*!< Head of linked list of routing steps (fm Record-Route) */ + struct sip_notify *notify; /*!< Custom notify type */ +@@ -1236,6 +1238,7 @@ + int busy_level; /*!< Level of active channels where we signal busy */ + int maxforwards; /*!< SIP Loop prevention */ + enum transfermodes allowtransfer; /*! SIP Refer restriction scheme */ ++ int enable_netborder_cpd; /*!< Enable Sangoma Netborder CPD */ + struct ast_codec_pref prefs; /*!< codec prefs */ + int lastmsgssent; + unsigned int sipoptions; /*!< Supported SIP options */