[asterisk-commits] rizzo: branch rizzo/astobj2 r72802 - /team/rizzo/astobj2/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Jun 30 17:41:31 CDT 2007
Author: rizzo
Date: Sat Jun 30 17:41:31 2007
New Revision: 72802
URL: http://svn.digium.com/view/asterisk?view=rev&rev=72802
Log:
merge from trunk svn 63613
Modified:
team/rizzo/astobj2/channels/chan_sip.c
Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=72802&r1=72801&r2=72802
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Sat Jun 30 17:41:31 2007
@@ -1634,6 +1634,7 @@
static const char *__get_header(const struct sip_request *req, const char *name, int *start);
static int lws2sws(char *msgbuf, int len);
static void extract_uri(struct sip_pvt *p, struct sip_request *req);
+static char *remove_uri_parameters(char *uri);
static int get_refer_info(struct sip_pvt *transferer, struct sip_request *outgoing_req);
static int get_also_info(struct sip_pvt *p, struct sip_request *oreq);
static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req);
@@ -2706,10 +2707,11 @@
return tmp;
}
-/*!
- * parses a URI in its components.
- * If scheme is specified, drop it from the top.
- * If a component is not requested, do not split around it.
+/*! \brief * parses a URI in its components.
+ *
+ * \note
+ *- If scheme is specified, drop it from the top.
+ * - If a component is not requested, do not split around it.
* This means that if we don't have domain, we cannot split
* name:pass and domain:port.
* It is safe to call with ret_name, pass, domain, port
@@ -2717,6 +2719,7 @@
* Init pointers to empty string so we never get NULL dereferencing.
* Overwrites the string.
* return 0 on success, other values on error.
+ * general form we are expecting is sip[s]:username[:password][;parameter]@host[:port][;...]
*/
static int parse_uri(char *uri, char *scheme,
char **ret_name, char **pass, char **domain, char **port, char **options)
@@ -2729,13 +2732,12 @@
*pass = "";
if (port)
*port = "";
- name = strsep(&uri, ";"); /* remove options */
if (scheme) {
int l = strlen(scheme);
- if (!strncmp(name, scheme, l))
- name += l;
+ if (!strncmp(uri, scheme, l))
+ uri += l;
else {
- ast_log(LOG_NOTICE, "Missing scheme '%s' in '%s'\n", scheme, name);
+ ast_log(LOG_NOTICE, "Missing scheme '%s' in '%s'\n", scheme, uri);
error = -1;
}
}
@@ -2749,14 +2751,20 @@
*/
char *c, *dom = "";
- if ((c = strchr(name, '@')) == NULL) {
+ if ((c = strchr(uri, '@')) == NULL) {
/* domain-only URI, according to the SIP RFC. */
- dom = name;
+ dom = uri;
name = "";
} else {
*c++ = '\0';
dom = c;
- }
+ name = uri;
+ }
+
+ /* Remove options in domain and name */
+ dom = strsep(&dom, ";");
+ name = strsep(&name, ";");
+
if (port && (c = strchr(dom, ':'))) { /* Remove :port */
*c++ = '\0';
*port = c;
@@ -4543,6 +4551,12 @@
pbx_builtin_setvar_helper(tmp,v->name,v->value);
append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
+
+ /* Inform manager user about new channel and their SIP call ID */
+ if (global_callevents)
+ manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
+ "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n",
+ tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact);
return tmp;
}
@@ -6312,7 +6326,7 @@
int debug=sip_debug_test_pvt(p);
/* Parse uri to h (host) and port - uri is already just the part inside the <> */
- /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */
+ /* general form we are expecting is sip[s]:username[:password][;parameter]@host[:port][;...] */
if (debug)
ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
@@ -6493,7 +6507,7 @@
ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"),
sizeof(stripped));
n = get_in_brackets(stripped);
- c = strsep(&n, ";"); /* trim ; and beyond */
+ c = remove_uri_parameters(n);
}
init_req(req, sipmethod, c);
@@ -7423,6 +7437,19 @@
return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
}
+/* \brief Remove URI parameters at end of URI, not in username part though */
+static char *remove_uri_parameters(char *uri) /* XXX simplify if possible with strsep */
+{
+ char *atsign;
+ atsign = strchr(uri, '@'); /* First, locate the at sign */
+ if (!atsign)
+ atsign = uri; /* Ok hostname only, let's stick with the rest */
+ atsign = strchr(atsign, ';'); /* Locate semi colon */
+ if (atsign)
+ *atsign = '\0'; /* Kill at the semi colon */
+ return uri;
+}
+
/*! \brief Check Contact: URI of SIP message */
static void extract_uri(struct sip_pvt *p, struct sip_request *req)
{
@@ -7431,7 +7458,8 @@
ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
c = get_in_brackets(stripped);
- c = strsep(&c, ";"); /* trim ; and beyond */
+ /* Cut the URI at the at sign after the @, not in the username part */
+ c = remove_uri_parameters(c);
if (!ast_strlen_zero(c))
ast_string_field_set(p, uri, c);
}
@@ -7819,11 +7847,14 @@
/* Check which device/devices we are watching and if they are registered */
if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
- /* If they are not registered, we will override notification and show no availability */
- if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
- local_state = NOTIFY_CLOSED;
- pidfstate = "away";
- pidfnote = "Not online";
+ char *hint2 = hint, *individual_hint = NULL;
+ while ((individual_hint = strsep(&hint2, "&"))) {
+ /* If they are not registered, we will override notification and show no availability */
+ if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) {
+ local_state = NOTIFY_CLOSED;
+ pidfstate = "away";
+ pidfnote = "Not online";
+ }
}
}
@@ -7833,7 +7864,8 @@
ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
return -1;
}
- mfrom = strsep(&c, ";"); /* trim ; and beyond */
+
+ mfrom = remove_uri_parameters(c);
ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
c = get_in_brackets(to);
@@ -7841,7 +7873,7 @@
ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
return -1;
}
- mto = strsep(&c, ";"); /* trim ; and beyond */
+ mto = remove_uri_parameters(c);
reqprep(&req, p, SIP_NOTIFY, 0, 1);
@@ -8586,6 +8618,7 @@
ast_sched_del(sched, peer->expire);
peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
register_peer_exten(peer, TRUE);
+ ast_device_state_changed("SIP/%s", peer->name);
}
/*! \brief Save contact header for 200 OK on INVITE */
@@ -9193,7 +9226,7 @@
ast_uri_decode(tmp);
c = get_in_brackets(tmp);
- c = strsep(&c, ";"); /* Ditch ;user=phone */
+ c = remove_uri_parameters(c);
if (!strncmp(c, "sip:", 4)) {
name = c + 4;
@@ -9218,6 +9251,9 @@
}
}
}
+ c = strchr(name, ';'); /* Remove any Username parameters */
+ if (c)
+ *c = '\0';
ast_string_field_set(p, exten, name);
build_contact(p);
@@ -12074,8 +12110,57 @@
ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
transmit_response(p, "200 OK", req);
} else {
- transmit_response(p, "403 Unauthorized", req);
- }
+ transmit_response(p, "403 Forbidden", req);
+ }
+ return;
+ } else if (!ast_strlen_zero(c = get_header(req, "Record"))) {
+ /* INFO messages generated by some phones to start/stop recording
+ on phone calls.
+ OEJ: I think this should be something that is enabled/disabled
+ per device. I don't want incoming callers to record calls in my
+ pbx.
+ */
+ /* first, get the feature string, if it exists */
+ struct ast_call_feature *feat;
+ int j;
+ struct ast_frame f = { AST_FRAME_DTMF, };
+
+ ast_rdlock_call_features();
+ feat = ast_find_call_feature("automon");
+ if (!feat || ast_strlen_zero(feat->exten)) {
+ ast_log(LOG_WARNING,"Recording requested, but no One Touch Monitor registered. (See features.conf)\n");
+ /* 403 means that we don't support this feature, so don't request it again */
+ transmit_response(p, "403 Forbidden", req);
+ ast_unlock_call_features();
+ return;
+ }
+ /* OEJ: Why is the DTMF code included in the record section? */
+ f.len = 100;
+ for (j=0; j<strlen(feat->exten); j++) {
+ f.subclass = feat->exten[j];
+ ast_queue_frame(p->owner, &f);
+ if (sipdebug)
+ ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
+ }
+ ast_unlock_call_features();
+#ifdef DISABLED_CODE
+ /* And feat isn't used here - Is this code tested at all???
+ We just send a reply ...
+ */
+ if (strcasecmp(c, "on")== 0) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Got a Request to Record the channel!\n");
+
+ transmit_response(p, "200 OK", req);
+ return;
+ } else if (strcasecmp(c, "off")== 0) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Got a Request to Stop Recording the channel\n");
+ transmit_response(p, "200 OK", req);
+ return;
+ }
+#endif
+ transmit_response(p, "200 OK", req);
return;
}
/* Other type of INFO message, not really understood by Asterisk */
@@ -12770,8 +12855,8 @@
char *domain;
ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
- s = get_in_brackets(tmp);
- s = strsep(&s, ";"); /* strip ; and beyond */
+ /* s = get_in_brackets(tmp); */ /* XXX why removed ? */
+ s = remove_uri_parameters(get_in_brackets(tmp));
if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
if (!strncasecmp(s, "sip:", 4))
s += 4;
@@ -12791,11 +12876,14 @@
/* No username part */
domain = tmp;
}
- e = strchr(tmp, '/');
+ e = strchr(tmp, '/'); /* WHEN do we hae a forward slash in the URI? */
if (e)
*e = '\0';
if (!strncasecmp(s, "sip:", 4))
s += 4;
+ e = strchr(s, ';'); /* And username ; parameters? */
+ if (e)
+ *e = '\0';
if (option_debug > 1)
ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
if (p->owner) {
@@ -13000,6 +13088,10 @@
if (!req_ignore(req) && p->owner) {
if (!reinvite) {
ast_queue_control(p->owner, AST_CONTROL_ANSWER);
+ if (global_callevents)
+ manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
+ "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
+ p->owner->name, p->owner->uniqueid, "SIP", p->callid, p->fullcontact, p->peername);
} else { /* RE-invite */
ast_queue_frame(p->owner, &ast_null_frame);
}
@@ -14924,8 +15016,7 @@
}
/* Respond to normal re-invite */
if (sendok)
- transmit_response_with_sdp(p, "200 OK", req, XMIT_CRITICAL);
-
+ transmit_response_with_sdp(p, "200 OK", req, ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL);
}
p->invitestate = INV_TERMINATED;
break;
@@ -14997,7 +15088,6 @@
transferer->refer->status = REFER_FAILED;
sip_pvt_unlock(targetcall_pvt);
ast_channel_unlock(current->chan1);
- ast_channel_unlock(targetcall_pvt->owner);
return -1;
}
@@ -16809,6 +16899,10 @@
p->jointcapability = oldformat;
sip_pvt_lock(p);
tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */
+ if (global_callevents)
+ manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
+ "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
+ p->owner? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername);
/* XXX who keeps the reference ? */
sip_pvt_unlock(p);
if (!tmpc)
@@ -17892,6 +17986,7 @@
if (ast_true(hassip) || (!hassip && genhassip)) {
peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
if (peer) {
+ ast_device_state_changed("SIP/%s", peer->name);
ASTOBJ_CONTAINER_LINK(&peerl,peer);
unref_peer(peer);
peer_count++;
@@ -18695,6 +18790,7 @@
/*! \brief PBX load module - initialization */
static int load_module(void)
{
+ ast_verbose("SIP channel loading...\n");
ASTOBJ_CONTAINER_INIT(&userl); /* User object list */
ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */
ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */
More information about the asterisk-commits
mailing list