[asterisk-commits] kharwell: branch kharwell/pimp_sip_diversion r386161 - /team/kharwell/pimp_si...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Apr 19 17:41:26 CDT 2013
Author: kharwell
Date: Fri Apr 19 17:41:22 2013
New Revision: 386161
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386161
Log:
compiles, not tested. incoming/outgoing code in place.
Modified:
team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c
Modified: team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c?view=diff&rev=386161&r1=386160&r2=386161
==============================================================================
--- team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c (original)
+++ team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c Fri Apr 19 17:41:22 2013
@@ -36,6 +36,8 @@
#include "asterisk/strings.h"
#define DIV_HDR_MAX_SIZE 256
+
+static const pj_str_t diversion_name = { "Diversion", 8 };
/*! \brief Diversion header reasons
*
@@ -79,25 +81,39 @@
return "unknown";
}
+static enum AST_REDIRECTING_REASON reason_str_to_code(const char *text)
+{
+ enum AST_REDIRECTING_REASON code = AST_REDIRECTING_REASON_UNKNOWN;
+ int i;
+
+ for (i = 0; i < ARRAY_LEN(reason_table); ++i) {
+ if (!strcasecmp(text, reason_table[i].text)) {
+ code = reason_table[i].code;
+ break;
+ }
+ }
+
+ return code;
+}
+
static pjsip_fromto_hdr *get_diversion_header(pjsip_rx_data *rdata)
{
- static const pj_str_t diversion = { "Diversion", 8 };
- static const pj_str_t diversion = { "From", 4 };
+ static const pj_str_t from_name = { "From", 4 };
pjsip_generic_string_hdr *hdr;
pjsip_fromto_hdr *parsed;
pj_str_t value;
int size;
- if (!(hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &diversion, NULL))) {
+ if (!(hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &diversion_name, NULL))) {
return NULL;
}
pj_strdup_with_null(rdata->tp_info.pool, &value, &hdr->hvalue);
/* parse as a fromto header */
- parsed = pjsip_parse_hdr(rdata->tp_info.pool, &from, value.ptr,
- pj_strlen(&header_content), &size);
+ parsed = pjsip_parse_hdr(rdata->tp_info.pool, &from_name, value.ptr,
+ pj_strlen(&value), &size);
return parsed ? parsed : NULL;
}
@@ -109,59 +125,81 @@
ast_copy_pj_str(*dst, src, pj_strlen(src));
}
-static void set_redirecting_id(pjsip_name_addr *hdr, struct ast_party_id *data,
+static void set_redirecting_id(pjsip_name_addr *uri, struct ast_party_id *data,
struct ast_set_party_id *update)
{
- pjsip_sip_uri *uri = pjsip_uri_get_uri(hdr->uri);
-
- if (pj_strlen(uri->user)) {
+ pjsip_sip_uri *sip_uri = pjsip_uri_get_uri(uri->uri);
+
+ if (pj_strlen(&sip_uri->user)) {
update->number = 1;
data->number.valid = 1;
- set_redirecting_value(&data->number.str, uri->user);
- }
-
- if (pj_strlen(hdr->display)) {
+ set_redirecting_value(&data->number.str, &sip_uri->user);
+ }
+
+ if (pj_strlen(&uri->display)) {
update->name = 1;
data->name.valid = 1;
- set_redirecting_value(&data->name.str, hdr->display);
- }
-}
-
-static int set_redirecting(pjsip_name_addr *div_hdr, pjsip_name_addr *to_hdr,
- struct ast_party_redirecting *data,
- struct ast_set_party_redirecting *update)
-{
- set_redirecting_id(div_hdr, &data->from, &update.from);
- set_redirecting_id(to_hdr, &data->to, &update.to);
-}
-
-static int set_redirecting(struct ast_sip_session *session,
- pjsip_name_addr *div_hdr,
- pjsip_name_addr *to_hdr)
+ set_redirecting_value(&data->name.str, &uri->display);
+ }
+
+ /* if (!ast_strlen_zero(p->cid_tag)) { */
+ /* ast_free(redirecting->from.tag); */
+ /* redirecting->from.tag = ast_strdup(p->cid_tag); */
+ /* ast_free(redirecting->to.tag); */
+ /* redirecting->to.tag = ast_strdup(p->cid_tag); */
+ /* } */
+}
+
+static void set_redirecting_reason(pjsip_name_addr *uri,
+ struct ast_party_redirecting_reason *data)
+{
+ static const pj_str_t reason_name = { "reason", 6 };
+
+ pjsip_sip_uri *sip_uri = pjsip_uri_get_uri(uri->uri);
+ pjsip_param *reason = pjsip_param_find(&sip_uri->other_param, &reason_name);
+
+ if (!reason) {
+ return;
+ }
+
+ set_redirecting_value(&data->str, &reason->value);
+ data->code = reason_str_to_code(data->str);
+}
+
+static void set_redirecting(struct ast_sip_session *session,
+ pjsip_name_addr *div_uri,
+ pjsip_name_addr *to_uri)
{
struct ast_party_redirecting data;
struct ast_set_party_redirecting update;
+ if (!session->channel) {
+ return;
+ }
+
ast_party_redirecting_init(&data);
memset(&update, 0, sizeof(update));
- set_redirecting(div_hdr, to_hdr, &data, &update);
+ set_redirecting_id(div_uri, &data.from, &update.from);
+ set_redirecting_id(to_uri, &data.to, &update.to);
+ set_redirecting_reason(div_uri, &data.reason);
ast_set_party_id_all(&update.priv_orig);
ast_set_party_id_all(&update.priv_from);
ast_set_party_id_all(&update.priv_to);
- ast_channel_queue_redirecting_update(session->channel, &data, update);
+ ast_channel_set_redirecting(session->channel, &data, &update); /* ast_channel_queue_redirecting_update */
ast_party_redirecting_free(&data);
}
static int diversion_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
{
/* check if diversion header is present, if so update channel's redirecting info */
- pjsip_fromto_hdr *hdr = get_diversion_header(rdata);
+ pjsip_fromto_hdr *div_hdr = get_diversion_header(rdata);
- if (!hdr) {
- return -1;
+ if (div_hdr) {
+ set_redirecting(session, (pjsip_name_addr*)div_hdr->uri,
+ (pjsip_name_addr*)rdata->msg_info.msg->line.req.uri);
}
return 0;
@@ -171,42 +209,86 @@
{
/* check if diversion header is present, if so update channel's redirecting info */
/* if 3xx and not present then update channel redirect info */
- if (!session->channel) {
+ struct pjsip_status_line status = rdata->msg_info.msg->line.status;
+ pjsip_fromto_hdr *div_hdr;
+
+ if (status.code != 302 || (!(div_hdr = get_diversion_header(rdata)))) {
return;
}
+
+ set_redirecting(session, (pjsip_name_addr*)div_hdr->uri,
+ (pjsip_name_addr*)PJSIP_MSG_TO_HDR(rdata->msg_info.msg)->uri);
+}
+
+static pjsip_fromto_hdr *create_hdr(pjsip_tx_data *tdata, const pj_str_t *hdr_name)
+{
+ pjsip_fromto_hdr *hdr;
+
+ /* if request base off 'msg line' otherwise use 'from' (e.g. response) */
+ pjsip_uri *base = tdata->msg->type == PJSIP_REQUEST_MSG ?
+ tdata->msg->line.req.uri : PJSIP_MSG_FROM_HDR(tdata->msg)->uri;
+
+ hdr = pjsip_from_hdr_create(tdata->pool);
+ hdr->type = PJSIP_H_OTHER;
+ pj_strdup(tdata->pool, &hdr->name, hdr_name);
+ hdr->sname.slen = 0;
+ hdr->uri = pjsip_uri_clone(tdata->pool, base);
+
+ return hdr;
+}
+
+#define param_add(pool,list,pname,pvalue) \
+ do { \
+ pjsip_param *param; \
+ param = PJ_POOL_ALLOC_T(pool, pjsip_param); \
+ param->name = pj_str(pname); \
+ param->value = pj_str(pvalue); \
+ pj_list_insert_before(&list, param); \
+ } while (0)
+
+static pjsip_fromto_hdr *update_hdr(pjsip_tx_data *tdata, pjsip_fromto_hdr *hdr,
+ struct ast_party_redirecting *data)
+{
+ pjsip_name_addr *name_addr = (pjsip_name_addr*)hdr;
+ pjsip_sip_uri *uri = pjsip_uri_get_uri(name_addr->uri);
+
+ struct ast_party_id *id = tdata->msg->type == PJSIP_REQUEST_MSG ?
+ &data->to : &data->from;
+
+ if (!id->number.valid || ast_strlen_zero(id->number.str)) {
+ return hdr;
+ }
+
+ pj_strdup2(tdata->pool, &name_addr->display, id->name.str);
+ pj_strdup2(tdata->pool, &uri->user, id->number.str);
+
+ param_add(tdata->pool, uri->other_param, "reason",
+ (char*)reason_code_to_str(&data->reason));
+
+ return hdr;
}
/*!
* \internal
* \brief Adds diversion header information to an outbound SIP message
*
- * \param session The session on which we will be sending the message
* \param tdata The outbound message
- */
-static void add_diversion_header(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
-{
- struct ast_str *buf = ast_str_alloca(DIV_HDR_MAX_SIZE);
- const char *reason, *contact, *domain;
- struct ast_party_id from = ast_channel_redirecting_effective_from(session->channel);
-
- if (!from.number.valid || ast_strlen_zero(from.number.str)) {
- return;
- }
-
- if (from.name.valid && !ast_strlen_zero(from.name.str)) {
- ast_str_set(&buf, ast_str_size(buf), "\"%s\"", from.name.str);
- }
-
- contact = ast_sip_location_retrieve_contact_from_aor_list(session->endpoint->aors)->uri;
- if ((domain = strchr(contact, '@'))) {
- ++domain;
- }
-
- reason = reason_code_to_str(&ast_channel_redirecting(session->channel)->reason);
- ast_str_append(&buf, ast_str_size(buf) - ast_str_strlen(buf), "<sip:%s@%s>;reason=%s",
- from.number.str, domain ? domain : contact, reason);
-
- ast_sip_add_header(tdata, "Diversion", ast_str_buffer(buf));
+ * \param data The redirecting data used to fill parts of the diversion header
+ */
+static void add_diversion_header(pjsip_tx_data *tdata, struct ast_party_redirecting *data)
+{
+ pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)update_hdr(tdata,
+ create_hdr(tdata, &diversion_name), data));
+}
+
+static void get_redirecting_add_diversion(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+ struct ast_party_redirecting *data;
+
+ if (session->channel &&
+ (data = ast_channel_redirecting(session->channel))->count) {
+ add_diversion_header(tdata, data);
+ }
}
/*!
@@ -219,12 +301,7 @@
*/
static void diversion_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
{
- struct ast_party_redirecting *data;
-
- if (session->channel &&
- (data = ast_channel_redirecting(session->channel))->count) {
- add_diversion_header(session, tdata, data);
- }
+ get_redirecting_add_diversion(session, tdata);
}
/*!
@@ -237,13 +314,10 @@
static void diversion_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
{
struct pjsip_status_line status = tdata->msg->line.status;
- struct ast_party_redirecting *data;
/* add to 302 and 181 */
- if (((status.code >= 300) && (status.code < 400) ||
- (status.code == 181)) && session->channel &&
- (data = ast_channel_redirecting(session->channel))->count)) {
- add_diversion_header(session, tdata, data);
+ if (((status.code >= 300) && (status.code < 400)) || (status.code == 181)) {
+ get_redirecting_add_diversion(session, tdata);
}
}
More information about the asterisk-commits
mailing list