[asterisk-commits] oej: branch oej/codename-pineapple r47237 - in
/team/oej/codename-pineapple/c...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Nov 6 15:56:41 MST 2006
Author: oej
Date: Mon Nov 6 16:56:40 2006
New Revision: 47237
URL: http://svn.digium.com/view/asterisk?rev=47237&view=rev
Log:
More cleanups, movements, documentation
Modified:
team/oej/codename-pineapple/channels/chan_sip3.c
team/oej/codename-pineapple/channels/sip3/sip3.h
team/oej/codename-pineapple/channels/sip3/sip3_compose.c
team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
team/oej/codename-pineapple/channels/sip3/sip3_network.c
team/oej/codename-pineapple/channels/sip3/sip3_parse.c
team/oej/codename-pineapple/channels/sip3/sip3funcs.h
Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?rev=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Mon Nov 6 16:56:40 2006
@@ -119,7 +119,7 @@
- \subpage chan_sip3_auth
- \subpage chan_sip3_dialogs
- \subpage chan_sip3_overview
-
+ - \subpage sip3_dialog_match
\par todo Things to do, ideas
- \subpage chan_sip3_todo
- \subpage chan_sip3_subs
@@ -467,7 +467,6 @@
static int transmit_refer(struct sip_dialog *p, const char *dest);
static int transmit_notify_with_mwi(struct sip_dialog *p, int newmsgs, int oldmsgs, char *vmexten);
static void receive_message(struct sip_dialog *p, struct sip_request *req);
-static void parse_moved_contact(struct sip_dialog *p, struct sip_request *req);
static int sip_send_mwi_to_peer(struct sip_peer *peer);
static int does_peer_need_mwi(struct sip_peer *peer);
@@ -506,19 +505,7 @@
static void sip_poke_all_peers(void);
/*--- Applications, functions, CLI and manager command helpers */
-//static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions);
-//static int sip_show_channels(int fd, int argc, char *argv[]);
-//static int sip_show_subscriptions(int fd, int argc, char *argv[]);
-//static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions);
-//static int sip_show_channel(int fd, int argc, char *argv[]);
-//static int sip_show_history(int fd, int argc, char *argv[]);
-//static int sip_do_debug_ip(int fd, int argc, char *argv[]);
-//static int sip_do_debug_peer(int fd, int argc, char *argv[]);
-//static int sip_do_debug(int fd, int argc, char *argv[]);
-//static int sip_no_debug(int fd, int argc, char *argv[]);
GNURK int sip_notify(int fd, int argc, char *argv[]);
-//static int sip_do_history(int fd, int argc, char *argv[]);
-//static int sip_no_history(int fd, int argc, char *argv[]);
static int func_header_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len);
static int function_sippeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
static int function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
@@ -556,7 +543,6 @@
static int get_msg_text(char *buf, int len, struct sip_request *req);
/*--- Constructing requests and responses */
-static void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod);
static int create_addr_from_peer(struct sip_dialog *r, struct sip_peer *peer);
static int add_vidupdate(struct sip_request *req);
static void build_rpid(struct sip_dialog *p);
@@ -2455,135 +2441,6 @@
fromdomain, p->tag);
}
-/*! \brief Initiate new SIP request to peer/user */
-static void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod)
-{
- char invite_buf[256] = "";
- char *invite = invite_buf;
- size_t invite_max = sizeof(invite_buf);
- char from[256];
- char to[256];
- char tmp[BUFSIZ/2];
- char tmp2[BUFSIZ/2];
- const char *l = NULL, *n = NULL;
- const char *urioptions = "";
-
- if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
- const char *s = p->username; /* being a string field, cannot be NULL */
-
- /* Test p->username against allowed characters in AST_DIGIT_ANY
- If it matches the allowed characters list, then sipuser = ";user=phone"
- If not, then sipuser = ""
- */
- /* + is allowed in first position in a tel: uri */
- if (*s == '+')
- s++;
- for (; *s; s++) {
- if (!strchr(AST_DIGIT_ANYNUM, *s) )
- break;
- }
- /* If we have only digits, add ;user=phone to the uri */
- if (*s)
- urioptions = ";user=phone";
- }
-
-
- snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_method2txt(sipmethod));
-
- if (p->owner) {
- l = p->owner->cid.cid_num;
- n = p->owner->cid.cid_name;
- }
- /* if we are not sending RPID and user wants his callerid restricted */
- if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
- ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
- l = CALLERID_UNKNOWN;
- n = l;
- }
- if (ast_strlen_zero(l))
- l = global.default_callerid;
- if (ast_strlen_zero(n))
- n = l;
- /* Allow user to be overridden */
- if (!ast_strlen_zero(p->fromuser))
- l = p->fromuser;
- else /* Save for any further attempts */
- ast_string_field_set(p, fromuser, l);
-
- /* Allow user to be overridden */
- if (!ast_strlen_zero(p->fromname))
- n = p->fromname;
- else /* Save for any further attempts */
- ast_string_field_set(p, fromname, n);
-
- ast_uri_encode(n, tmp, sizeof(tmp), 0);
- n = tmp;
- ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
- l = tmp2;
-
- if ((sipnet_ourport() != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */
- snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), sipnet_ourport(), p->tag);
- else
- snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
-
- /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
- if (!ast_strlen_zero(p->fullcontact)) {
- /* If we have full contact, trust it */
- ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
- } else {
- /* Otherwise, use the defaultuser while waiting for registration */
- ast_build_string(&invite, &invite_max, "sip:");
- if (!ast_strlen_zero(p->defaultuser)) {
- n = p->defaultuser;
- ast_uri_encode(n, tmp, sizeof(tmp), 0);
- n = tmp;
- ast_build_string(&invite, &invite_max, "%s@", n);
- }
- ast_build_string(&invite, &invite_max, "%s", p->tohost);
- if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) /* Needs to be 5060 */
- ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
- ast_build_string(&invite, &invite_max, "%s", urioptions);
- }
-
- /* If custom URI options have been provided, append them */
- if (p->options && p->options->uri_options)
- ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
-
- ast_string_field_set(p, uri, invite_buf);
-
- if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) {
- /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
- snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
- } else if (p->options && p->options->vxml_url) {
- /* If there is a VXML URL append it to the SIP URL */
- snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
- } else
- snprintf(to, sizeof(to), "<%s>", p->uri);
-
- init_req(req, sipmethod, p->uri);
- snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_method2txt(sipmethod));
-
- 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 */
- /* Build Remote Party-ID and From */
- if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
- build_rpid(p);
- add_header(req, "From", p->rpid_from);
- } else
- add_header(req, "From", from);
- add_header(req, "To", to);
- ast_string_field_set(p, exten, l);
- build_contact(p);
- add_header(req, "Contact", p->our_contact);
- add_header(req, "Call-ID", p->callid);
- add_header(req, "CSeq", tmp);
- add_header(req, "User-Agent", global.useragent);
- add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
- if (!ast_strlen_zero(p->rpid))
- add_header(req, "Remote-Party-ID", p->rpid);
-}
-
/*! \brief Build REFER/INVITE/OPTIONS message and transmit it */
GNURK int transmit_invite(struct sip_dialog *p, int sipmethod, int sdp, int init)
{
@@ -2593,12 +2450,12 @@
if (init) { /* Seems like init always is 2 */
/* Bump branch even on initial requests */
build_via(p, TRUE);
- if (init > 1)
+ if (init > 1) /* open a new dialog */
initreqprep(&req, p, sipmethod);
else
- reqprep(&req, p, sipmethod, 0, 1);
+ reqprep(&req, p, sipmethod, 0, TRUE);
} else
- reqprep(&req, p, sipmethod, 0, 1);
+ reqprep(&req, p, sipmethod, 0, TRUE);
if (p->options && p->options->auth)
add_header(&req, p->options->authheader, p->options->auth);
@@ -2765,7 +2622,7 @@
}
mto = strsep(&c, ";"); /* trim ; and beyond */
- reqprep(&req, p, SIP_NOTIFY, 0, 1);
+ reqprep(&req, p, SIP_NOTIFY, 0, TRUE);
add_header(&req, "Event", subscriptiontype->event);
@@ -2894,7 +2751,7 @@
struct sip_request req;
char tmp[BUFSIZ/2];
- reqprep(&req, p, SIP_NOTIFY, 0, 1);
+ reqprep(&req, p, SIP_NOTIFY, 0, TRUE);
snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
add_header(&req, "Event", tmp);
add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
@@ -2917,7 +2774,7 @@
{
struct sip_request req;
- reqprep(&req, p, SIP_MESSAGE, 0, 1);
+ reqprep(&req, p, SIP_MESSAGE, 0, TRUE);
add_text(&req, text);
return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
}
@@ -2976,7 +2833,7 @@
ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
p->refer->status = REFER_SENT; /* Set refer status */
- reqprep(&req, p, SIP_REFER, 0, 1);
+ reqprep(&req, p, SIP_REFER, 0, TRUE);
add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
add_header(&req, "Refer-To", referto);
@@ -3002,7 +2859,7 @@
{
struct sip_request req;
- reqprep(&req, p, SIP_INFO, 0, 1);
+ reqprep(&req, p, SIP_INFO, 0, TRUE);
add_digit(&req, digit);
return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
}
@@ -3012,7 +2869,7 @@
{
struct sip_request req;
- reqprep(&req, p, SIP_INFO, 0, 1);
+ reqprep(&req, p, SIP_INFO, 0, TRUE);
add_vidupdate(&req);
return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
}
@@ -4818,7 +4675,7 @@
static struct ast_custom_function sip_header_function = {
.name = "SIP_HEADER",
- .synopsis = "Gets the specified SIP header",
+ .synopsis = "Gets the specified SIP header from the INVITE",
.syntax = "SIP_HEADER(<name>[,<number>])",
.desc = "Since there are several headers (such as Via) which can occur multiple\n"
"times, SIP_HEADER takes an optional second argument to specify which header with\n"
@@ -4985,48 +4842,6 @@
"- t38passthrough 1 if T38 is offered or enabled in this channel, otherwise 0\n"
};
-/*! \brief Parse 302 Moved temporalily response */
-static void parse_moved_contact(struct sip_dialog *p, struct sip_request *req)
-{
- char tmp[256];
- char *s, *e;
- char *domain;
-
- ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
- s = get_in_brackets(tmp);
- s = strsep(&s, ";"); /* strip ; and beyond */
- if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
- if (!strncasecmp(s, "sip:", 4))
- s += 4;
- e = strchr(s, '/');
- if (e)
- *e = '\0';
- if (option_debug)
- ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
- if (p->owner)
- ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
- } else {
- e = strchr(tmp, '@');
- if (e) {
- *e++ = '\0';
- domain = e;
- } else {
- /* No username part */
- domain = tmp;
- }
- e = strchr(tmp, '/');
- if (e)
- *e = '\0';
- if (!strncasecmp(s, "sip:", 4))
- s += 4;
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
- if (p->owner) {
- pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
- ast_string_field_set(p->owner, call_forward, s);
- }
- }
-}
/*! \brief Check pending actions on SIP call */
static void check_pendings(struct sip_dialog *p)
@@ -5231,6 +5046,17 @@
ast_set_flag(&p->flags[0], SIP_CAN_BYE);
check_pendings(p);
break;
+ case 300: /* Multiple Choices */
+ case 301: /* Moved permenantly */
+ case 302: /* Moved temporarily */
+ case 305: /* Use Proxy */
+ transmit_request(p, SIP_ACK, req->seqno, XMIT_UNRELIABLE, FALSE);
+ ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ stop_media_flows(p); /* Stop RTP, VRTP and UDPTL */
+ parse_moved_contact(p, req);
+ if (p->owner)
+ ast_queue_control(p->owner, AST_CONTROL_BUSY);
+ break;
case 407: /* Proxy authentication */
case 401: /* Www auth */
/* First we ACK */
@@ -5279,12 +5105,24 @@
/* we have to wait a while, then retransmit */
/* Transmission is rescheduled, so everything should be taken care of.
We should support the retry-after at some point */
+ /*! \todo fix 491 pending support */
break;
+ case 488: /* Not acceptable here - codec error */
case 501: /* Not implemented */
transmit_request(p, SIP_ACK, req->seqno, XMIT_UNRELIABLE, FALSE);
dialogstatechange(p, DIALOG_STATE_TERMINATED);
if (p->owner)
ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+ break;
+ case 486: /* Busy here */
+ case 600: /* Busy everywhere */
+ case 603: /* Decline */
+ dialogstatechange(p, DIALOG_STATE_TERMINATED);
+ transmit_request(p, SIP_ACK, req->seqno, XMIT_UNRELIABLE, FALSE);
+ ast_set_flag(&p->flags[0], SIP_ALREADYGONE);
+ stop_media_flows(p); /* Stop RTP, VRTP and UDPTL */
+ if (p->owner)
+ ast_queue_control(p->owner, AST_CONTROL_BUSY);
break;
}
}
@@ -5575,6 +5413,9 @@
if (sipmethod == SIP_REFER) {
handle_response_refer(p, resp, rest, req);
break;
+ } else if (sipmethod == SIP_INVITE) {
+ handle_response_invite(p, resp, rest, req);
+ break;
}
/* Fallthrough */
default:
@@ -5590,13 +5431,10 @@
case 301: /* Moved permenantly */
case 302: /* Moved temporarily */
case 305: /* Use Proxy */
- parse_moved_contact(p, req);
- /* Fall through */
case 486: /* Busy here */
case 600: /* Busy everywhere */
- case 603: /* Decline */
- if (p->owner)
- ast_queue_control(p->owner, AST_CONTROL_BUSY);
+ if (sipmethod == SIP_INVITE)
+ handle_response_invite(p, resp, rest, req);
break;
case 487: /* Response on INVITE that has been CANCELled */
/* channel now destroyed - dec the inUse counter */
@@ -5604,6 +5442,11 @@
ast_queue_hangup(p->owner);
update_call_counter(p, DEC_CALL_LIMIT);
break;
+ case 488: /* Not acceptable here - codec error */
+ if (sipmethod == SIP_INVITE) {
+ handle_response_invite(p, resp, rest, req);
+ break;
+ }
case 482: /*
\note SIP is incapable of performing a hairpin call, which
is yet another failure of not having a layer 2 (again, YAY
@@ -5615,7 +5458,6 @@
ast_string_field_build(p->owner, call_forward,
"Local/%s@%s", p->peername, p->context);
/* Fall through */
- case 488: /* Not acceptable here - codec error */
case 480: /* Temporarily Unavailable */
case 404: /* Not Found */
case 410: /* Gone */
Modified: team/oej/codename-pineapple/channels/sip3/sip3.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3.h?rev=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3.h Mon Nov 6 16:56:40 2006
@@ -187,7 +187,11 @@
TRANSFER_CLOSED, /*!< Allow no SIP transfers */
};
-
+typedef enum {
+ AST_FALSE = 0,
+ AST_TRUE = 1,
+ AST_HAVENOCLUEANDDONOTCARE = -1,
+} sip_boolean;
enum sip_result {
AST_SUCCESS = 0,
Modified: team/oej/codename-pineapple/channels/sip3/sip3_compose.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_compose.c?rev=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_compose.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_compose.c Mon Nov 6 16:56:40 2006
@@ -132,6 +132,85 @@
return 0;
}
+/*! \brief Build the Remote Party-ID & From using callingpres options */
+static void build_rpid(struct sip_dialog *p)
+{
+ int send_pres_tags = TRUE;
+ const char *privacy=NULL;
+ const char *screen=NULL;
+ char buf[256];
+ const char *clid = global.default_callerid;
+ const char *clin = NULL;
+ const char *fromdomain;
+
+ if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))
+ return;
+
+ if (p->owner && p->owner->cid.cid_num)
+ clid = p->owner->cid.cid_num;
+ if (p->owner && p->owner->cid.cid_name)
+ clin = p->owner->cid.cid_name;
+ if (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 = "pass";
+ break;
+ case AST_PRES_NUMBER_NOT_AVAILABLE:
+ send_pres_tags = FALSE;
+ 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 = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
+
+ 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);
+ ast_string_field_set(p, rpid, buf);
+
+ ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
+ S_OR(p->fromuser, clid),
+ fromdomain, p->tag);
+}
+
/*! \brief Prepare SIP response packet */
int respprep(struct sip_request *resp, struct sip_dialog *p, const char *msg, const struct sip_request *req)
{
@@ -305,6 +384,135 @@
p->sa.sin_port = htons(port);
if (debug)
ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
+}
+
+/*! \brief Initiate new SIP request to peer/user */
+void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod)
+{
+ char invite_buf[256] = "";
+ char *invite = invite_buf;
+ size_t invite_max = sizeof(invite_buf);
+ char from[256];
+ char to[256];
+ char tmp[BUFSIZ/2];
+ char tmp2[BUFSIZ/2];
+ const char *l = NULL, *n = NULL;
+ const char *urioptions = "";
+
+ if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
+ const char *s = p->username; /* being a string field, cannot be NULL */
+
+ /* Test p->username against allowed characters in AST_DIGIT_ANY
+ If it matches the allowed characters list, then sipuser = ";user=phone"
+ If not, then sipuser = ""
+ */
+ /* + is allowed in first position in a tel: uri */
+ if (*s == '+')
+ s++;
+ for (; *s; s++) {
+ if (!strchr(AST_DIGIT_ANYNUM, *s) )
+ break;
+ }
+ /* If we have only digits, add ;user=phone to the uri */
+ if (*s)
+ urioptions = ";user=phone";
+ }
+
+
+ snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_method2txt(sipmethod));
+
+ if (p->owner) {
+ l = p->owner->cid.cid_num;
+ n = p->owner->cid.cid_name;
+ }
+ /* if we are not sending RPID and user wants his callerid restricted */
+ if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
+ ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
+ l = CALLERID_UNKNOWN;
+ n = l;
+ }
+ if (ast_strlen_zero(l))
+ l = global.default_callerid;
+ if (ast_strlen_zero(n))
+ n = l;
+ /* Allow user to be overridden */
+ if (!ast_strlen_zero(p->fromuser))
+ l = p->fromuser;
+ else /* Save for any further attempts */
+ ast_string_field_set(p, fromuser, l);
+
+ /* Allow user to be overridden */
+ if (!ast_strlen_zero(p->fromname))
+ n = p->fromname;
+ else /* Save for any further attempts */
+ ast_string_field_set(p, fromname, n);
+
+ ast_uri_encode(n, tmp, sizeof(tmp), 0);
+ n = tmp;
+ ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
+ l = tmp2;
+
+ if ((sipnet_ourport() != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain)) /* Needs to be 5060 */
+ snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), sipnet_ourport(), p->tag);
+ else
+ snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
+
+ /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
+ if (!ast_strlen_zero(p->fullcontact)) {
+ /* If we have full contact, trust it */
+ ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
+ } else {
+ /* Otherwise, use the defaultuser while waiting for registration */
+ ast_build_string(&invite, &invite_max, "sip:");
+ if (!ast_strlen_zero(p->defaultuser)) {
+ n = p->defaultuser;
+ ast_uri_encode(n, tmp, sizeof(tmp), 0);
+ n = tmp;
+ ast_build_string(&invite, &invite_max, "%s@", n);
+ }
+ ast_build_string(&invite, &invite_max, "%s", p->tohost);
+ if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) /* Needs to be 5060 */
+ ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
+ ast_build_string(&invite, &invite_max, "%s", urioptions);
+ }
+
+ /* If custom URI options have been provided, append them */
+ if (p->options && p->options->uri_options)
+ ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
+
+ ast_string_field_set(p, uri, invite_buf);
+
+ if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) {
+ /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
+ snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
+ } else if (p->options && p->options->vxml_url) {
+ /* If there is a VXML URL append it to the SIP URL */
+ snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
+ } else
+ snprintf(to, sizeof(to), "<%s>", p->uri);
+
+ init_req(req, sipmethod, p->uri);
+ snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_method2txt(sipmethod));
+
+ 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 */
+ /* Build Remote Party-ID and From */
+ if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
+ build_rpid(p);
+ add_header(req, "From", p->rpid_from);
+ } else
+ add_header(req, "From", from);
+ add_header(req, "To", to);
+ ast_string_field_set(p, exten, l);
+ build_contact(p);
+ add_header(req, "Contact", p->our_contact);
+ add_header(req, "Call-ID", p->callid);
+ add_header(req, "CSeq", tmp);
+ add_header(req, "User-Agent", global.useragent);
+ add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
+ if (!ast_strlen_zero(p->rpid))
+ add_header(req, "Remote-Party-ID", p->rpid);
}
Modified: team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_dialog.c?rev=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_dialog.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_dialog.c Mon Nov 6 16:56:40 2006
@@ -439,6 +439,9 @@
}
/*! \brief Convert SIP hangup causes to Asterisk hangup causes */
+/* \page SIP_isdn2sip Conversion from ISDN to SIP codes
+ - see function \ref hangup_sip2cause()
+*/
int hangup_sip2cause(int cause)
{
/* Possible values taken from causes.h */
@@ -520,6 +523,7 @@
}
/*! \brief Convert Asterisk hangup causes to SIP codes
+\page SIP_isdn2sip Conversion from ISDN to SIP codes
\verbatim
Possible values from causes.h
AST_CAUSE_NOTDEFINED AST_CAUSE_NORMAL AST_CAUSE_BUSY
@@ -550,6 +554,7 @@
29 facility rejected 501 Not implemented
31 normal unspecified 480 Temporarily unavailable
\endverbatim
+Also see \ref SIP_sip2isdn
*/
const char *hangup_cause2sip(int cause)
{
@@ -807,6 +812,7 @@
/*! \brief Connect incoming SIP message to current dialog or create new dialog structure
\note Called by handle_request, sipsock_read
+ \page sip3_dialog_match chan_sip3:: Dialog matching and scenarios
\title Dialog matching
SIP can be forked, so we need to separate dialogs from each other in a
@@ -970,6 +976,7 @@
For requests, we might be getting a statelessly forked call to us.
*/
if (!ast_strlen_zero(cur->remotebranch) && strcmp(cur->remotebranch, branch)) {
+ /* XXX What do we do here ? */
}
}
Modified: team/oej/codename-pineapple/channels/sip3/sip3_network.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_network.c?rev=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_network.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_network.c Mon Nov 6 16:56:40 2006
@@ -249,6 +249,8 @@
setsockopt(sipnet.sipsock, SOL_SOCKET, SO_REUSEADDR,
(const char*)&reuseFlag,
sizeof reuseFlag);
+
+ ast_enable_packet_fragmentation(sipnet.sipsock);
if (bind(sipnet.sipsock, (struct sockaddr *)&sipnet.bindaddr, sizeof(sipnet.bindaddr)) < 0) {
ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
Modified: team/oej/codename-pineapple/channels/sip3/sip3_parse.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_parse.c?rev=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_parse.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_parse.c Mon Nov 6 16:56:40 2006
@@ -636,3 +636,46 @@
ast_string_field_set(p, uri, c);
}
+/*! \brief Parse 302 Moved temporalily response */
+void parse_moved_contact(struct sip_dialog *p, struct sip_request *req)
+{
+ char tmp[256];
+ char *s, *e;
+ char *domain;
+
+ ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
+ s = get_in_brackets(tmp);
+ s = strsep(&s, ";"); /* strip ; and beyond */
+ if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
+ if (!strncasecmp(s, "sip:", 4))
+ s += 4;
+ e = strchr(s, '/');
+ if (e)
+ *e = '\0';
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
+ if (p->owner)
+ ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
+ } else {
+ e = strchr(tmp, '@');
+ if (e) {
+ *e++ = '\0';
+ domain = e;
+ } else {
+ /* No username part */
+ domain = tmp;
+ }
+ e = strchr(tmp, '/');
+ if (e)
+ *e = '\0';
+ if (!strncasecmp(s, "sip:", 4))
+ s += 4;
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
+ if (p->owner) {
+ pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
+ ast_string_field_set(p->owner, call_forward, s);
+ }
+ }
+}
+
Modified: team/oej/codename-pineapple/channels/sip3/sip3funcs.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3funcs.h?rev=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3funcs.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3funcs.h Mon Nov 6 16:56:40 2006
@@ -131,6 +131,7 @@
GNURK const char *gettag(const char *header, char *tagbuf, int tagbufsize);
GNURK int determine_firstline_parts(struct sip_request *req);
GNURK void extract_uri(struct sip_dialog *p, struct sip_request *req);
+GNURK void parse_moved_contact(struct sip_dialog *p, struct sip_request *req);
/*! sip3_compose.c : Composing new SIP messages */
GNURK void build_callid_pvt(struct sip_dialog *pvt);
@@ -141,6 +142,7 @@
GNURK void add_route(struct sip_request *req, struct sip_route *route);
GNURK int add_line(struct sip_request *req, const char *line);
GNURK int add_header_contentLength(struct sip_request *req, int len);
+GNURK void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod);
GNURK int reqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod, int seqno, int newbranch);
/*! sip3_domain.c: Domain handling functions (sip domain hosting, not DNS lookups) */
More information about the asterisk-commits
mailing list