summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorKevin P. Fleming <kpfleming@digium.com>2005-09-27 01:54:17 +0000
committerKevin P. Fleming <kpfleming@digium.com>2005-09-27 01:54:17 +0000
commit8af7725f98fb24372c0915af4406d5ed21d245b8 (patch)
tree415c0672335394c6119cca3e7148ea8afe8f5676 /channels
parent266529a50318a5537831ec3de8db21e7eb82413f (diff)
support optional sending of Remote-Party-ID headers (issue #2471, heavily modified to actually work properly)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6671 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rwxr-xr-xchannels/chan_sip.c116
1 files changed, 111 insertions, 5 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 3751f4b3f..97f6056c9 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -546,6 +546,8 @@ struct sip_auth {
/* Call states */
#define SIP_CALL_ONHOLD (1 << 28)
#define SIP_CALL_LIMIT (1 << 29)
+/* Remote Party-ID Support */
+#define SIP_SENDRPID (1 << 30)
/* a new page of flags for peer */
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0)
@@ -622,6 +624,8 @@ static struct sip_pvt {
char fullcontact[128]; /* The Contact: that the UA registers with us */
char accountcode[AST_MAX_ACCOUNT_CODE]; /* Account code */
char our_contact[256]; /* Our contact header */
+ char *rpid; /* Our RPID header */
+ char *rpid_from; /* Our RPID From header */
char realm[MAXHOSTNAMELEN]; /* Authorization realm */
char nonce[256]; /* Authorization nonce */
char opaque[256]; /* Opaque nonsense */
@@ -2074,6 +2078,13 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner)
p->registry->call = NULL;
ASTOBJ_UNREF(p->registry,sip_registry_destroy);
}
+
+ if (p->rpid)
+ free(p->rpid);
+
+ if (p->rpid_from)
+ free(p->rpid_from);
+
/* Unlink us from the owner if we have one */
if (p->owner) {
if (lockowner)
@@ -3013,7 +3024,7 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg
build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
else
ast_copy_string(p->callid, callid, sizeof(p->callid));
- ast_copy_flags(p, (&global_flags), SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_DTMF | SIP_REINVITE | SIP_PROG_INBAND | SIP_OSPAUTH);
+ ast_copy_flags(p, (&global_flags), SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | SIP_PROG_INBAND | SIP_OSPAUTH);
/* Assign default music on hold class */
strcpy(p->musicclass, global_musicclass);
p->capability = global_capability;
@@ -4482,6 +4493,90 @@ static void build_contact(struct sip_pvt *p)
snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip));
}
+/*--- build_rpid: Build the Remote Party-ID & From using callingpres options ---*/
+static void build_rpid(struct sip_pvt *p)
+{
+ int send_pres_tags = 1;
+ const char *privacy;
+ const char *screen;
+ char buf[256];
+ const char *clid = default_callerid;
+ const char *clin = NULL;
+ char iabuf[INET_ADDRSTRLEN];
+ const char *fromdomain;
+
+ if (p->rpid || p->rpid_from)
+ return;
+
+ if (p->owner && p->owner->cid.cid_num) {
+ clid = strdup(p->owner->cid.cid_num);
+ }
+
+ if (p->owner && p->owner->cid.cid_name) {
+ clin = strdup(p->owner->cid.cid_name);
+ }
+ if (!clin || ast_strlen_zero(clin))
+ clin = clid;
+
+ switch (p->callingpres) {
+ case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
+ privacy = "off";
+ screen = "no";
+ break;
+ case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
+ privacy = "off";
+ screen = "pass";
+ break;
+ case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
+ privacy = "off";
+ screen = "fail";
+ break;
+ case AST_PRES_ALLOWED_NETWORK_NUMBER:
+ privacy = "off";
+ screen = "yes";
+ break;
+ case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
+ privacy = "full";
+ screen = "no";
+ break;
+ case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
+ privacy = "full";
+ screen = "pass";
+ break;
+ case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
+ privacy = "full";
+ screen = "fail";
+ break;
+ case AST_PRES_PROHIB_NETWORK_NUMBER:
+ privacy = "full";
+ screen = "fail";
+ break;
+ case AST_PRES_NUMBER_NOT_AVAILABLE:
+ send_pres_tags = 0;
+ break;
+ default:
+ ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
+ if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
+ privacy = "full";
+ else
+ privacy = "off";
+ screen = "no";
+ break;
+ }
+
+ fromdomain = ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain;
+
+ snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
+ if (send_pres_tags)
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
+ p->rpid = strdup(buf);
+
+ snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>;tag=as%08x", clin,
+ ast_strlen_zero(p->fromuser) ? clid : p->fromuser,
+ fromdomain, p->tag);
+ p->rpid_from = strdup(buf);
+}
+
/*--- initreqprep: Initiate new SIP request to peer/user ---*/
static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod)
{
@@ -4601,7 +4696,12 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
add_header(req, "Via", p->via);
/* SLD: FIXME?: do Route: here too? I think not cos this is the first request.
* OTOH, then we won't have anything in p->route anyway */
- add_header(req, "From", from);
+ /* Build Remote Party-ID and From */
+ if (ast_test_flag(p, SIP_SENDRPID)) {
+ build_rpid(p);
+ add_header(req, "From", p->rpid_from);
+ } else
+ add_header(req, "From", from);
ast_copy_string(p->exten, l, sizeof(p->exten));
build_contact(p);
add_header(req, "To", to);
@@ -4609,6 +4709,8 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
add_header(req, "Call-ID", p->callid);
add_header(req, "CSeq", tmp);
add_header(req, "User-Agent", default_useragent);
+ if (ast_test_flag(p, SIP_SENDRPID))
+ add_header(req, "Remote-Party-ID", p->rpid);
}
/*--- transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---*/
@@ -6827,7 +6929,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme
if (debug)
ast_verbose("Found peer '%s'\n", peer->name);
/* Take the peer */
- ast_copy_flags(p, peer, SIP_TRUSTRPID | SIP_USECLIENTCODE | SIP_NAT | SIP_PROG_INBAND | SIP_OSPAUTH);
+ ast_copy_flags(p, peer, SIP_TRUSTRPID | SIP_SENDRPID | SIP_USECLIENTCODE | SIP_NAT | SIP_PROG_INBAND | SIP_OSPAUTH);
/* Copy SIP extensions profile to peer */
if (p->sipoptions)
@@ -11197,6 +11299,10 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask
ast_set_flag(mask, SIP_TRUSTRPID);
ast_set2_flag(flags, ast_true(v->value), SIP_TRUSTRPID);
res = 1;
+ } else if (!strcasecmp(v->name, "sendrpid")) {
+ ast_set_flag(mask, SIP_SENDRPID);
+ ast_set2_flag(flags, ast_true(v->value), SIP_SENDRPID);
+ res = 1;
} else if (!strcasecmp(v->name, "useclientcode")) {
ast_set_flag(mask, SIP_USECLIENTCODE);
ast_set2_flag(flags, ast_true(v->value), SIP_USECLIENTCODE);
@@ -11576,7 +11682,7 @@ static struct sip_peer *temp_peer(const char *name)
ast_copy_flags(peer, &global_flags,
SIP_PROMISCREDIR | SIP_USEREQPHONE | SIP_TRUSTRPID | SIP_USECLIENTCODE |
SIP_DTMF | SIP_NAT | SIP_REINVITE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE |
- SIP_PROG_INBAND | SIP_OSPAUTH);
+ SIP_PROG_INBAND | SIP_OSPAUTH | SIP_SENDRPID);
strcpy(peer->context, default_context);
strcpy(peer->subscribecontext, default_subscribecontext);
strcpy(peer->language, default_language);
@@ -11675,7 +11781,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
ast_copy_flags(peer, &global_flags,
SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_USECLIENTCODE |
SIP_DTMF | SIP_REINVITE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE |
- SIP_PROG_INBAND | SIP_OSPAUTH);
+ SIP_PROG_INBAND | SIP_OSPAUTH | SIP_SENDRPID);
peer->capability = global_capability;
peer->rtptimeout = global_rtptimeout;
peer->rtpholdtimeout = global_rtpholdtimeout;