diff -Naur asterisk-11.22.0/channels/chan_sip.c asterisk-11.22.0-new/channels/chan_sip.c
--- asterisk-11.22.0/channels/chan_sip.c	2016-03-29 15:25:17.000000000 -0400
+++ asterisk-11.22.0-new/channels/chan_sip.c	2016-06-07 12:38:35.107094092 -0400
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2012, Digium, Inc.
+ * /Copyright (C) 1999 - 2012, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  *
@@ -1559,6 +1559,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 int determine_firstline_parts(struct sip_request *req);
 static const struct cfsubscription_types *find_subscription_type(enum subscriptiontype subtype);
 static const char *gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize);
@@ -5903,6 +5904,7 @@
 	dialog->named_pickupgroups = ast_ref_namedgroups(peer->named_pickupgroups);
 	ast_copy_string(dialog->zone, peer->zone, sizeof(dialog->zone));
 	dialog->allowtransfer = peer->allowtransfer;
+	dialog->enable_netborder_cpd = peer->enable_netborder_cpd;
 	dialog->jointnoncodeccapability = dialog->noncodeccapability;
 
 	/* Update dialog authorization credentials */
@@ -8111,6 +8113,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 = sip_get_header(req, "CPD-Result");
+	const char *cpddr = sip_get_header(req, "X-Netborder-Detailed-CPD-Result-v2-0");
+	const char *cpdcid = sip_get_header(req, "X-Netborder-Call-ID");
+	const char *cpdrid = sip_get_header(req, "X-Netborder-Cpa-Reference-ID");
+	const char *cpdcamp = sip_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",
+				ast_channel_name(p->owner),
+				S_COR(ast_channel_caller(p->owner)->id.name.valid, ast_channel_caller(p->owner)->id.name.str, "<unknown>"),
+				ast_channel_uniqueid(p->owner),
+				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)
 {
 	/*
@@ -8626,6 +8688,7 @@
 	ast_string_field_set(p, mohsuggest, default_mohsuggest);
 	ast_format_cap_copy(p->caps, sip_cfg.caps);
 	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;
@@ -13825,6 +13888,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;
 	int cid_has_name = 1;
 	int cid_has_num = 1;
@@ -13980,6 +14044,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
@@ -20135,6 +20202,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))
@@ -20275,6 +20343,7 @@
 		astman_append(s, "MOHSuggest: %s\r\n", peer->mohsuggest);
 		peer_mailboxes_to_str(&tmp_str, peer);
 		astman_append(s, "VoiceMailbox: %s\r\n", ast_str_buffer(tmp_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);
@@ -20433,6 +20502,7 @@
 			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, "  Tonezone     : %s\n", user->zone[0] != '\0' ? user->zone : "<Not set>");
+		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));
@@ -20908,6 +20978,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));
@@ -21323,6 +21394,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", force_rport_string(cur->flags));
 			if (ast_sockaddr_isnull(&cur->redirip)) {
@@ -24013,6 +24085,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
@@ -30694,6 +30769,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;
@@ -31166,6 +31242,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, "namedcallgroup")) {
@@ -31814,6 +31892,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 */
@@ -31938,6 +32017,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-11.22.0/channels/sip/include/sip.h asterisk-11.22.0-new/channels/sip/include/sip.h
--- asterisk-11.22.0/channels/sip/include/sip.h	2016-03-29 15:25:17.000000000 -0400
+++ asterisk-11.22.0-new/channels/sip/include/sip.h	2016-06-07 12:32:46.840453388 -0400
@@ -766,6 +766,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 */
@@ -1145,6 +1146,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 */
@@ -1334,6 +1336,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;				/*!< The last known VM message counts (new/old) */
 	unsigned int sipoptions;        /*!<  Supported SIP options */
