summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMark Spencer <markster@digium.com>2004-12-02 23:44:35 +0000
committerMark Spencer <markster@digium.com>2004-12-02 23:44:35 +0000
commit3b7b1306835a4a837b23af9d9f99cc88bda40f62 (patch)
tree8e2d6e5be60b68947aaab563cb2be072aebea130 /channels
parent1a147cf804d18aa25d0d30ae4a9189999edba26d (diff)
Add nasty "AddSIPHeader" application (bug #2846)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4373 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rwxr-xr-xchannels/chan_sip.c132
1 files changed, 117 insertions, 15 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 7ebdc1b51..41ff1eca2 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -114,7 +114,7 @@ static int default_expiry = DEFAULT_DEFAULT_EXPIRY;
#define DEBUG_SEND 1 /* Transmit data */
static char *desc = "Session Initiation Protocol (SIP)";
-static char *type = "SIP";
+static char *channeltype = "SIP";
static char *tdesc = "Session Initiation Protocol (SIP)";
static char *config = "sip.conf";
@@ -561,7 +561,7 @@ static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_r
static int transmit_response_with_auth(struct sip_pvt *p, char *msg, struct sip_request *req, char *rand, int reliable, char *header);
static int transmit_request(struct sip_pvt *p, char *msg, int inc, int reliable, int newbranch);
static int transmit_request_with_auth(struct sip_pvt *p, char *msg, int inc, int reliable, int newbranch);
-static int transmit_invite(struct sip_pvt *p, char *msg, int sendsdp, char *auth, char *authheader, char *vxml_url,char *distinctive_ring, char *osptoken,int init);
+static int transmit_invite(struct sip_pvt *p, char *msg, int sendsdp, char *auth, char *authheader, char *vxml_url, char *distinctive_ring, char *osptoken, int addsipheaders, int init);
static int transmit_reinvite_with_sdp(struct sip_pvt *p);
static int transmit_info_with_digit(struct sip_pvt *p, char digit);
static int transmit_message_with_text(struct sip_pvt *p, char *text);
@@ -1043,7 +1043,7 @@ static void register_peer_exten(struct sip_peer *peer, int onoff)
stringp = multi;
while((ext = strsep(&stringp, "&"))) {
if (onoff)
- ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, type);
+ ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype);
else
ast_context_remove_extension(regcontext, ext, 1, NULL);
}
@@ -1388,6 +1388,7 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
#endif
struct varshead *headp;
struct ast_var_t *current;
+ int addsipheaders = 0;
p = ast->pvt->pvt;
if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
@@ -1404,7 +1405,12 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
} else if (!distinctive_ring && !strcasecmp(ast_var_name(current),"ALERT_INFO")) {
/* Check whether there is a ALERT_INFO variable */
distinctive_ring = ast_var_value(current);
+ } else if (!addsipheaders && !strncasecmp(ast_var_name(current),"SIPADDHEADER",strlen("SIPADDHEADER"))) {
+ /* Check whether there is a variable with a name starting with SIPADDHEADER */
+ addsipheaders = 1;
}
+
+
#ifdef OSP_SUPPORT
else if (!osptoken && !strcasecmp(ast_var_name(current), "OSPTOKEN")) {
osptoken = ast_var_value(current);
@@ -1429,7 +1435,7 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
if ( res != -1 ) {
p->callingpres = ast->cid.cid_pres;
p->jointcapability = p->capability;
- transmit_invite(p, "INVITE", 1, NULL, NULL, vxml_url,distinctive_ring, osptoken, 1);
+ transmit_invite(p, "INVITE", 1, NULL, NULL, vxml_url,distinctive_ring, osptoken, addsipheaders, 1);
if (p->maxtime) {
/* Initialize auto-congest time */
p->initid = ast_sched_add(sched, p->maxtime * 4, auto_congest, p);
@@ -1949,7 +1955,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title)
{
snprintf(tmp->name, sizeof(tmp->name), "SIP/%s-%08x", i->fromdomain, (int)(long)(i));
}
- tmp->type = type;
+ tmp->type = channeltype;
if (i->dtmfmode & SIP_DTMF_INBAND) {
i->vad = ast_dsp_new();
ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
@@ -3726,7 +3732,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, char *cmd, c
/*--- transmit_invite: Build REFER/INVITE/OPTIONS message and trasmit it ---*/
-static int transmit_invite(struct sip_pvt *p, char *cmd, int sdp, char *auth, char *authheader, char *vxml_url, char *distinctive_ring, char *osptoken, int init)
+static int transmit_invite(struct sip_pvt *p, char *cmd, int sdp, char *auth, char *authheader, char *vxml_url, char *distinctive_ring, char *osptoken, int addsipheaders, int init)
{
struct sip_request req;
char iabuf[INET_ADDRSTRLEN];
@@ -3761,6 +3767,47 @@ static int transmit_invite(struct sip_pvt *p, char *cmd, int sdp, char *auth, ch
add_header(&req, "Alert-info",distinctive_ring);
}
add_header(&req, "Allow", ALLOWED_METHODS);
+ if (addsipheaders && init) {
+ struct ast_channel *ast;
+ char *header = (char *) NULL;
+ char *content = (char *) NULL;
+ char *end = (char *) NULL;
+ struct varshead *headp = (struct varshead *) NULL;
+ struct ast_var_t *current;
+
+ ast = p->owner; /* The owner channel */
+ if (ast) {
+ headp=&ast->varshead;
+ if (!headp)
+ ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n");
+ else {
+ AST_LIST_TRAVERSE(headp,current,entries) {
+ /* SIPADDHEADER: Add SIP header to outgoing call */
+ if (!strncasecmp(ast_var_name(current),"SIPADDHEADER",strlen("SIPADDHEADER"))) {
+ header = ast_var_value(current);
+ /* Strip of the starting " (if it's there) */
+ if (*header == '"')
+ header++;
+ if ((content = strchr(header, ':'))) {
+ *content = '\0';
+ content++; /* Move pointer ahead */
+ /* Skip white space */
+ while (*content == ' ')
+ content++;
+ /* Strip the ending " (if it's there) */
+ end = content + strlen(content) -1;
+ if (*end == '"')
+ *end = '\0';
+
+ add_header(&req, header, content);
+ if (sipdebug)
+ ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", header, content);
+ }
+ }
+ }
+ }
+ }
+ }
if (sdp) {
ast_rtp_offered_from_local(p->rtp, 1);
add_sdp(&req, p);
@@ -6260,7 +6307,7 @@ static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *heade
/* No way to authenticate */
return -1;
}
- return transmit_invite(p,msg,!strcasecmp(msg, "INVITE"),digest, respheader, NULL,NULL,NULL, init);
+ return transmit_invite(p,msg,!strcasecmp(msg, "INVITE"),digest, respheader, NULL,NULL,NULL, 0, init);
}
/*--- reply_digest: reply to authentication for outbound registrations ---*/
@@ -7994,9 +8041,9 @@ static int sip_poke_peer(struct sip_peer *peer)
p->outgoing = 1;
#ifdef VOCAL_DATA_HACK
strncpy(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username) - 1);
- transmit_invite(p, "INVITE", 0, NULL, NULL, NULL,NULL,NULL, 1);
+ transmit_invite(p, "INVITE", 0, NULL, NULL, NULL,NULL,NULL, 0, 1);
#else
- transmit_invite(p, "OPTIONS", 0, NULL, NULL, NULL,NULL,NULL, 1);
+ transmit_invite(p, "OPTIONS", 0, NULL, NULL, NULL,NULL,NULL, 0, 1);
#endif
gettimeofday(&peer->ps, NULL);
peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
@@ -8687,7 +8734,7 @@ static int reload_config(void)
strncpy(regcontext, v->value, sizeof(regcontext) - 1);
/* Create context if it doesn't exist already */
if (!ast_context_find(regcontext))
- ast_context_create(NULL, regcontext, type);
+ ast_context_create(NULL, regcontext, channeltype);
} else if (!strcasecmp(v->name, "callerid")) {
strncpy(default_callerid, v->value, sizeof(default_callerid)-1);
} else if (!strcasecmp(v->name, "fromdomain")) {
@@ -8945,6 +8992,18 @@ static char *synopsis_dtmfmode = "Change the dtmfmode for a SIP call";
static char *descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n";
static char *app_dtmfmode = "SIPDtmfMode";
+static char *app_sipaddheader = "SIPAddHeader";
+static char *synopsis_sipaddheader = "Add a SIP header to the outbound call";
+
+
+static char *descrip_sipaddheader = ""
+" SIPAddHeader(Header: Content)\n"
+"Adds a header to a SIP call placed with DIAL.\n"
+"Remember to user the X-header if you are adding non-standard SIP\n"
+"headers, like \"X-Asterisk-Accuntcode:\". Use this with care.\n"
+"Adding the wrong headers may jeopardize the SIP dialog.\n"
+"Always returns 0\n";
+
/*--- sip_dtmfmode: change the DTMFmode for a SIP call (application) ---*/
static int sip_dtmfmode(struct ast_channel *chan, void *data)
{
@@ -8957,7 +9016,7 @@ static int sip_dtmfmode(struct ast_channel *chan, void *data)
return 0;
}
ast_mutex_lock(&chan->lock);
- if (chan->type != type) {
+ if (chan->type != channeltype) {
ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
ast_mutex_unlock(&chan->lock);
return 0;
@@ -8990,6 +9049,47 @@ static int sip_dtmfmode(struct ast_channel *chan, void *data)
return 0;
}
+/*--- sip_addheader: Add a SIP header ---*/
+static int sip_addheader(struct ast_channel *chan, void *data)
+{
+ int arglen;
+ int no = 0;
+ int ok = 0;
+ char *content = (char *) NULL;
+ char varbuf[128];
+
+ arglen = strlen(data);
+ if (!arglen) {
+ ast_log(LOG_WARNING, "This application requires the argument: Header\n");
+ return 0;
+ }
+ ast_mutex_lock(&chan->lock);
+ if (chan->type != channeltype) {
+ ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n");
+ ast_mutex_unlock(&chan->lock);
+ return 0;
+ }
+
+ /* Check for headers */
+ while (!ok && no <= 50) {
+ no++;
+ snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no);
+ content = pbx_builtin_getvar_helper(chan, varbuf);
+
+ if (!content)
+ ok = 1;
+ }
+ if (ok) {
+ pbx_builtin_setvar_helper (chan, varbuf, data);
+ if (sipdebug)
+ ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf);
+ } else {
+ ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
+ }
+ ast_mutex_unlock(&chan->lock);
+ return 0;
+}
+
static int sip_get_codec(struct ast_channel *chan)
{
struct sip_pvt *p = chan->pvt->pvt;
@@ -9138,8 +9238,8 @@ int load_module()
res = reload_config();
if (!res) {
/* Make sure we can register our sip channel type */
- if (ast_channel_register_ex(type, tdesc, ((AST_FORMAT_MAX_AUDIO << 1) - 1), sip_request, sip_devicestate)) {
- ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
+ if (ast_channel_register_ex(channeltype, tdesc, ((AST_FORMAT_MAX_AUDIO << 1) - 1), sip_request, sip_devicestate)) {
+ ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
return -1;
}
ast_cli_register(&cli_show_users);
@@ -9161,9 +9261,10 @@ int load_module()
ast_cli_register(&cli_no_history);
ast_cli_register(&cli_sip_reload);
ast_cli_register(&cli_inuse_show);
- sip_rtp.type = type;
+ sip_rtp.type = channeltype;
ast_rtp_proto_register(&sip_rtp);
ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
+ ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
ast_mutex_lock(&peerl.lock);
for (peer = peerl.peers; peer; peer = peer->next)
sip_poke_peer(peer);
@@ -9186,6 +9287,7 @@ int unload_module()
/* First, take us out of the channel loop */
ast_unregister_application(app_dtmfmode);
+ ast_unregister_application(app_sipaddheader);
ast_cli_unregister(&cli_show_users);
ast_cli_unregister(&cli_show_channels);
ast_cli_unregister(&cli_show_channel);
@@ -9206,7 +9308,7 @@ int unload_module()
ast_cli_unregister(&cli_sip_reload);
ast_cli_unregister(&cli_inuse_show);
ast_rtp_proto_unregister(&sip_rtp);
- ast_channel_unregister(type);
+ ast_channel_unregister(channeltype);
if (!ast_mutex_lock(&iflock)) {
/* Hangup all interfaces if they have an owner */
p = iflist;