提交 8d716e6a authored 作者: Anthony Minessale's avatar Anthony Minessale

break everything in sofia as you know it but add in/out reg + auth, look in the…

break everything in sofia as you know it but add in/out reg + auth, look in the default config for the new syntax

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2875 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 82d79185
...@@ -111,7 +111,21 @@ ...@@ -111,7 +111,21 @@
</mappings> </mappings>
</configuration> </configuration>
<configuration name="sofia.conf" description="sofia Endpoint"> <configuration name="sofia.conf" description="sofia Endpoint">
<profiles>
<profile name="test"> <profile name="test">
<registrations>
<registration name="asterlink">
<param name="register-scheme" value="Digest"/>
<param name="register-realm" value=""/>
<param name="register-username" value="1001"/>
<param name="register-password" value="nhy65tgb"/>
<param name="register-from" value="sip:1001@208.64.200.40"/>
<param name="register-to" value="sip:1001@66.250.68.194"/>
<param name="register-proxy" value="sip:66.250.68.194:5060"/>
<param name="register-frequency" value="20"/>
</registration>
</registrations>
<settings>
<param name="debug" value="1"/> <param name="debug" value="1"/>
<param name="rfc2833-pt" value="101"/> <param name="rfc2833-pt" value="101"/>
<param name="sip-port" value="5060"/> <param name="sip-port" value="5060"/>
...@@ -129,7 +143,7 @@ ...@@ -129,7 +143,7 @@
<param name="accept-blind-reg" value="true"/> <param name="accept-blind-reg" value="true"/>
<!--<param name="auth-calls" value="true"/>--> <!--<param name="auth-calls" value="true"/>-->
<!-- on authed calls, authenticate *all* the packets not just invite ---> <!-- on authed calls, authenticate *all* the packets not just invite -->
<!--<param name="auth-all-packets" value="true"/>--> <!--<param name="auth-all-packets" value="true"/>-->
<!-- optional ; --> <!-- optional ; -->
...@@ -140,7 +154,9 @@ ...@@ -140,7 +154,9 @@
<!-- <param name="vad" value="out"/> --> <!-- <param name="vad" value="out"/> -->
<!-- <param name="vad" value="both"/> --> <!-- <param name="vad" value="both"/> -->
<!--<param name="alias" value="sip:10.0.1.251:5555"/>--> <!--<param name="alias" value="sip:10.0.1.251:5555"/>-->
</settings>
</profile> </profile>
</profiles>
</configuration> </configuration>
<configuration name="syslog.conf" description="Syslog Logger"> <configuration name="syslog.conf" description="Syslog Logger">
<!-- SYSLOG --> <!-- SYSLOG -->
...@@ -447,9 +463,9 @@ ...@@ -447,9 +463,9 @@
so any call info acquired after the various actions cannot so any call info acquired after the various actions cannot
be taken into consideration. be taken into consideration.
The first match will play a beep and the second one plays The first match will play a beep and the second one plays
the desired file. This is for demo purposes both actions the desired file. This is for demo purposes both actions
could have been under the same <extension> tag as well. could have been under the same <extension> tag as well.
--> -->
<extension name="playsound1" continue="true"> <extension name="playsound1" continue="true">
<condition field="source" expression="mod_exosip"/> <condition field="source" expression="mod_exosip"/>
......
...@@ -39,13 +39,23 @@ ...@@ -39,13 +39,23 @@
#define HAVE_APR #define HAVE_APR
#include <switch.h> #include <switch.h>
struct outbound_reg;
typedef struct outbound_reg outbound_reg_t;
struct sofia_profile; struct sofia_profile;
typedef struct sofia_profile sofia_profile_t; typedef struct sofia_profile sofia_profile_t;
#define NUA_MAGIC_T sofia_profile_t #define NUA_MAGIC_T sofia_profile_t
struct sofia_private {
switch_core_session_t *session;
outbound_reg_t *oreg;
};
typedef struct sofia_private sofia_private_t;
struct private_object; struct private_object;
typedef struct private_object private_object_t; typedef struct private_object private_object_t;
#define NUA_HMAGIC_T switch_core_session_t #define NUA_HMAGIC_T sofia_private_t
#define MY_EVENT_REGISTER "sofia::register" #define MY_EVENT_REGISTER "sofia::register"
#define MY_EVENT_EXPIRE "sofia::expire" #define MY_EVENT_EXPIRE "sofia::expire"
...@@ -77,10 +87,6 @@ static char auth_sql[] = ...@@ -77,10 +87,6 @@ static char auth_sql[] =
" expires INTEGER(8)" " expires INTEGER(8)"
");\n"; ");\n";
static const char modname[] = "mod_sofia"; static const char modname[] = "mod_sofia";
#define STRLEN 15 #define STRLEN 15
...@@ -133,6 +139,41 @@ static struct { ...@@ -133,6 +139,41 @@ static struct {
switch_mutex_t *mutex; switch_mutex_t *mutex;
} globals; } globals;
typedef enum {
REG_FLAG_AUTHED = (1 << 0),
} reg_flags_t;
typedef enum {
REG_STATE_UNREGED,
REG_STATE_TRYING,
REG_STATE_REGISTER,
REG_STATE_REGED,
REG_STATE_FAILED,
REG_STATE_EXPIRED
} reg_state_t;
struct outbound_reg {
sofia_private_t sofia_private;
nua_handle_t *nh;
sofia_profile_t *profile;
char *name;
char *register_scheme;
char *register_realm;
char *register_username;
char *register_password;
char *register_from;
char *register_to;
char *register_proxy;
char *expires_str;
uint32_t freq;
time_t expires;
time_t retry;
uint32_t flags;
reg_state_t state;
switch_memory_pool_t *pool;
struct outbound_reg *next;
};
struct sofia_profile { struct sofia_profile {
int debug; int debug;
char *name; char *name;
...@@ -163,12 +204,14 @@ struct sofia_profile { ...@@ -163,12 +204,14 @@ struct sofia_profile {
sip_alias_node_t *aliases; sip_alias_node_t *aliases;
switch_payload_t te; switch_payload_t te;
uint32_t codec_flags; uint32_t codec_flags;
switch_mutex_t *reg_mutex; switch_mutex_t *ireg_mutex;
switch_mutex_t *oreg_mutex;
outbound_reg_t *registrations;
}; };
struct private_object { struct private_object {
sofia_private_t sofia_private;
uint32_t flags; uint32_t flags;
switch_core_session_t *session; switch_core_session_t *session;
switch_frame_t read_frame; switch_frame_t read_frame;
...@@ -263,21 +306,21 @@ static void sip_i_state(int status, ...@@ -263,21 +306,21 @@ static void sip_i_state(int status,
nua_t *nua, nua_t *nua,
sofia_profile_t *profile, sofia_profile_t *profile,
nua_handle_t *nh, nua_handle_t *nh,
switch_core_session_t *session, sofia_private_t *sofia_private,
sip_t const *sip, sip_t const *sip,
tagi_t tags[]); tagi_t tags[]);
static void sip_i_invite(nua_t *nua, static void sip_i_invite(nua_t *nua,
sofia_profile_t *profile, sofia_profile_t *profile,
nua_handle_t *nh, nua_handle_t *nh,
switch_core_session_t *session, sofia_private_t *sofia_private,
sip_t const *sip, sip_t const *sip,
tagi_t tags[]); tagi_t tags[]);
static void sip_i_register(nua_t *nua, static void sip_i_register(nua_t *nua,
sofia_profile_t *profile, sofia_profile_t *profile,
nua_handle_t *nh, nua_handle_t *nh,
switch_core_session_t *session, sofia_private_t *sofia_private,
sip_t const *sip, sip_t const *sip,
tagi_t tags[]); tagi_t tags[]);
...@@ -287,7 +330,7 @@ static void event_callback(nua_event_t event, ...@@ -287,7 +330,7 @@ static void event_callback(nua_event_t event,
nua_t *nua, nua_t *nua,
sofia_profile_t *profile, sofia_profile_t *profile,
nua_handle_t *nh, nua_handle_t *nh,
switch_core_session_t *session, sofia_private_t *sofia_private,
sip_t const *sip, sip_t const *sip,
tagi_t tags[]); tagi_t tags[]);
...@@ -356,7 +399,7 @@ static auth_res_t parse_auth(sofia_profile_t *profile, sip_authorization_t const ...@@ -356,7 +399,7 @@ static auth_res_t parse_auth(sofia_profile_t *profile, sip_authorization_t const
} }
if (switch_strlen_zero(np)) { if (switch_strlen_zero(np)) {
if (!get_auth_data(profile->dbname, nonce, np, nplen, profile->reg_mutex)) { if (!get_auth_data(profile->dbname, nonce, np, nplen, profile->ireg_mutex)) {
ret = AUTH_STALE; ret = AUTH_STALE;
goto end; goto end;
} }
...@@ -468,7 +511,7 @@ static void check_expire(sofia_profile_t *profile, time_t now) ...@@ -468,7 +511,7 @@ static void check_expire(sofia_profile_t *profile, time_t now)
return; return;
} }
switch_mutex_lock(profile->reg_mutex); switch_mutex_lock(profile->ireg_mutex);
snprintf(sql, sizeof(sql), "select '%s',* from sip_registrations where expires > 0 and expires < %ld", profile->name, (long) now); snprintf(sql, sizeof(sql), "select '%s',* from sip_registrations where expires > 0 and expires < %ld", profile->name, (long) now);
switch_core_db_exec(db, sql, del_callback, NULL, &errmsg); switch_core_db_exec(db, sql, del_callback, NULL, &errmsg);
...@@ -482,7 +525,7 @@ static void check_expire(sofia_profile_t *profile, time_t now) ...@@ -482,7 +525,7 @@ static void check_expire(sofia_profile_t *profile, time_t now)
switch_core_db_persistant_execute(db, sql, 25); switch_core_db_persistant_execute(db, sql, 25);
snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and expires < %ld", (long) now); snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and expires < %ld", (long) now);
switch_core_db_persistant_execute(db, sql, 25); switch_core_db_persistant_execute(db, sql, 25);
switch_mutex_unlock(profile->reg_mutex); switch_mutex_unlock(profile->ireg_mutex);
switch_core_db_close(db); switch_core_db_close(db);
} }
...@@ -500,7 +543,7 @@ static char *find_reg_url(sofia_profile_t *profile, char *user, char *host, char ...@@ -500,7 +543,7 @@ static char *find_reg_url(sofia_profile_t *profile, char *user, char *host, char
cbt.val = val; cbt.val = val;
cbt.len = len; cbt.len = len;
switch_mutex_lock(profile->reg_mutex); switch_mutex_lock(profile->ireg_mutex);
if (host) { if (host) {
snprintf(val, len, "select contact from sip_registrations where user='%s' and host='%s'", user, host); snprintf(val, len, "select contact from sip_registrations where user='%s' and host='%s'", user, host);
} else { } else {
...@@ -515,7 +558,7 @@ static char *find_reg_url(sofia_profile_t *profile, char *user, char *host, char ...@@ -515,7 +558,7 @@ static char *find_reg_url(sofia_profile_t *profile, char *user, char *host, char
errmsg = NULL; errmsg = NULL;
} }
switch_mutex_unlock(profile->reg_mutex); switch_mutex_unlock(profile->ireg_mutex);
switch_core_db_close(db); switch_core_db_close(db);
return cbt.matches ? val : NULL; return cbt.matches ? val : NULL;
...@@ -723,7 +766,8 @@ static void do_invite(switch_core_session_t *session) ...@@ -723,7 +766,8 @@ static void do_invite(switch_core_session_t *session)
switch_set_flag_locked(tech_pvt, TFLAG_READY); switch_set_flag_locked(tech_pvt, TFLAG_READY);
tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL, SIPTAG_TO_STR(tech_pvt->dest), TAG_END()); tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL, SIPTAG_TO_STR(tech_pvt->dest), TAG_END());
nua_handle_bind(tech_pvt->nh, session); tech_pvt->sofia_private.session = session;
nua_handle_bind(tech_pvt->nh, &tech_pvt->sofia_private);
nua_invite(tech_pvt->nh, nua_invite(tech_pvt->nh,
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE),
...@@ -1593,7 +1637,7 @@ static void sip_i_state(int status, ...@@ -1593,7 +1637,7 @@ static void sip_i_state(int status,
nua_t *nua, nua_t *nua,
sofia_profile_t *profile, sofia_profile_t *profile,
nua_handle_t *nh, nua_handle_t *nh,
switch_core_session_t *session, sofia_private_t *sofia_private,
sip_t const *sip, sip_t const *sip,
tagi_t tags[]) tagi_t tags[])
...@@ -1604,6 +1648,7 @@ static void sip_i_state(int status, ...@@ -1604,6 +1648,7 @@ static void sip_i_state(int status,
int ss_state = nua_callstate_init; int ss_state = nua_callstate_init;
switch_channel_t *channel = NULL; switch_channel_t *channel = NULL;
private_object_t *tech_pvt = NULL; private_object_t *tech_pvt = NULL;
switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
tl_gets(tags, tl_gets(tags,
NUTAG_CALLSTATE_REF(ss_state), NUTAG_CALLSTATE_REF(ss_state),
...@@ -1842,7 +1887,6 @@ typedef enum { ...@@ -1842,7 +1887,6 @@ typedef enum {
static uint8_t handle_register(nua_t *nua, static uint8_t handle_register(nua_t *nua,
sofia_profile_t *profile, sofia_profile_t *profile,
nua_handle_t *nh, nua_handle_t *nh,
switch_core_session_t *session,
sip_t const *sip, sip_t const *sip,
sofia_regtype_t regtype, sofia_regtype_t regtype,
char *key, char *key,
...@@ -1852,7 +1896,6 @@ static uint8_t handle_register(nua_t *nua, ...@@ -1852,7 +1896,6 @@ static uint8_t handle_register(nua_t *nua,
sip_expires_t const *expires = sip->sip_expires; sip_expires_t const *expires = sip->sip_expires;
sip_authorization_t const *authorization = sip->sip_authorization; sip_authorization_t const *authorization = sip->sip_authorization;
sip_contact_t const *contact = sip->sip_contact; sip_contact_t const *contact = sip->sip_contact;
switch_xml_t domain, xml, user, param; switch_xml_t domain, xml, user, param;
char params[1024] = ""; char params[1024] = "";
char *sql; char *sql;
...@@ -1865,9 +1908,9 @@ static uint8_t handle_register(nua_t *nua, ...@@ -1865,9 +1908,9 @@ static uint8_t handle_register(nua_t *nua,
char *passwd = NULL; char *passwd = NULL;
uint8_t stale = 0, ret = 0, forbidden = 0; uint8_t stale = 0, ret = 0, forbidden = 0;
auth_res_t auth_res; auth_res_t auth_res;
long exptime = 60; long exptime = 60;
if (expires) { if (expires) {
exptime = expires->ex_delta; exptime = expires->ex_delta;
} else if (contact->m_expires) { } else if (contact->m_expires) {
...@@ -1979,7 +2022,7 @@ static uint8_t handle_register(nua_t *nua, ...@@ -1979,7 +2022,7 @@ static uint8_t handle_register(nua_t *nua,
} }
execute_sql(profile->dbname, sql, profile->reg_mutex); execute_sql(profile->dbname, sql, profile->ireg_mutex);
switch_core_db_free(sql); switch_core_db_free(sql);
switch_core_db_free(auth_str); switch_core_db_free(auth_str);
ret = 1; ret = 1;
...@@ -2025,7 +2068,7 @@ static uint8_t handle_register(nua_t *nua, ...@@ -2025,7 +2068,7 @@ static uint8_t handle_register(nua_t *nua,
} }
if (sql) { if (sql) {
execute_sql(profile->dbname, sql, profile->reg_mutex); execute_sql(profile->dbname, sql, profile->ireg_mutex);
switch_core_db_free(sql); switch_core_db_free(sql);
sql = NULL; sql = NULL;
} }
...@@ -2051,17 +2094,17 @@ static uint8_t handle_register(nua_t *nua, ...@@ -2051,17 +2094,17 @@ static uint8_t handle_register(nua_t *nua,
static void sip_i_invite(nua_t *nua, static void sip_i_invite(nua_t *nua,
sofia_profile_t *profile, sofia_profile_t *profile,
nua_handle_t *nh, nua_handle_t *nh,
switch_core_session_t *session, sofia_private_t *sofia_private,
sip_t const *sip, sip_t const *sip,
tagi_t tags[]) tagi_t tags[])
{ {
switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
char key[128] = ""; char key[128] = "";
if (!session) { if (!session) {
if ((profile->pflags & PFLAG_AUTH_CALLS)) { if ((profile->pflags & PFLAG_AUTH_CALLS)) {
if (handle_register(nua, profile, nh, session, sip, REG_INVITE, key, sizeof(key))) { if (handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key))) {
return; return;
} }
} }
...@@ -2119,7 +2162,8 @@ static void sip_i_invite(nua_t *nua, ...@@ -2119,7 +2162,8 @@ static void sip_i_invite(nua_t *nua,
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
} }
switch_set_flag_locked(tech_pvt, TFLAG_INBOUND); switch_set_flag_locked(tech_pvt, TFLAG_INBOUND);
nua_handle_bind(nh, session); tech_pvt->sofia_private.session = session;
nua_handle_bind(nh, &tech_pvt->sofia_private);
} }
} }
} }
...@@ -2127,11 +2171,79 @@ static void sip_i_invite(nua_t *nua, ...@@ -2127,11 +2171,79 @@ static void sip_i_invite(nua_t *nua,
static void sip_i_register(nua_t *nua, static void sip_i_register(nua_t *nua,
sofia_profile_t *profile, sofia_profile_t *profile,
nua_handle_t *nh, nua_handle_t *nh,
switch_core_session_t *session, sofia_private_t *sofia_private,
sip_t const *sip,
tagi_t tags[])
{
//switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
handle_register(nua, profile, nh, sip, REG_REGISTER, NULL, 0);
}
static void sip_r_register(int status,
char const *phrase,
nua_t *nua,
sofia_profile_t *profile,
nua_handle_t *nh,
sofia_private_t *sofia_private,
sip_t const *sip, sip_t const *sip,
tagi_t tags[]) tagi_t tags[])
{ {
handle_register(nua, profile, nh, session, sip, REG_REGISTER, NULL, 0); outbound_reg_t *oreg = NULL;
sip_www_authenticate_t const *authenticate = NULL;
if (sofia_private) {
if (sofia_private->oreg) {
oreg = sofia_private->oreg;
} else if (profile) {
/* NOTE
this is a linked list, when nua_identity comes
we need to actually pick the right one...
*/
oreg = profile->registrations;
}
}
if (!oreg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No authentication available!\n");
return;
}
if (sip->sip_www_authenticate) {
authenticate = sip->sip_www_authenticate;
} else if (sip->sip_proxy_authenticate) {
authenticate = sip->sip_proxy_authenticate;
}
if (authenticate) {
char const *realm = (char const *) *authenticate->au_params;
char const *scheme = (char const *) authenticate->au_scheme;
char authentication[256] = "";
int ss_state;
snprintf(authentication, sizeof(authentication), "%s:%s:%s:%s", scheme, strstr(realm, "=") + 1,
oreg->register_username,
oreg->register_password);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Authenticating '%s' with '%s'.\n",
profile->username, authentication);
ss_state = nua_callstate_authenticating;
tl_gets(tags,
NUTAG_CALLSTATE_REF(ss_state),
SIPTAG_WWW_AUTHENTICATE_REF(authenticate),
TAG_END());
nua_authenticate(nh, NUTAG_AUTH(authentication), TAG_END());
} else if (status == 200) {
if (!sofia_private->session) {
oreg->state = REG_STATE_REGISTER;
}
}
} }
static void event_callback(nua_event_t event, static void event_callback(nua_event_t event,
...@@ -2140,12 +2252,13 @@ static void event_callback(nua_event_t event, ...@@ -2140,12 +2252,13 @@ static void event_callback(nua_event_t event,
nua_t *nua, nua_t *nua,
sofia_profile_t *profile, sofia_profile_t *profile,
nua_handle_t *nh, nua_handle_t *nh,
switch_core_session_t *session, sofia_private_t *sofia_private,
sip_t const *sip, sip_t const *sip,
tagi_t tags[]) tagi_t tags[])
{ {
struct private_object *tech_pvt = NULL; struct private_object *tech_pvt = NULL;
auth_res_t auth_res = AUTH_FORBIDDEN; auth_res_t auth_res = AUTH_FORBIDDEN;
switch_core_session_t *session = sofia_private ? sofia_private->session : NULL;
if (session) { if (session) {
if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
...@@ -2184,107 +2297,104 @@ static void event_callback(nua_event_t event, ...@@ -2184,107 +2297,104 @@ static void event_callback(nua_event_t event,
switch (event) { switch (event) {
case nua_r_shutdown: case nua_r_shutdown:
//sip_r_shutdown(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_shutdown(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_get_params: case nua_r_get_params:
//sip_r_get_params(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_get_params(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_invite:
case nua_r_register: case nua_r_register:
//sip_r_register(status, phrase, nua, profile, nh, session, sip, tags); sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_unregister: case nua_r_unregister:
//sip_r_unregister(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_unregister(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_options: case nua_r_options:
//sip_r_options(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break;
case nua_r_invite:
//sip_r_invite(status, phrase, nua, profile, nh, session, sip, tags);
break; break;
case nua_i_fork: case nua_i_fork:
//sip_i_fork(status, phrase, nua, profile, nh, session, sip, tags); //sip_i_fork(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_invite: case nua_i_invite:
sip_i_invite(nua, profile, nh, session, sip, tags); sip_i_invite(nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_register: case nua_i_register:
sip_i_register (nua, profile, nh, session, sip, tags); sip_i_register (nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_prack: case nua_i_prack:
//sip_i_prack(nua, profile, nh, session, sip, tags); //sip_i_prack(nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_state: case nua_i_state:
sip_i_state(status, phrase, nua, profile, nh, session, sip, tags); sip_i_state(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_bye: case nua_r_bye:
//sip_r_bye(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_bye(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_bye: case nua_i_bye:
//sip_i_bye(nua, profile, nh, session, sip, tags); //sip_i_bye(nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_message: case nua_r_message:
//sip_r_message(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_message(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_message: case nua_i_message:
//sip_i_message(nua, profile, nh, session, sip, tags); //sip_i_message(nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_info: case nua_r_info:
//sip_r_info(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_info(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_info: case nua_i_info:
//sip_i_info(nua, profile, nh, session, sip, tags); //sip_i_info(nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_refer: case nua_r_refer:
//sip_r_refer(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_refer(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_refer: case nua_i_refer:
//sip_i_refer(nua, profile, nh, session, sip, tags); //sip_i_refer(nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_subscribe: case nua_r_subscribe:
//sip_r_subscribe(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_unsubscribe: case nua_r_unsubscribe:
//sip_r_unsubscribe(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_unsubscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_publish: case nua_r_publish:
//sip_r_publish(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_publish(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_r_notify: case nua_r_notify:
//sip_r_notify(status, phrase, nua, profile, nh, session, sip, tags); //sip_r_notify(status, phrase, nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_notify: case nua_i_notify:
//sip_i_notify(nua, profile, nh, session, sip, tags); //sip_i_notify(nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_cancel: case nua_i_cancel:
//sip_i_cancel(nua, profile, nh, session, sip, tags); //sip_i_cancel(nua, profile, nh, sofia_private, sip, tags);
break; break;
case nua_i_error: case nua_i_error:
//sip_i_error(nua, profile, nh, session, status, phrase, tags); //sip_i_error(nua, profile, nh, sofia_private, status, phrase, tags);
break; break;
case nua_i_active: case nua_i_active:
...@@ -2309,15 +2419,67 @@ static void event_callback(nua_event_t event, ...@@ -2309,15 +2419,67 @@ static void event_callback(nua_event_t event,
} }
} }
#define REG_SECONDS 30 static void check_oreg(sofia_profile_t *profile, time_t now)
{
outbound_reg_t *oregp;
for (oregp = profile->registrations; oregp; oregp = oregp->next) {
int ss_state = nua_callstate_authenticating;
reg_state_t ostate = oregp->state;
switch(ostate) {
case REG_STATE_REGISTER:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "registered %s\n", oregp->name);
oregp->expires = now + oregp->freq;
oregp->state = REG_STATE_REGED;
oregp->retry = 0;
break;
case REG_STATE_UNREGED:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "registering %s\n", oregp->name);
if ((oregp->nh = nua_handle(oregp->profile->nua, NULL,
NUTAG_URL(oregp->register_proxy),
SIPTAG_TO_STR(oregp->register_to),
NUTAG_CALLSTATE_REF(ss_state),
SIPTAG_FROM_STR(oregp->register_from), TAG_END()))) {
oregp->sofia_private.oreg = oregp;
nua_handle_bind(oregp->nh, &oregp->sofia_private);
nua_register(oregp->nh,
SIPTAG_FROM_STR(oregp->register_from),
SIPTAG_CONTACT_STR(oregp->register_from),
SIPTAG_EXPIRES_STR(oregp->expires_str),
NUTAG_REGISTRAR(oregp->register_proxy),
TAG_NULL());
oregp->state = REG_STATE_TRYING;
oregp->retry = now + 10;
}
break;
default:
if (oregp->retry && now >= oregp->retry) {
oregp->state = REG_STATE_UNREGED;
oregp->retry = 0;
}
if (oregp->expires && now >= oregp->expires) {
oregp->state = REG_STATE_UNREGED;
oregp->expires = 0;
}
break;
}
}
}
#define IREG_SECONDS 30
#define OREG_SECONDS 1
static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void *obj) static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void *obj)
{ {
sofia_profile_t *profile = (sofia_profile_t *) obj; sofia_profile_t *profile = (sofia_profile_t *) obj;
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
sip_alias_node_t *node; sip_alias_node_t *node;
uint32_t loops = 0; uint32_t ireg_loops = 0;
uint32_t oreg_loops = 0;
switch_core_db_t *db; switch_core_db_t *db;
profile->s_root = su_root_create(NULL); profile->s_root = su_root_create(NULL);
profile->nua = nua_create(profile->s_root, /* Event loop */ profile->nua = nua_create(profile->s_root, /* Event loop */
event_callback, /* Callback for processing events */ event_callback, /* Callback for processing events */
...@@ -2363,18 +2525,25 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void ...@@ -2363,18 +2525,25 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
} }
switch_core_db_close(db); switch_core_db_close(db);
switch_mutex_init(&profile->reg_mutex, SWITCH_MUTEX_NESTED, profile->pool); switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
switch_mutex_init(&profile->oreg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
switch_mutex_lock(globals.mutex); switch_mutex_lock(globals.mutex);
globals.running = 1; globals.running = 1;
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
loops = REG_SECONDS; ireg_loops = IREG_SECONDS;
oreg_loops = OREG_SECONDS;
while(globals.running == 1) { while(globals.running == 1) {
if (++loops >= REG_SECONDS) { if (++ireg_loops >= IREG_SECONDS) {
check_expire(profile, time(NULL)); check_expire(profile, time(NULL));
loops = 0; ireg_loops = 0;
}
if (++oreg_loops >= OREG_SECONDS) {
check_oreg(profile, time(NULL));
oreg_loops = 0;
} }
su_root_step(profile->s_root, 1000); su_root_step(profile->s_root, 1000);
...@@ -2411,8 +2580,10 @@ static void launch_profile_thread(sofia_profile_t *profile) ...@@ -2411,8 +2580,10 @@ static void launch_profile_thread(sofia_profile_t *profile)
static switch_status_t config_sofia(int reload) static switch_status_t config_sofia(int reload)
{ {
char *cf = "sofia.conf"; char *cf = "sofia.conf";
switch_xml_t cfg, xml = NULL, xprofile, param; switch_xml_t cfg, xml = NULL, xprofile, param, settings, profiles, registration, registrations;
switch_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
sofia_profile_t *profile = NULL;
char url[512] = "";
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
...@@ -2420,11 +2591,14 @@ static switch_status_t config_sofia(int reload) ...@@ -2420,11 +2591,14 @@ static switch_status_t config_sofia(int reload)
goto done; goto done;
} }
for (xprofile = switch_xml_child(cfg, "profile"); xprofile; xprofile = xprofile->next) { if ((profiles = switch_xml_child(cfg, "profiles"))) {
for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
if (!(settings = switch_xml_child(xprofile, "settings"))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Settings, check the new config!\n", cf);
} else {
char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name"); char *xprofilename = (char *) switch_xml_attr_soft(xprofile, "name");
sofia_profile_t *profile;
switch_memory_pool_t *pool = NULL; switch_memory_pool_t *pool = NULL;
char url[512] = "";
/* Setup the pool */ /* Setup the pool */
if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) { if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
...@@ -2450,7 +2624,7 @@ static switch_status_t config_sofia(int reload) ...@@ -2450,7 +2624,7 @@ static switch_status_t config_sofia(int reload)
profile->dtmf_duration = 100; profile->dtmf_duration = 100;
profile->codec_ms = 20; profile->codec_ms = 20;
for (param = switch_xml_child(xprofile, "param"); param; param = param->next) { for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name"); char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value"); char *val = (char *) switch_xml_attr_soft(param, "value");
...@@ -2559,11 +2733,91 @@ static switch_status_t config_sofia(int reload) ...@@ -2559,11 +2733,91 @@ static switch_status_t config_sofia(int reload)
snprintf(url, sizeof(url), "sip:%s:%d", profile->sipip, profile->sip_port); snprintf(url, sizeof(url), "sip:%s:%d", profile->sipip, profile->sip_port);
profile->url = switch_core_strdup(profile->pool, url); profile->url = switch_core_strdup(profile->pool, url);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url); }
launch_profile_thread(profile); if (profile) {
if ((registrations = switch_xml_child(xprofile, "registrations"))) {
uint32_t reg_count = 0;
for (registration = switch_xml_child(registrations, "registration"); registration; registration = registration->next) {
char *name = (char *) switch_xml_attr_soft(registration, "name");
outbound_reg_t *oreg;
if (++reg_count > 1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Sorry, only one registration per profile for now =(:::, ask the sofia team for NUTAG_IDENTITY!!!!\n");
}
if (switch_strlen_zero(name)) {
name = "anonymous";
}
if ((oreg = switch_core_alloc(profile->pool, sizeof(*oreg)))) {
oreg->pool = profile->pool;
oreg->profile = profile;
oreg->name = switch_core_strdup(oreg->pool, name);
oreg->freq = 60;
for (param = switch_xml_child(registration, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!strcmp(var, "register-scheme")) {
oreg->register_scheme = switch_core_strdup(oreg->pool, val);
} else if (!strcmp(var, "register-realm")) {
oreg->register_realm = switch_core_strdup(oreg->pool, val);
} else if (!strcmp(var, "register-username")) {
oreg->register_username = switch_core_strdup(oreg->pool, val);
} else if (!strcmp(var, "register-password")) {
oreg->register_password = switch_core_strdup(oreg->pool, val);
} else if (!strcmp(var, "register-from")) {
oreg->register_from = switch_core_strdup(oreg->pool, val);
} else if (!strcmp(var, "register-to")) {
oreg->register_to = switch_core_strdup(oreg->pool, val);
} else if (!strcmp(var, "register-proxy")) {
oreg->register_proxy = switch_core_strdup(oreg->pool, val);
} else if (!strcmp(var, "register-frequency")) {
oreg->expires_str = switch_core_strdup(oreg->pool, val);
oreg->freq = atoi(val);
}
}
if (switch_strlen_zero(oreg->register_scheme)) {
oreg->register_scheme = switch_core_strdup(oreg->pool, "Digest");
}
if (switch_strlen_zero(oreg->register_realm)) {
oreg->register_realm = switch_core_strdup(oreg->pool, "freeswitch.org");
}
if (switch_strlen_zero(oreg->register_username)) {
oreg->register_username = switch_core_strdup(oreg->pool, "freeswitch");
}
if (switch_strlen_zero(oreg->register_password)) {
oreg->register_password = switch_core_strdup(oreg->pool, "works");
}
if (switch_strlen_zero(oreg->register_from)) {
oreg->register_from = switch_core_strdup(oreg->pool, "FreeSWITCH <sip:freeswitch@freeswitch.org>");
}
if (switch_strlen_zero(oreg->register_to)) {
oreg->register_to = switch_core_strdup(oreg->pool, "sip:freeswitch@freeswitch.org");
}
if (switch_strlen_zero(oreg->register_proxy)) {
oreg->register_proxy = switch_core_strdup(oreg->pool, "sip:freeswitch@freeswitch.org");
}
if (switch_strlen_zero(oreg->expires_str)) {
oreg->expires_str = switch_core_strdup(oreg->pool, "300");
}
oreg->freq = atoi(oreg->expires_str);
oreg->next = profile->registrations;
profile->registrations = oreg;
}
}
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Started Profile %s [%s]\n", profile->name, url);
launch_profile_thread(profile);
profile = NULL;
}
}
}
done: done:
if (xml) { if (xml) {
switch_xml_free(xml); switch_xml_free(xml);
...@@ -2612,7 +2866,7 @@ static void event_handler(switch_event_t *event) ...@@ -2612,7 +2866,7 @@ static void event_handler(switch_event_t *event)
} }
if (sql) { if (sql) {
execute_sql(profile->dbname, sql, profile->reg_mutex); execute_sql(profile->dbname, sql, profile->ireg_mutex);
switch_core_db_free(sql); switch_core_db_free(sql);
sql = NULL; sql = NULL;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s@%s\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating registration for %s@%s->%s@%s\n",
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论