[Freeswitch-svn] [commit] r4388 - freeswitch/trunk/src/mod/endpoints/mod_sofia
Freeswitch SVN
mikej at freeswitch.org
Sun Feb 25 11:53:18 EST 2007
Author: mikej
Date: Sun Feb 25 11:53:17 2007
New Revision: 4388
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
Log:
refactor of sip_i_invite. Much more error handling of different missing data on the inbound invite. Some minor changes in behavior. Chanvars are now not set for vars we don't have. the channel name will now include :port (the full uri as we create it from the data available), display name is now unknown not service if there is not one available. Added contact uri as a chan var like all the others, the channel name if there is no user portion of the from will not have a from part of service, it will have no user part or @. The contact will now be used for the channel name if there is no from header in the invite.
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Sun Feb 25 11:53:17 2007
@@ -358,7 +358,7 @@
static void attach_private(switch_core_session_t *session,
sofia_profile_t *profile,
private_object_t *tech_pvt,
- char *channame);
+ const char *channame);
static void terminate_session(switch_core_session_t **session, switch_call_cause_t cause, int line);
@@ -843,7 +843,7 @@
static void attach_private(switch_core_session_t *session,
sofia_profile_t *profile,
private_object_t *tech_pvt,
- char *channame)
+ const char *channame)
{
switch_channel_t *channel;
char name[256];
@@ -4231,6 +4231,88 @@
return;
}
+
+#define url_set_chanvars(session, url, varprefix) _url_set_chanvars(session, url, #varprefix "_user", #varprefix "_host", #varprefix "_port", #varprefix "_uri")
+static const char * _url_set_chanvars(switch_core_session_t *session, url_t *url, const char * user_var, const char * host_var, const char * port_var, const char * uri_var)
+{
+ const char *user = NULL, *host = NULL, *port = NULL;
+ char *uri = NULL;
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+
+ if (url) {
+ user = url->url_user;
+ host = url->url_host;
+ port = url->url_port;
+ }
+
+ if (user) {
+ switch_channel_set_variable(channel, user_var, user);
+ }
+
+ if (!port) {
+ port = "5060";
+ }
+
+ switch_channel_set_variable(channel, port_var, port);
+ if (host) {
+ if (user) {
+ uri = switch_core_session_sprintf(session, "%s@%s:%s", user, host, port);
+ } else {
+ uri = switch_core_session_sprintf(session, "%s:%s", host, port);
+ }
+ switch_channel_set_variable_nodup(channel, uri_var, uri);
+ switch_channel_set_variable(channel, host_var, host);
+ }
+
+ return uri;
+}
+
+static void process_rpid(sip_unknown_t *un, private_object_t *tech_pvt)
+{
+ int argc, x, screen = 1;
+ char *mydata, *argv[10] = { 0 };
+ if (!switch_strlen_zero(un->un_value)) {
+ if ((mydata = strdup(un->un_value))) {
+ argc = switch_separate_string(mydata, ';', argv, (sizeof(argv) / sizeof(argv[0])));
+
+ // Do We really need this at this time
+ // clid_uri = argv[0];
+
+ for (x=1; x < argc && argv[x]; x++){
+ // we dont need to do anything with party yet we should only be seeing party=calling here anyway
+ // maybe thats a dangerous assumption bit oh well yell at me later
+ // if (!strncasecmp(argv[x], "party", 5)) {
+ // party = argv[x];
+ // } else
+ if (!strncasecmp(argv[x], "privacy=", 8)) {
+ char *arg = argv[x] + 9;
+
+ if (!strcasecmp(arg, "yes")) {
+ switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
+ } else if (!strcasecmp(arg, "full")) {
+ switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
+ } else if (!strcasecmp(arg, "name")) {
+ switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
+ } else if (!strcasecmp(arg, "number")) {
+ switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
+ } else {
+ switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
+ switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
+ }
+
+ } else if (!strncasecmp(argv[x], "screen=", 7) && screen > 0) {
+ char *arg = argv[x] + 8;
+ if (!strcasecmp(arg, "no")) {
+ screen = 0;
+ switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN);
+ }
+ }
+ }
+ free(mydata);
+ }
+ }
+}
+
static void sip_i_invite(nua_t *nua,
sofia_profile_t *profile,
nua_handle_t *nh,
@@ -4241,266 +4323,166 @@
switch_core_session_t *session = NULL;
char key[128] = "";
sip_unknown_t *un;
- private_object_t *tech_pvt = NULL;
- switch_channel_t *channel = NULL;
- sip_from_t const *from = sip->sip_from;
- sip_to_t const *to = sip->sip_to;
- char *displayname;
- char *username, *req_username = NULL;
- char *url_user = (char *) from->a_url->url_user;
- char *to_user, *to_host, *to_port;
- char *req_user, *req_host, *req_port;
- char *contact_user, *contact_host, *contact_port;
- char *via_rport, *via_host, *via_port;
- char *from_port;
- char uri[1024];
+ private_object_t *tech_pvt = NULL;
+ switch_channel_t *channel = NULL;
+ const char *channel_name = NULL;
+ const char *displayname = NULL;
+ const char *destination_number = NULL;
+ const char *from_user = NULL, *from_host = NULL;
+ const char *context;
char network_ip[80];
+ if (!sip) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received an invite callback with no packet!\n");
+ nua_respond(nh, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
+ return;
+ }
- if (!(sip && sip->sip_contact && sip->sip_contact->m_url)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT!\n");
+ if (!(sip->sip_contact && sip->sip_contact->m_url)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT!\n");
nua_respond(nh, 400, "Missing Contact Header", TAG_END());
- return;
- }
+ return;
+ }
- if ((profile->pflags & PFLAG_AUTH_CALLS)) {
- if (handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key))) {
- return;
- }
- }
+ if ((profile->pflags & PFLAG_AUTH_CALLS)) {
+ if (handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key))) {
+ return;
+ }
+ }
- if (!(session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session Alloc Failed!\n");
+ if (!(session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Session Alloc Failed!\n");
nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, TAG_END());
return;
- }
+ }
- if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
- terminate_session(&session, SWITCH_CAUSE_SWITCH_CONGESTION, __LINE__);
- return;
- }
+ if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
+ terminate_session(&session, SWITCH_CAUSE_SWITCH_CONGESTION, __LINE__);
+ return;
+ }
- if (!switch_strlen_zero(key)) {
- tech_pvt->key = switch_core_session_strdup(session, key);
- }
+ if (!switch_strlen_zero(key)) {
+ tech_pvt->key = switch_core_session_strdup(session, key);
+ }
get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *)msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_addr);
-
- to_user = (char *) to->a_url->url_user;
- to_host = (char *) to->a_url->url_host;
- if (!(to_port = (char *) to->a_url->url_port)) {
- to_port = "5060";
- }
-
- if (switch_strlen_zero(to_user)) { /* if sofia doesnt parse the To: right, we'll have to do it */
- if ((to_user = sip_header_as_string(tech_pvt->home, (sip_header_t *) to))) {
- char *p;
- if (*to_user == '<') {
- to_user++;
- }
- if ((p = strchr((to_user += 4), '@'))) {
- *p++ = '\0';
- to_host = p;
- if ((p = strchr(to_host, '>'))) {
- *p = '\0';
- }
- }
- }
- }
-
- if (switch_strlen_zero(url_user)) {
- url_user = "service";
- }
-
- if (!switch_strlen_zero(from->a_display)) {
- displayname = switch_core_session_strdup(session, (char *) from->a_display);
- if (*displayname == '"') {
- char *p;
-
- displayname++;
- if ((p = strchr(displayname, '"'))) {
- *p = '\0';
- }
- }
- } else {
- displayname = url_user;
- }
-
- if (!(username = switch_mprintf("%s@%s", url_user, (char *) from->a_url->url_host))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- return;
- }
+ channel = switch_core_session_get_channel(session);
- attach_private(session, profile, tech_pvt, username);
- tech_set_codecs(tech_pvt);
+ if (sip->sip_from && sip->sip_from->a_url) {
+ from_user = sip->sip_from->a_url->url_user;
+ from_host = sip->sip_from->a_url->url_host;
+ channel_name = url_set_chanvars(session, sip->sip_from->a_url, "sip_from");
+
+ if (!switch_strlen_zero(from_user)) {
+ if (*from_user == '+') {
+ switch_channel_set_variable(channel, "sip_from_user_stripped", (const char *)(from_user+1));
+ } else {
+ switch_channel_set_variable(channel, "sip_from_user_stripped", from_user);
+ }
+ }
- channel = switch_core_session_get_channel(session);
- switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
- set_chat_hash(tech_pvt, sip);
+ if (!switch_strlen_zero(sip->sip_from->a_display)) {
+ char *tmp;
+ tmp = switch_core_session_strdup(session, sip->sip_from->a_display);
+ if (*tmp == '"') {
+ char *p;
- if (switch_test_flag(tech_pvt, TFLAG_INB_NOMEDIA)) {
- switch_set_flag_locked(tech_pvt, TFLAG_NOMEDIA);
- switch_channel_set_flag(channel, CF_NOMEDIA);
- }
+ tmp++;
+ if ((p = strchr(tmp, '"'))) {
+ *p = '\0';
+ }
+ }
+ displayname = tmp;
+ } else {
+ displayname = switch_strlen_zero(from_user) ? "unkonwn" : from_user;
+ }
+ }
-
- switch_channel_set_variable(channel, "sip_from_user", from->a_url->url_user);
- if (from->a_url->url_user && *from->a_url->url_user == '+') {
- switch_channel_set_variable(channel, "sip_from_user_stripped", (char *)(from->a_url->url_user+1));
- } else {
- switch_channel_set_variable(channel, "sip_from_user_stripped", from->a_url->url_user);
- }
- switch_channel_set_variable(channel, "sip_from_host", from->a_url->url_host);
+ if (sip->sip_request && sip->sip_request->rq_url) {
+ const char * req_uri = url_set_chanvars(session, sip->sip_request->rq_url, "sip_req");
+ if (profile->pflags & PFLAG_FULL_ID) {
+ destination_number = req_uri;
+ } else {
+ destination_number = sip->sip_request->rq_url->url_user;
+ }
+ }
-
- if (!(from_port = (char *) from->a_url->url_port)) {
- from_port = "5060";
- }
+ if (sip->sip_to && sip->sip_to->a_url) {
+ url_set_chanvars(session, sip->sip_to->a_url, "sip_to");
+ }
- switch_channel_set_variable(channel, "sip_from_port", from_port);
+ if (sip->sip_contact && sip->sip_contact->m_url) {
+ const char *contact_uri = url_set_chanvars(session, sip->sip_contact->m_url, "sip_contact");
+ if (!channel_name) {
+ channel_name = contact_uri;
+ }
+ }
+ attach_private(session, profile, tech_pvt, channel_name);
+ tech_set_codecs(tech_pvt);
- snprintf(uri, sizeof(uri), "%s@%s:%s", from->a_url->url_user, from->a_url->url_host, from_port);
- switch_channel_set_variable(channel, "sip_from_uri", uri);
-
-
- switch_channel_set_variable(channel, "sip_to_user", to_user);
- switch_channel_set_variable(channel, "sip_to_host", to_host);
- switch_channel_set_variable(channel, "sip_to_port", to_port);
+ switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
+ set_chat_hash(tech_pvt, sip);
- snprintf(uri, sizeof(uri), "%s@%s:%s", to_user, to_host, to_port);
- switch_channel_set_variable(channel, "sip_to_uri", uri);
+ if (switch_test_flag(tech_pvt, TFLAG_INB_NOMEDIA)) {
+ switch_set_flag_locked(tech_pvt, TFLAG_NOMEDIA);
+ switch_channel_set_flag(channel, CF_NOMEDIA);
+ }
+ if (!tech_pvt->call_id && sip->sip_call_id && sip->sip_call_id->i_id) {
+ tech_pvt->call_id = switch_core_session_strdup(session, sip->sip_call_id->i_id);
+ switch_channel_set_variable(channel, "sip_call_id", tech_pvt->call_id);
+ }
- req_user = (char *) sip->sip_request->rq_url->url_user;
- req_host = (char *) sip->sip_request->rq_url->url_host;
- if (!(req_port = (char *) sip->sip_request->rq_url->url_port)) {
- req_port = "5060";
- }
-
- switch_channel_set_variable(channel, "sip_req_user", req_user);
- switch_channel_set_variable(channel, "sip_req_host", req_host);
- switch_channel_set_variable(channel, "sip_req_port", req_port);
-
- if (profile->pflags & PFLAG_FULL_ID) {
- if (req_user) {
- if (!(req_username = switch_mprintf("%s@%s:%s", req_user, req_host, req_port))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- switch_safe_free(username);
- return;
- }
- } else {
- if (!(req_username = switch_mprintf("%s:%s", req_host, req_port))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- switch_safe_free(username);
- return;
- }
+ if (sip->sip_via) {
+ if (sip->sip_via->v_host) {
+ switch_channel_set_variable(channel, "sip_via_host", sip->sip_via->v_host);
}
- }
-
- contact_user = (char *) sip->sip_contact->m_url->url_user;
- contact_host = (char *) sip->sip_contact->m_url->url_host;
- if (!(contact_port = (char *) sip->sip_contact->m_url->url_port)) {
- contact_port = "5060";
- }
-
- switch_channel_set_variable(channel, "sip_contact_user", contact_user);
- switch_channel_set_variable(channel, "sip_contact_host", contact_host);
- switch_channel_set_variable(channel, "sip_contact_port", contact_port);
-
- if (!tech_pvt->call_id && sip && sip->sip_call_id && sip->sip_call_id->i_id) {
- tech_pvt->call_id = switch_core_session_strdup(session, sip->sip_call_id->i_id);
- switch_channel_set_variable(channel, "sip_call_id", tech_pvt->call_id);
- }
-
- via_host = (char *) sip->sip_via->v_host;
- if (!(via_port = (char *) sip->sip_via->v_port)) {
- via_port = "5060";
- }
- if (!(via_rport = (char *) sip->sip_via->v_rport)) {
- via_rport = "5060";
- }
-
- switch_channel_set_variable(channel, "sip_via_host", via_host);
- switch_channel_set_variable(channel, "sip_via_port", via_port);
- switch_channel_set_variable(channel, "sip_via_rport", via_rport);
-
-
- snprintf(uri, sizeof(uri), "%s@%s:%s", req_user, req_host, req_port);
- switch_channel_set_variable(channel, "sip_req_uri", uri);
+ if (sip->sip_via->v_port) {
+ switch_channel_set_variable(channel, "sip_via_port", sip->sip_via->v_port);
+ }
+ if (sip->sip_via->v_rport) {
+ switch_channel_set_variable(channel, "sip_via_rport", sip->sip_via->v_rport);
+ }
+ }
if (sip->sip_max_forwards) {
- snprintf(uri, sizeof(uri), "%u", sip->sip_max_forwards->mf_count);
- switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, uri);
+ char max_forwards[32];
+ snprintf(max_forwards, sizeof(max_forwards), "%u", sip->sip_max_forwards->mf_count);
+ switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards);
}
- if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
- (char *) from->a_url->url_user,
- profile->dialplan,
- displayname,
- (char *) from->a_url->url_user,
- network_ip,
- NULL,
- NULL,
- NULL,
- (char *)modname,
- (profile->context && !strcasecmp(profile->context, "_domain_")) ?
- (char *) from->a_url->url_host : profile->context,
- req_username ? req_username : req_user ? (char *) req_user : ""
- )) != 0) {
+ if (profile->context && !strcasecmp(profile->context, "_domain_")) {
+ context = from_host;
+ } else {
+ context = profile->context;
+ }
-
- for (un=sip->sip_unknown; un; un=un->un_next) {
- if (!strncasecmp(un->un_name, "Alert-Info", 10)) {
- if (!switch_strlen_zero(un->un_value)) {
- switch_channel_set_variable(channel, "alert_info", (char *)un->un_value);
- }
- // Loop thru Known Headers Here so we can do something with them
- } else if (!strncasecmp(un->un_name, "Remote-Party-ID", 15)) {
- int argc, x, screen = 1;
- char *mydata, *argv[10] = { 0 };
- if (!switch_strlen_zero(un->un_value)) {
- if ((mydata = strdup(un->un_value))) {
- argc = switch_separate_string(mydata, ';', argv, (sizeof(argv) / sizeof(argv[0])));
-
- // Do We really need this at this time
- // clid_uri = argv[0];
-
- for (x=1; x < argc && argv[x]; x++){
- // we dont need to do anything with party yet we should only be seeing party=calling here anyway
- // maybe thats a dangerous assumption bit oh well yell at me later
- // if (!strncasecmp(argv[x], "party", 5)) {
- // party = argv[x];
- // } else
- if (!strncasecmp(argv[x], "privacy=", 8)) {
- char *arg = argv[x] + 9;
-
- if (!strcasecmp(arg, "yes")) {
- switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
- } else if (!strcasecmp(arg, "full")) {
- switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
- } else if (!strcasecmp(arg, "name")) {
- switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
- } else if (!strcasecmp(arg, "number")) {
- switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
- } else {
- switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
- switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
- }
+ tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
+ from_user,
+ profile->dialplan,
+ displayname,
+ from_user,
+ network_ip,
+ NULL,
+ NULL,
+ NULL,
+ modname,
+ context,
+ destination_number);
- } else if (!strncasecmp(argv[x], "screen=", 7) && screen > 0) {
- char *arg = argv[x] + 8;
- if (!strcasecmp(arg, "no")) {
- screen = 0;
- switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN);
- }
- }
- }
- free(mydata);
- }
- }
+ if (tech_pvt->caller_profile) {
+
+ /* Loop thru unknown Headers Here so we can do something with them */
+ for (un=sip->sip_unknown; un; un=un->un_next) {
+ if (!strncasecmp(un->un_name, "Alert-Info", 10)) {
+ if (!switch_strlen_zero(un->un_value)) {
+ switch_channel_set_variable(channel, "alert_info", un->un_value);
+ }
+ } else if (!strncasecmp(un->un_name, "Remote-Party-ID", 15)) {
+ process_rpid(un, tech_pvt);
} else if (!strncasecmp(un->un_name, "X-", 2)) {
if (!switch_strlen_zero(un->un_value)) {
char *new_name;
@@ -4510,20 +4492,18 @@
}
}
}
- }
+ }
- switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
- switch_safe_free(username);
- switch_safe_free(req_username);
- }
+ switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
+ }
- if (!(tech_pvt->sofia_private = malloc(sizeof(*tech_pvt->sofia_private)))) {
- abort();
- }
- memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
- switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
- nua_handle_bind(nh, tech_pvt->sofia_private);
- tech_pvt->nh = nh;
+ if (!(tech_pvt->sofia_private = malloc(sizeof(*tech_pvt->sofia_private)))) {
+ abort();
+ }
+ memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
+ switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
+ nua_handle_bind(nh, tech_pvt->sofia_private);
+ tech_pvt->nh = nh;
}
static void sip_i_register(nua_t *nua,
More information about the Freeswitch-svn
mailing list