experimental multiple registrations
in sofia conf <param name="multiple-registrations" value="true"/> in dialplan <action application="bridge" data="$sofia_contact(mysofia_profile_name/user@regtodomain.com)"/> or <action application="bridge" data="$sofia_contact(mysofia_profile_name_same_as_regto_domain.com/user)"/> or <action application="bridge" data="$sofia_contact(user@mysofia_profile_name_same_as_regto_domain.com)"/> git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5956 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
89472232ec
commit
7c93a4e4eb
|
@ -54,6 +54,7 @@
|
|||
<param name="sip-ip" value="$${local_ip_v4}"/>
|
||||
<!--enable to use presense and mwi -->
|
||||
<param name="manage-presence" value="true"/>
|
||||
<!--<param name="multiple-registrations" value="true"/>-->
|
||||
<!--set to 'greedy' if you want your codec list to take precedence -->
|
||||
<param name="inbound-codec-negotiation" value="generous"/>
|
||||
<!-- if you want to send any special bind params of your own -->
|
||||
|
|
|
@ -1248,6 +1248,96 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int contact_callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||
{
|
||||
struct cb_helper *cb = (struct cb_helper *) pArg;
|
||||
char *contact;
|
||||
|
||||
if (!switch_strlen_zero(argv[0]) && (contact = sofia_glue_get_url_from_contact(argv[0], 1))) {
|
||||
cb->stream->write_function(cb->stream, "sofia/%s/%s,", cb->profile->name, contact + 4);
|
||||
free(contact);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(sofia_contact_function)
|
||||
{
|
||||
char *data;
|
||||
char *user = NULL;
|
||||
char *domain = NULL;
|
||||
char *profile_name = NULL;
|
||||
char *p;
|
||||
|
||||
if (!cmd) {
|
||||
stream->write_function(stream, "%s", "");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
data = strdup(cmd);
|
||||
assert(data);
|
||||
|
||||
if ((p = strchr(data, '/'))) {
|
||||
profile_name = data;
|
||||
*p++ = '\0';
|
||||
user = p;
|
||||
} else {
|
||||
user = data;
|
||||
}
|
||||
|
||||
if ((domain = strchr(user, '@'))) {
|
||||
*domain++ = '\0';
|
||||
}
|
||||
|
||||
if (!profile_name && domain) {
|
||||
profile_name = domain;
|
||||
}
|
||||
|
||||
if (user && profile_name) {
|
||||
char *sql;
|
||||
sofia_profile_t *profile;
|
||||
|
||||
if (!(profile = sofia_glue_find_profile(profile_name))) {
|
||||
profile_name = domain;
|
||||
domain = NULL;
|
||||
}
|
||||
|
||||
if (!profile && profile_name) {
|
||||
profile = sofia_glue_find_profile(profile_name);
|
||||
}
|
||||
|
||||
if (profile) {
|
||||
struct cb_helper cb;
|
||||
switch_stream_handle_t mystream = { 0 };
|
||||
if (!domain || !strchr(domain, '.')) {
|
||||
domain = profile->name;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_STREAM(mystream);
|
||||
cb.profile = profile;
|
||||
cb.stream = &mystream;
|
||||
|
||||
sql = switch_mprintf("select contact from sip_registrations where user='%q' and host='%q'", user, domain);
|
||||
assert(sql);
|
||||
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE, profile->ireg_mutex, sql, contact_callback, &cb);
|
||||
switch_safe_free(sql);
|
||||
if (mystream.data) {
|
||||
char *str = mystream.data;
|
||||
*(str + (strlen(str) - 1)) = '\0';
|
||||
}
|
||||
stream->write_function(stream, "%s", mystream.data);
|
||||
switch_safe_free(mystream.data);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
stream->write_function(stream, "%s", "");
|
||||
end:
|
||||
|
||||
switch_safe_free(data);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(sofia_function)
|
||||
{
|
||||
char *argv[1024] = { 0 };
|
||||
|
@ -1589,6 +1679,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
|||
management_interface->management_function = sofia_manage;
|
||||
|
||||
SWITCH_ADD_API(api_interface, "sofia", "Sofia Controls", sofia_function, "<cmd> <args>");
|
||||
SWITCH_ADD_API(api_interface, "sofia_contact", "Sofia Contacts", sofia_contact_function, "[profile/]<user>@<domain>");
|
||||
SWITCH_ADD_CHAT(chat_interface, SOFIA_CHAT_PROTO, sofia_presence_chat_send);
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
|
|
|
@ -112,7 +112,8 @@ typedef enum {
|
|||
PFLAG_REWRITE_TIMESTAMPS = (1 << 7),
|
||||
PFLAG_RUNNING = (1 << 8),
|
||||
PFLAG_RESPAWN = (1 << 9),
|
||||
PFLAG_GREEDY = (1 << 10)
|
||||
PFLAG_GREEDY = (1 << 10),
|
||||
PFLAG_MULTIREG = (1 << 11)
|
||||
} PFLAGS;
|
||||
|
||||
|
||||
|
|
|
@ -260,7 +260,8 @@ void event_handler(switch_event_t *event)
|
|||
long expires = (long) time(NULL) + atol(exp_str);
|
||||
char *profile_name = switch_event_get_header(event, "orig-profile-name");
|
||||
sofia_profile_t *profile = NULL;
|
||||
char buf[512];
|
||||
char *icontact = NULL, *p;
|
||||
|
||||
|
||||
if (!rpid) {
|
||||
rpid = "unknown";
|
||||
|
@ -270,26 +271,33 @@ void event_handler(switch_event_t *event)
|
|||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!sofia_reg_find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
|
||||
sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Regestered', '%q', %ld)",
|
||||
from_user, from_host, contact_str, rpid, expires);
|
||||
if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
|
||||
icontact = sofia_glue_get_url_from_contact(contact_str, 1);
|
||||
|
||||
if ((p = strchr(icontact, ';'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q' and contact like '%%%q%%'", from_user, from_host, icontact);
|
||||
switch_safe_free(icontact);
|
||||
} else {
|
||||
sql =
|
||||
switch_mprintf
|
||||
("update sip_registrations set contact='%q', rpid='%q', expires=%ld where user='%q' and host='%q'",
|
||||
contact_str, rpid, expires, from_user, from_host);
|
||||
|
||||
sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q'", from_user, from_host);
|
||||
}
|
||||
|
||||
switch_mutex_lock(profile->ireg_mutex);
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Regestered', '%q', %ld)",
|
||||
from_user, from_host, contact_str, rpid, expires);
|
||||
|
||||
if (sql) {
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
sql = NULL;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s\n", from_user, from_host, contact_str);
|
||||
|
||||
}
|
||||
switch_mutex_unlock(profile->ireg_mutex);
|
||||
|
||||
|
||||
if (profile) {
|
||||
sofia_glue_release_profile(profile);
|
||||
|
@ -844,6 +852,10 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
|||
if (switch_true(val)) {
|
||||
profile->pflags |= PFLAG_PRESENCE;
|
||||
}
|
||||
} else if (!strcasecmp(var, "multiple-registrations")) {
|
||||
if (switch_true(val)) {
|
||||
profile->pflags |= PFLAG_MULTIREG;
|
||||
}
|
||||
} else if (!strcasecmp(var, "NDLB-to-in-200-contact")) {
|
||||
if (switch_true(val)) {
|
||||
profile->ndlb |= PFLAG_NDLB_TO_IN_200_CONTACT;
|
||||
|
|
|
@ -329,7 +329,7 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
|
|||
const char *to_user = NULL;
|
||||
const char *to_host = NULL;
|
||||
char contact_str[1024] = "";
|
||||
char buf[512];
|
||||
//char buf[512];
|
||||
uint8_t stale = 0, forbidden = 0;
|
||||
auth_res_t auth_res;
|
||||
long exptime = 60;
|
||||
|
@ -461,16 +461,32 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
|
|||
}
|
||||
|
||||
if (exptime) {
|
||||
if (!sofia_reg_find_reg_url(profile, to_user, to_host, buf, sizeof(buf))) {
|
||||
sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','%q', '%q', %ld)",
|
||||
to_user, to_host, contact_str, cd ? "Registered(NATHACK)" : "Registered", rpid, (long) time(NULL) + (long) exptime * 2);
|
||||
|
||||
if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
|
||||
char *icontact, *p;
|
||||
icontact = sofia_glue_get_url_from_contact(contact_str, 1);
|
||||
if ((p = strchr(icontact, ';'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q' and contact like '%%%q%%'", to_user, to_host, icontact);
|
||||
switch_safe_free(icontact);
|
||||
} else {
|
||||
sql =
|
||||
switch_mprintf
|
||||
("update sip_registrations set contact='%q', expires=%ld, rpid='%q' where user='%q' and host='%q'",
|
||||
contact_str, (long) time(NULL) + (long) exptime * 2, rpid, to_user, to_host);
|
||||
|
||||
sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q'", to_user, to_host);
|
||||
}
|
||||
switch_mutex_lock(profile->ireg_mutex);
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','%q', '%q', %ld)",
|
||||
to_user, to_host, contact_str, cd ? "Registered(NATHACK)" : "Registered", rpid, (long) time(NULL) + (long) exptime * 2);
|
||||
|
||||
|
||||
if (sql) {
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
sql = NULL;
|
||||
}
|
||||
switch_mutex_unlock(profile->ireg_mutex);
|
||||
|
||||
if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
|
||||
|
@ -482,11 +498,7 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
|
|||
switch_event_fire(&s_event);
|
||||
}
|
||||
|
||||
if (sql) {
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
|
||||
switch_safe_free(sql);
|
||||
sql = NULL;
|
||||
}
|
||||
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
"Register:\nFrom: [%s@%s]\nContact: [%s]\nExpires: [%ld]\n", to_user, to_host, contact_str, (long) exptime);
|
||||
|
@ -503,15 +515,36 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
|
|||
switch_event_fire(&event);
|
||||
}
|
||||
} else {
|
||||
if ((sql = switch_mprintf("delete from sip_subscriptions where user='%q' and host='%q'", to_user, to_host))) {
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
|
||||
switch_safe_free(sql);
|
||||
sql = NULL;
|
||||
}
|
||||
if ((sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q'", to_user, to_host))) {
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
|
||||
switch_safe_free(sql);
|
||||
sql = NULL;
|
||||
if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
|
||||
char *icontact, *p;
|
||||
icontact = sofia_glue_get_url_from_contact(contact_str, 1);
|
||||
if ((p = strchr(icontact, ';'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
if ((sql = switch_mprintf("delete from sip_subscriptions where user='%q' and host='%q' and contact like '%%%q%%'", to_user, to_host, icontact))) {
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
|
||||
switch_safe_free(sql);
|
||||
sql = NULL;
|
||||
}
|
||||
|
||||
if ((sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q' and contact like '%%%q%%'", to_user, to_host, icontact))) {
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
|
||||
switch_safe_free(sql);
|
||||
sql = NULL;
|
||||
}
|
||||
switch_safe_free(icontact);
|
||||
} else {
|
||||
if ((sql = switch_mprintf("delete from sip_subscriptions where user='%q' and host='%q'", to_user, to_host))) {
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
|
||||
switch_safe_free(sql);
|
||||
sql = NULL;
|
||||
}
|
||||
|
||||
if ((sql = switch_mprintf("delete from sip_registrations where user='%q' and host='%q'", to_user, to_host))) {
|
||||
sofia_glue_execute_sql(profile, SWITCH_FALSE, sql, profile->ireg_mutex);
|
||||
switch_safe_free(sql);
|
||||
sql = NULL;
|
||||
}
|
||||
}
|
||||
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
|
||||
|
|
Loading…
Reference in New Issue