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);
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];
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,
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';
- }
- }
- }
- }
+ channel = switch_core_session_get_channel(session);
- 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;
- }
+ 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");
- attach_private(session, profile, tech_pvt, username);
- tech_set_codecs(tech_pvt);
+ 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);
- }
-
- 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) {
+ 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 (profile->context && !strcasecmp(profile->context, "_domain_")) {
+ context = from_host;
+ } else {
+ context = profile->context;
+ }
+
+ 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);
+
+ if (tech_pvt->caller_profile) {
- 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);
- }
-
- } 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);
- }
- }
+ /* 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;
}
}
}
- }
+ }
- 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,