]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
refactor the presence stuff and add it to mod_conference
authorAnthony Minessale <anthony.minessale@gmail.com>
Fri, 20 Oct 2006 22:11:26 +0000 (22:11 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Fri, 20 Oct 2006 22:11:26 +0000 (22:11 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3124 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_module_interfaces.h
src/mod/applications/mod_conference/mod_conference.c
src/mod/endpoints/mod_dingaling/mod_dingaling.c
src/mod/endpoints/mod_sofia/mod_sofia.c

index 18c3d092ee62bc6f789218e4a3fc544b42777f64..37c79fdd067e380576a1b6ff6b1fed462b01a6cf 100644 (file)
@@ -371,7 +371,7 @@ struct switch_chat_interface {
        /*! the name of the interface */
        const char *interface_name;
        /*! function to open the directory interface */
-       switch_status_t (*chat_send)(char *from, char *to, char *subject, char *body, char *hint);
+       switch_status_t (*chat_send)(char *proto, char *from, char *to, char *subject, char *body, char *hint);
        const struct switch_chat_interface *next;
 };
 
index 9ccb5031c52b3770e290f816ba3c4922d7858a70..4b03ee2421618ba0f69a172f662c410767f4530b 100644 (file)
@@ -44,6 +44,7 @@ static switch_api_interface_t conf_api_interface;
 #define CONF_DBLOCK_SIZE CONF_BUFFER_SIZE
 #define CONF_DBUFFER_SIZE CONF_BUFFER_SIZE
 #define CONF_DBUFFER_MAX 0
+#define CONF_CHAT_PROTO "conf"
 
 typedef enum {
        FILE_STOP_CURRENT,
@@ -128,6 +129,7 @@ struct conference_obj {
        char *pin_sound;
        char *bad_pin_sound;
        char *profile_name;
+       char *domain;
        uint32_t flags;
        switch_call_cause_t bridge_hangup_cause;
        switch_mutex_t *flag_mutex;
@@ -217,6 +219,7 @@ static switch_status_t conference_member_say(conference_obj_t *conference, confe
 static uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop);
 static conference_obj_t *conference_new(char *name, switch_xml_t profile, switch_memory_pool_t *pool);
 static void switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol);
+static switch_status_t chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint);
 
 /* Return a Distinct ID # */
 static uint32_t next_member_id(void)
@@ -358,6 +361,16 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
        conference->members = member;
        conference->count++;
 
+       if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", conference->name);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d caller%s)", conference->count, conference->count == 1 ? "" : "s");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+               switch_event_fire(&event);
+       }
+
+
        if (conference->enter_sound) {
                conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN);
        }
@@ -411,9 +424,19 @@ static void conference_del_member(conference_obj_t *conference, conference_membe
                }
                last = imember;
        }
+
        conference->count--;
        member->conference = NULL;
 
+       if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", conference->name);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Active (%d caller%s)", conference->count, conference->count == 1 ? "" : "s");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+               switch_event_fire(&event);
+       }
+
        if ((conference->min && switch_test_flag(conference, CFLAG_ENFORCE_MIN) && conference->count < conference->min) 
                || (switch_test_flag(conference, CFLAG_DYNAMIC) && conference->count == 0) ) {
                switch_set_flag(conference, CFLAG_DESTRUCT);
@@ -456,6 +479,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
        uint32_t bytes = samples * 2;
        uint8_t ready = 0;
        switch_timer_t timer = {0};
+       switch_event_t *event;
 
        if (switch_core_timer_init(&timer, conference->timer_name, conference->interval, samples, conference->pool) == SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setup timer success interval: %u  samples: %u\n", conference->interval, samples);      
@@ -676,6 +700,16 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
                }
        }
 
+       if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", conference->name);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", conference->name, conference->domain);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Inactive");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "idle");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+               
+               switch_event_fire(&event);
+       }
        globals.threads--;      
        return NULL;
 }
@@ -729,8 +763,19 @@ static void conference_loop(conference_member_t *member)
                switch_event_t *event;
 
                if (switch_core_session_dequeue_event(member->session, &event) == SWITCH_STATUS_SUCCESS) {
+                       char *p;
+                       char *from = switch_event_get_header(event, "from");
+                       char *to = switch_event_get_header(event, "to");
+                       char *proto = switch_event_get_header(event, "proto");
+                       char *subject = switch_event_get_header(event, "subject");
+                       char *body = switch_event_get_body(event);
+                       if ((p = strchr(to, '+'))) {
+                               to = ++p;
+                       }
+                       chat_send(proto, from, to, subject, body, "");
                        switch_event_destroy(&event);
                }
+
 #if 1
                if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
                        // test to see if outbound channel has answered
@@ -1312,6 +1357,26 @@ static void conference_list(conference_obj_t *conference, switch_stream_handle_t
        switch_mutex_unlock(conference->member_mutex);
 }
 
+
+static void conference_list_pretty(conference_obj_t *conference, switch_stream_handle_t *stream)
+{
+       conference_member_t *member = NULL;
+
+       switch_mutex_lock(conference->member_mutex);
+
+       for (member = conference->members; member; member = member->next) {
+               switch_channel_t *channel = switch_core_session_get_channel(member->session);
+               switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel);
+
+               stream->write_function(stream, "Caller %s <%s>\n", 
+                                                          profile->caller_id_name,
+                                                          profile->caller_id_number
+                                                          );
+
+       }
+       switch_mutex_unlock(conference->member_mutex);
+}
+
 /* API Interface Function */
 static switch_status_t conf_function(char *buf, switch_core_session_t *session, switch_stream_handle_t *stream)
 {
@@ -2669,6 +2734,50 @@ static switch_api_interface_t conf_api_interface = {
        /*.next */ 
 };
 
+static switch_status_t chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint)
+{
+       char name[512] = "", *p;
+       switch_chat_interface_t *ci;
+       conference_obj_t *conference = NULL;
+       switch_stream_handle_t stream = {0};
+
+       if (!(ci = switch_loadable_module_get_chat_interface(proto))) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invaid Chat Interface [%s]!\n", proto);
+       }
+
+       if ((p = strchr(to, '@'))) {
+               switch_copy_string(name, to, ++p-to);
+       } else {
+               switch_copy_string(name, to, sizeof(name));
+       }
+
+       if (!(conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, name))) {
+               ci->chat_send(CONF_CHAT_PROTO, to, from, "", "Sorry, We're Closed", "");
+               return SWITCH_STATUS_FALSE;
+       }
+       
+       SWITCH_STANDARD_STREAM(stream);
+
+       if (strstr(body, "list")) {
+               conference_list_pretty(conference, &stream);
+       } else {
+               stream.write_function(&stream, "The only command we have is so far is 'list' Get coding or go press PayPal!!\n");
+       }
+
+       ci->chat_send(CONF_CHAT_PROTO, to, from, "", stream.data, "");
+       switch_safe_free(stream.data);
+
+       
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+static const switch_chat_interface_t conference_chat_interface = {
+       /*.name */ CONF_CHAT_PROTO,
+       /*.chat_send */ chat_send,
+       
+};
+
 static switch_loadable_module_interface_t conference_module_interface = {
        /*.module_name */ modname,
        /*.endpoint_interface */ NULL,
@@ -2679,7 +2788,8 @@ static switch_loadable_module_interface_t conference_module_interface = {
        /*.api_interface */ &conf_api_interface,
        /*.file_interface */ NULL,
        /*.speech_interface */ NULL,
-       /*.directory_interface */ NULL
+       /*.directory_interface */ NULL,
+       /*.chat_interface */ &conference_chat_interface
 };
 
 /* create a new conferene with a specific profile */
@@ -2690,6 +2800,7 @@ static conference_obj_t *conference_new(char *name, switch_xml_t profile, switch
        char *rate_name = NULL;
        char *interval_name = NULL;
        char *timer_name = NULL;
+       char *domain = NULL;
        char *tts_engine = NULL;
        char *tts_voice = NULL;
        char *enter_sound = NULL;
@@ -2734,6 +2845,8 @@ static conference_obj_t *conference_new(char *name, switch_xml_t profile, switch
                
                if (!strcasecmp(var, "rate")) {
                        rate_name = val;
+               } else if (!strcasecmp(var, "domain")) {
+                       domain = val;
                } else if (!strcasecmp(var, "interval")) {
                        interval_name= val;
                } else if (!strcasecmp(var, "timer-name")) {
@@ -2886,6 +2999,11 @@ static conference_obj_t *conference_new(char *name, switch_xml_t profile, switch
        }
 
        conference->name = switch_core_strdup(conference->pool, name);
+       if (domain) {
+               conference->domain = switch_core_strdup(conference->pool, domain);
+       } else {
+               conference->domain = "cluecon.com";
+       }
        conference->rate = rate;
        conference->interval = interval;
 
@@ -2899,11 +3017,13 @@ static conference_obj_t *conference_new(char *name, switch_xml_t profile, switch
        return conference;
 }
 
+
 /* Called by FreeSWITCH when the module loads */
 SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
 {
        switch_status_t status = SWITCH_STATUS_SUCCESS;
-       
+       switch_xml_t cfg, xml, param, ads;
+
        memset(&globals, 0, sizeof(globals));
 
        /* Connect my internal structure to the blank pointer passed to me */
@@ -2920,6 +3040,29 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
                return SWITCH_STATUS_TERM;
        }
 
+       if ((xml = switch_xml_open_cfg(global_cf_name, &cfg, NULL))) {
+               if ((ads = switch_xml_child(cfg, "advertise"))) {
+                       switch_event_t *event;
+               
+                       for (param = switch_xml_child(ads, "room"); param; param = param->next) {
+                               char *status = (char *) switch_xml_attr_soft(param, "status");
+                               char *name = (char *) switch_xml_attr_soft(param, "name");
+
+                               if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+                                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO);
+                                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", name);
+                                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", name);
+                                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", status ? status : "Inactive");
+                                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "idle");
+                                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+                               
+                                       switch_event_fire(&event);
+                               }                       
+                       }
+               }
+       }
+
+
        /* Setup a hash to store conferences by name */
        switch_core_hash_init(&globals.conference_hash, globals.conference_pool);
        switch_mutex_init(&globals.conference_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool);
index a6023391fcc1216dfdc552e37955ef8e36b3f274..f5b414034302fc209331d2716dac4a4befb786d3 100644 (file)
@@ -38,7 +38,7 @@
 #define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success"
 #define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure"
 #define DL_EVENT_CONNECTED "dingaling::connected"
-#define MDL_CHAT_NAME "jingle"
+#define MDL_CHAT_PROTO "jingle"
 
 static const char modname[] = "mod_dingaling";
 
@@ -212,6 +212,10 @@ static char *translate_rpid(char *in, char *ext)
                r = "dnd";
        }
 
+       if (!strcasecmp(in, "idle")) {
+               r = "away";
+       }
+
        if (ext && !strcasecmp(ext, "idle")) {
                r = "away";
        } else if (ext && !strcasecmp(ext, "away")) {
@@ -230,16 +234,19 @@ static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
        char *type = argv[2];
        char *rpid = argv[3];
        char *status = argv[4];
-
+       //char *proto = argv[5];
+       
        if (switch_strlen_zero(type)) {
                type = NULL;
        } else if (!strcasecmp(type, "unavailable")) {
                status = NULL;
        }
        rpid = translate_rpid(rpid, status);
-       
+
+       ldl_handle_send_presence(profile->handle, sub_to, sub_from, "probe", rpid, status);
        ldl_handle_send_presence(profile->handle, sub_to, sub_from, type, rpid, status);
 
+
        return 0;
 }
 
@@ -270,14 +277,23 @@ static void pres_event_handler(switch_event_t *event)
        struct mdl_profile *profile = NULL;
        switch_hash_index_t *hi;
     void *val;
+       char *proto = switch_event_get_header(event, "proto");
        char *from = switch_event_get_header(event, "from");
        char *status= switch_event_get_header(event, "status");
        char *rpid = switch_event_get_header(event, "rpid");
        char *type = switch_event_get_header(event, "event_subtype");
        char *sql;
        switch_core_db_t *db;
-       char *p;
 
+       if (!proto) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Missing 'proto' header\n");
+               return;
+       }
+
+       if (!from) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Missing 'from' header\n");
+               return;
+       }
 
        if (status && !strcasecmp(status, "n/a")) {
                status = NULL;
@@ -297,12 +313,22 @@ static void pres_event_handler(switch_event_t *event)
        }
        
 
-       if ((p = strchr(from, '/'))) {
-               *p = '\0';
+       if (!type) {
+               type = "";
+       }
+       if (!rpid) {
+               rpid = "";
        }
+       if (!status) {
+               status = "Away";
+       }
+       
+
+       sql = switch_mprintf("select sub_from, sub_to,'%q','%q','%q','%q' from subscriptions where sub_to like '%%%q'", 
+                                                type, rpid, status, proto, from);
+       
        
-       sql = switch_mprintf("select sub_from, sub_to,'%q','%q','%q' from subscriptions where sub_to='%q'", 
-                                                type ? type : "", rpid, status ? status : "unavailable", from);
+
        for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
                char *errmsg;
         switch_hash_this(hi, NULL, NULL, &val);
@@ -330,11 +356,13 @@ static void pres_event_handler(switch_event_t *event)
        switch_safe_free(sql);
 }
 
-static switch_status_t chat_send(char *from, char *to, char *subject, char *body, char *hint)
+static switch_status_t chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint)
 {
-       char *user, *host, *f_user, *f_host = NULL;
+       char *user, *host, *f_user = NULL, *ffrom = NULL, *f_host = NULL;
        struct mdl_profile *profile = NULL;
 
+       assert(proto != NULL);
+
        if (from && (f_user = strdup(from))) {
                if ((f_host = strchr(f_user, '@'))) {
                        *f_host++ = '\0';
@@ -347,14 +375,25 @@ static switch_status_t chat_send(char *from, char *to, char *subject, char *body
                }
 
                if (f_host && (profile = switch_core_hash_find(globals.profile_hash, f_host))) {
+                       
+                       if (!strcmp(proto, MDL_CHAT_PROTO)) {
+                               from = hint;
+                       } else {
+                               char *p;
+                               ffrom = switch_mprintf("%s+%s", proto, from);
+                               from = ffrom;
+                               if ((p = strchr(from, '/'))) {
+                                       *p = '\0';
+                               }
+                       }
                        ldl_handle_send_msg(profile->handle, from, to, NULL, body);
                } else {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile %s\n", f_host ? f_host : "NULL");
                        return SWITCH_STATUS_FALSE;
                }
 
-               switch_safe_free(f_host);
-               free(user);
+               switch_safe_free(user);
+               switch_safe_free(f_user);
        }
 
        return SWITCH_STATUS_SUCCESS;
@@ -548,12 +587,8 @@ static void *SWITCH_THREAD_FUNC handle_thread_run(switch_thread_t *thread, void
 {
        ldl_handle_t *handle = obj;
        struct mdl_profile *profile = NULL;
-       switch_event_t *event;
 
-       if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
-               switch_event_fire(&event);
-       }
+
 
        profile = ldl_handle_get_private(handle);
        globals.handles++;
@@ -1342,7 +1377,7 @@ static switch_api_interface_t login_api_interface = {
 };
 
 static const switch_chat_interface_t channel_chat_interface = {
-       /*.name */ MDL_CHAT_NAME,
+       /*.name */ MDL_CHAT_PROTO,
        /*.chat_send */ chat_send,
 };
 
@@ -1936,7 +1971,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
                        break;
                case LDL_SIGNAL_ROSTER:
                        if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
-                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
                                switch_event_fire(&event);
                        }
@@ -1949,7 +1984,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
                        }
 
                        if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
-                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s",  from);
                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", msg);
@@ -1967,7 +2002,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
                        }
 
                        if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
-                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
                                switch_event_fire(&event);
@@ -1975,8 +2010,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
                        break;
                case LDL_SIGNAL_MSG: {
                        switch_chat_interface_t *ci;
-                       char *proto = MDL_CHAT_NAME;
-                       char *pproto = NULL;
+                       char *proto = MDL_CHAT_PROTO;
+                       char *pproto = NULL, *ffrom = NULL;
 
                        if (profile->auto_reply) {
                                ldl_handle_send_msg(handle, (profile->user_flags & LDL_FLAG_COMPONENT) ? to : profile->login, from, "", profile->auto_reply);
@@ -1990,13 +2025,23 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
                                proto = pproto;
                        }
                        
+                       if (strchr(from, '/') && (ffrom = strdup(from))) {
+                               char *p;
+                               if ((p = strchr(ffrom, '/'))) {
+                                       *p = '\0';
+                               }
+                               from = ffrom;
+
+                       }
+
                        if ((ci = switch_loadable_module_get_chat_interface(proto))) {
-                               ci->chat_send(from, to, subject, msg, "");
+                               ci->chat_send(MDL_CHAT_PROTO, from, to, subject, msg, "");
                        } else {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invaid Chat Interface [%s]!\n", proto);
                        }
 
                        switch_safe_free(pproto);
+                       switch_safe_free(ffrom);
                }
                        break;
                case LDL_SIGNAL_LOGIN_SUCCESS:
@@ -2093,14 +2138,23 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
                                        switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_BREAK);
                                }
                        }
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SESSION MSG [%s]\n", msg);
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SESSION MSG [%s]\n", msg);
                }
 
                if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
+                       char *p, *freeme = NULL;
+                       
+                       if (strchr(from, '/')) {
+                               freeme = strdup(from);
+                               p = strchr(freeme, '/');
+                               *p = '\0';
+                               from = freeme;
+                       }
+
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
-                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to);
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", "%s", subject);
                        if (msg) {
                                switch_event_add_body(event, msg);
@@ -2110,6 +2164,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
                                switch_event_fire(&event);
                        }
 
+                       switch_safe_free(freeme);
                }
                break;
        case LDL_SIGNAL_TRANSPORT_ACCEPT:
index ffce1fe941f1bb236ffe9d1b44d6f10d21e0718e..0d79b2fcf19710e189821a5e48c1ca25a4c9c414 100644 (file)
@@ -63,7 +63,7 @@ typedef struct private_object private_object_t;
 #define MULTICAST_EVENT "multicast::event"
 #define SOFIA_REPLACES_HEADER "_sofia_replaces_"
 #define SOFIA_USER_AGENT "FreeSWITCH(mod_sofia)"
-#define SOFIA_CHAT_NAME "sip"
+#define SOFIA_CHAT_PROTO "sip"
 
 #include <sofia-sip/nua.h>
 #include <sofia-sip/sip_status.h>
@@ -349,6 +349,8 @@ static uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp)
 
 static char *get_auth_data(char *dbname, char *nonce, char *npassword, size_t len, switch_mutex_t *mutex);
 
+static void establish_presence(sofia_profile_t *profile);
+
 static void sip_i_state(int status,
                         char const *phrase,
                         nua_t *nua,
@@ -397,7 +399,7 @@ static void launch_profile_thread(sofia_profile_t *profile);
 
 static switch_status_t config_sofia(int reload);
 
-static switch_status_t chat_send(char *from, char *to, char *subject, char *body, char *hint);
+static switch_status_t chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint);
 
 /* BODY OF THE MODULE */
 /*************************************************************************************************************************************************************/
@@ -837,53 +839,6 @@ static switch_status_t tech_choose_port(private_object_t *tech_pvt)
        return SWITCH_STATUS_SUCCESS;
 }
 
-char *encode_name(char *s) 
-{
-       char *ss, *sret;
-       uint32_t len;
-       char *at, *resource;
-       char *user;
-
-       if (!s) {
-               return NULL;
-       }
-
-       if (!strchr(s, '/')) {
-               return NULL;
-       }
-
-       if (!(ss = strdup(s))) {
-               return NULL;
-       }
-
-       user = ss;
-
-       resource = strchr(user, '/');
-       at = strchr(user, '@');
-       
-       if (resource) {
-               *resource++ = '\0';
-       }
-
-       len = (uint32_t)strlen(user) + 25;
-
-       if (at) {
-               *at++ = '\0';
-       }
-
-       if (!(sret = (char *) malloc(len))) {
-               return NULL;
-       }
-
-       memset(sret, 0, len);
-       snprintf(sret, len, "jingle+%s+%s", user, at);
-
-       free(ss);
-       
-
-       return sret;
-}
-
 static void do_invite(switch_core_session_t *session)
 {
        char rpid[1024] = { 0 };
@@ -892,7 +847,7 @@ static void do_invite(switch_core_session_t *session)
        private_object_t *tech_pvt;
     switch_channel_t *channel = NULL;
        switch_caller_profile_t *caller_profile;
-       char *cid_name, *cid_num_p = NULL, *cid_num;
+       char *cid_name, *cid_num;
        char *e_dest = NULL;
 
     channel = switch_core_session_get_channel(session);
@@ -906,10 +861,6 @@ static void do_invite(switch_core_session_t *session)
        cid_name = (char *) caller_profile->caller_id_name;
        cid_num = (char *) caller_profile->caller_id_number;
        
-       if ((cid_num_p = encode_name(cid_num))) {
-               cid_num = cid_num_p;
-       }
-
        if ((tech_pvt->from_str = switch_mprintf("\"%s\" <sip:%s@%s>", 
                                                                                                         cid_name,
                                                                                                         cid_num,
@@ -985,8 +936,6 @@ static void do_invite(switch_core_session_t *session)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
        }
        
-       switch_safe_free(cid_num_p);
-
 }
 
 
@@ -1861,7 +1810,7 @@ static const switch_endpoint_interface_t sofia_endpoint_interface = {
 };
 
 static const switch_chat_interface_t sofia_chat_interface = {
-       /*.name */ SOFIA_CHAT_NAME,
+       /*.name */ SOFIA_CHAT_PROTO,
        /*.chat_send */ chat_send,
        
 };
@@ -2192,6 +2141,11 @@ static void sip_i_message(int status,
                        to_host = (char *) to->a_url->url_host;
                }
 
+
+               if (!to_user) {
+                       return;
+               }
+
                if (payload) {
                        msg = payload->pl_data;
                }
@@ -2209,7 +2163,7 @@ static void sip_i_message(int status,
                        char *from_addr;
                        char *p;
                        char *full_from;
-                       char proto[512] = SOFIA_CHAT_NAME;
+                       char proto[512] = SOFIA_CHAT_PROTO;
                        
                        full_from = sip_header_as_string(profile->home, (void *)sip->sip_from);
 
@@ -2219,21 +2173,23 @@ static void sip_i_message(int status,
                                *p++ = '\0';
                                
                                if ((to_addr = strdup(p))) {
-                                       p = strchr(to_addr, '+');
-                                       *p = '@';
+                                       if((p = strchr(to_addr, '+'))) {
+                                               *p = '@';
+                                       }
                                }
                                
                        } else {
                                to_addr = switch_mprintf("%s@%s", to_user, to_host);
                        }
 
-                       from_addr = switch_mprintf("%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
+                       from_addr = switch_mprintf("%s@%s", from_user, from_host);
+
 
                        set_hash_key(hash_key, sizeof(hash_key), sip);
                        if ((tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) {
                                channel = switch_core_session_get_channel(tech_pvt->session);
                                if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
-                                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+                                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
                                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
                                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", tech_pvt->hash_key);
                                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to_addr);
@@ -2250,7 +2206,7 @@ static void sip_i_message(int status,
                                switch_chat_interface_t *ci;
                                
                                if ((ci = switch_loadable_module_get_chat_interface(proto))) {
-                                       ci->chat_send(from_addr, to_addr, "", msg, full_from);
+                                       ci->chat_send(SOFIA_CHAT_PROTO, from_addr, to_addr, "", msg, full_from);
                                } else {
                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invaid Chat Interface [%s]!\n", proto);
                                }
@@ -2594,7 +2550,7 @@ static char *get_auth_data(char *dbname, char *nonce, char *npassword, size_t le
 
        sql = switch_mprintf("select passwd from sip_authentication where nonce='%q'", nonce);
        
-       if(switch_core_db_prepare(db, sql, -1, &stmt, 0)) {
+       if (switch_core_db_prepare(db, sql, -1, &stmt, 0)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Statement Error!\n");
                goto fail;
        } else {
@@ -2858,7 +2814,7 @@ static uint8_t handle_register(nua_t *nua,
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
                        
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Registered");
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
@@ -2873,7 +2829,7 @@ static uint8_t handle_register(nua_t *nua,
                if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
-                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_PROTO, from_user, from_host);
                
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "unavailable");
                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
@@ -2903,18 +2859,18 @@ static uint8_t handle_register(nua_t *nua,
 static int sub_reg_callback(void *pArg, int argc, char **argv, char **columnNames)
 {
        sofia_profile_t *profile = (sofia_profile_t *) pArg;
-       char *from = argv[0];
-       char *status = argv[1];
+       //char *proto = argv[0];
+       char *user = argv[1];
+       char *host = argv[2];
        switch_event_t *event;
-
+       char *status = NULL;
        if (switch_strlen_zero(status)) {
                status = "Available";
        }
-
        if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
-               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", user, host);
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", status);
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
@@ -2924,6 +2880,28 @@ static int sub_reg_callback(void *pArg, int argc, char **argv, char **columnName
        return 0;
 }
 
+static int resub_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+       sofia_profile_t *profile = (sofia_profile_t *) pArg;
+       char *user = argv[0];
+       char *host = argv[1];
+       char *status = argv[2];
+       char *rpid = argv[3];
+       switch_event_t *event;
+
+       if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", user, host);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", status);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
+               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+               switch_event_fire(&event);
+       }
+
+       return 0;
+}
+
 static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
 {
        sofia_profile_t *profile = (sofia_profile_t *) pArg;
@@ -2958,7 +2936,7 @@ static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
                open = "closed";
        }
 
-       if (strcasecmp(proto, "sip")) {
+       if (strcasecmp(proto, SOFIA_CHAT_PROTO)) {
                /*encapsulate*/
                id = switch_mprintf("sip:%s+%s+%s@%s", proto, sub_to_user, sub_to_host, host);
        } else {
@@ -2985,7 +2963,6 @@ static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
 
        nh = nua_handle(profile->nua, NULL,     TAG_END());
                                        
-               
        nua_notify(nh,
                           NUTAG_URL(contact),
                           SIPTAG_TO_STR(full_from),
@@ -3069,11 +3046,13 @@ static void sip_i_subscribe(int status,
                        }
 
                        if (strchr(to_user, '+')) {
+                               char *h;
                                if ((proto = (d_user = strdup(to_user)))) {
                                        if ((to_user = strchr(d_user, '+'))) {
                                                *to_user++ = '\0';
-                                               if ((to_host = strchr(to_user, '+'))) {
-                                                       *to_host++ = '\0';
+                                               if ((h = strchr(to_user, '+')) || (h = strchr(to_user, '@'))) {
+                                                       *h++ = '\0';
+                                                       to_host = h;
                                                }
                                        }
                                }
@@ -3113,7 +3092,7 @@ static void sip_i_subscribe(int status,
                                                                                          full_from,
                                                                                          full_via,
                                                                                          exp
-                                                                                         ))) {
+                                                                         ))) {
                                execute_sql(profile->dbname, sql, profile->ireg_mutex);
                                switch_safe_free(sql);
                        }
@@ -3133,7 +3112,7 @@ static void sip_i_subscribe(int status,
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
                                goto end;
                        }
-                       if ((sql = switch_mprintf("select 'sip+%q@%q',status,rpid from sip_registrations where user='%q' and host='%q'", 
+                       if ((sql = switch_mprintf("select * from sip_subscriptions where user='%q' and host='%q'", 
                                                                          to_user, to_host, to_user, to_host))) {
                                switch_mutex_lock(profile->ireg_mutex);
                                switch_core_db_exec(db, sql, sub_reg_callback, profile, &errmsg);
@@ -3501,10 +3480,10 @@ static void sip_i_publish(nua_t *nua,
 
                                if (in) {
                                        if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
-                                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+                                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
                                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
                                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
-                                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
+                                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
                                                
                                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", note_txt);
                                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "%s", event_type);
@@ -3512,10 +3491,10 @@ static void sip_i_publish(nua_t *nua,
                                        }
                                } else {
                                        if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
-                                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+                                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
                                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
                                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
-                                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
+                                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
 
                                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "%s", event_type);
                                                switch_event_fire(&event);
@@ -3681,7 +3660,7 @@ static void sip_i_invite(nua_t *nua,
                                                                        if (!strncasecmp(argv[x], "privacy=", 8)) {
                                                                                char *arg = argv[x] + 9;
 
-                                                                               if(!strcasecmp(arg, "no")) {
+                                                                               if (!strcasecmp(arg, "no")) {
                                                                                        switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME);
                                                                                        switch_clear_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NUMBER);
                                                                                } else if (!strcasecmp(arg, "yes")) {
@@ -4162,10 +4141,7 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
        switch_mutex_unlock(globals.hash_mutex);
 
        if (profile->pflags & PFLAG_PRESENCE) {
-               if (switch_event_create(&s_event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
-                       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_NAME);
-                       switch_event_fire(&s_event);
-               }
+               establish_presence(profile);
        }
 
        while(globals.running == 1) {
@@ -4542,13 +4518,14 @@ static void event_handler(switch_event_t *event)
 }
 
 
-static switch_status_t chat_send(char *from, char *to, char *subject, char *body, char *hint)
+static switch_status_t chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint)
 {
        char buf[256];
        char *user, *host;
        sofia_profile_t *profile;
-       char *from_p = NULL, *from_pp = NULL, *from_ppp = NULL;
-       
+       char *ffrom = NULL;
+       nua_handle_t *msg_nh;
+
        if (to && (user = strdup(to))) {
                if ((host = strchr(user, '@'))) {
                        *host++ = '\0';
@@ -4559,48 +4536,47 @@ static switch_status_t chat_send(char *from, char *to, char *subject, char *body
                        return SWITCH_STATUS_FALSE;
                }
 
-               if (find_reg_url(profile, user, host, buf, sizeof(buf))) {
-                       nua_handle_t *msg_nh;
-                       
-                       if ((from_p = encode_name(from))) {
-                               char *p, *q = NULL;
-
-                               from_ppp = strdup(from_p);
-                               if ((p = strchr(from_ppp, '+'))) {
-                                       *p++ = '\0';
-                                       if ((q = strchr(p, '+'))) {
-                                               *q = '@';
-                                       }
-                               }
-                               if (!p) {
-                                       p = from;
-                               }
-                               from_pp = switch_mprintf("\"%s\" <sip:%s@%s>", p, from_p, host);
-                               from = from_pp;
-                       } else {
-                               from = hint;
-                       }
+        if (!find_reg_url(profile, user, host, buf, sizeof(buf))) {
+                       return SWITCH_STATUS_FALSE;
+               }
 
+               if (!strcmp(proto, SOFIA_CHAT_PROTO)) {
+                       from = hint;
+               } else {
+                       char *fp, *p, *fu = NULL;
 
-                       msg_nh = nua_handle(profile->nua, NULL,
-                                                               SIPTAG_FROM_STR(from),
-                                                               NUTAG_URL(buf),
-                                                               SIPTAG_TO_STR(buf),
-                                                               SIPTAG_CONTACT_STR(profile->url),
-                                                               TAG_END());
+                       if (!(fp = strdup(from))) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+                               return SWITCH_STATUS_FALSE;
+                       }
 
-                       nua_message(msg_nh,
-                                               SIPTAG_CONTENT_TYPE_STR("text/html"),
-                                               SIPTAG_PAYLOAD_STR(body),
-                                               TAG_END());
-                               
-               } else {
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid chat dest");
+                       if ((p = strchr(fp, '@'))) {
+                               *p = '\0';
+                               fu = strdup(fp);
+                               *p = '+';
+                       }
+                       
+                       ffrom = switch_mprintf("\"%s\"<sip:%s+%s@%s>", fu, proto, fp, profile->name);                   
+                       from = ffrom;
+                       switch_safe_free(fu);
+                       switch_safe_free(fp);
                }
 
-               switch_safe_free(from_p);
-               switch_safe_free(from_pp);
-               switch_safe_free(from_ppp);
+               
+               msg_nh = nua_handle(profile->nua, NULL,
+                                                       SIPTAG_FROM_STR(from),
+                                                       NUTAG_URL(buf),
+                                                       SIPTAG_TO_STR(buf),
+                                                       SIPTAG_CONTACT_STR(profile->url),
+                                                       TAG_END());
+               
+               nua_message(msg_nh,
+                                       SIPTAG_CONTENT_TYPE_STR("text/html"),
+                                       SIPTAG_PAYLOAD_STR(body),
+                                       TAG_END());
+               
+               
+               switch_safe_free(ffrom);
                free(user);
        }
                
@@ -4637,6 +4613,28 @@ static void cancel_presence(void)
 
 }
 
+static void establish_presence(sofia_profile_t *profile) 
+{
+       char *sql, *errmsg = NULL;
+       switch_core_db_t *db;
+
+       if (!(db = switch_core_db_open_file(profile->dbname))) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
+               return;
+       }
+
+       if ((sql = switch_mprintf("select user,host,'Registered','unavailable' from sip_registrations"))) {
+               switch_mutex_lock(profile->ireg_mutex);
+               switch_core_db_exec(db, sql, resub_callback, profile, &errmsg);
+               switch_mutex_unlock(profile->ireg_mutex);
+               switch_safe_free(sql);
+       }
+
+       switch_core_db_close(db);
+
+}
+
+
 
 static char *translate_rpid(char *in, char *ext)
 {
@@ -4671,15 +4669,17 @@ static void pres_event_handler(switch_event_t *event)
        switch_hash_index_t *hi;
     void *val;
        char *from = switch_event_get_header(event, "from");
+       char *proto = switch_event_get_header(event, "proto");
        char *rpid = switch_event_get_header(event, "rpid");
        char *status= switch_event_get_header(event, "status");
        char *event_type = switch_event_get_header(event, "event_type");
-       char *sql = NULL, *sql2 = NULL;
+       //char *event_subtype = switch_event_get_header(event, "event_subtype");
+       char *sql = NULL;
        char *euser = NULL, *user = NULL, *host = NULL;
        char *errmsg;
-       char *resource;
        switch_core_db_t *db;
 
+
        if (rpid && !strcasecmp(rpid, "n/a")) {
                rpid = NULL;
        }
@@ -4690,7 +4690,7 @@ static void pres_event_handler(switch_event_t *event)
 
        if (rpid) {
                rpid = translate_rpid(rpid, status);
-       }
+       } 
 
        if (!status) {
                status = "Available";
@@ -4706,12 +4706,16 @@ static void pres_event_handler(switch_event_t *event)
                }
        }
 
+       if (!rpid) {
+               rpid = "unknown";
+       }
+
        if (event->event_id == SWITCH_EVENT_ROSTER) {
 
                if (from) {
-                       sql = switch_mprintf("select 1,'%q',%q',* from sip_subscriptions where event='presence' and full_from like '%%%q%%'", status, rpid, from);
+                       sql = switch_mprintf("select 1,'%q','%q',* from sip_subscriptions where event='presence' and full_from like '%%%q%%'", status, rpid, from);
                } else {
-                       sql = switch_mprintf("select 1,'%q',%q',* from sip_subscriptions where event='presence'", status, rpid);
+                       sql = switch_mprintf("select 1,'%q','%q',* from sip_subscriptions where event='presence'", status, rpid);
                }
 
                for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
@@ -4744,37 +4748,29 @@ static void pres_event_handler(switch_event_t *event)
        if ((user = strdup(from))) {
                if ((host = strchr(user, '@'))) {
                        *host++ = '\0';
-               }
-               if ((resource = strchr(host, '/'))) {
-                       *resource++ = '\0';
+               } else {
+                       switch_safe_free(user);
+                       return;
                }
                if ((euser = strchr(user, '+'))) {
                        euser++;
                } else {
                        euser = user;
                }
+               
        } else {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
                return;
        }
 
 
-
-       if (!host) {
-               switch_safe_free(user);
-               return;
-       }
-       
-
-
        switch(event->event_id) {
        case SWITCH_EVENT_PRESENCE_IN:
-               sql = switch_mprintf("select 1,'%q','%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'", 
-                                                        status , rpid, event_type, euser, host);
+               sql = switch_mprintf("select 1,'%q','%q',* from sip_subscriptions where proto='%q' and event='%q' and sub_to_user='%q' and sub_to_host='%q'", 
+                                                        status , rpid, proto, event_type, euser, host);
                break;
        case SWITCH_EVENT_PRESENCE_OUT:
-               sql = switch_mprintf("select 0,'%q','%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'", 
-                                                        status, rpid, event_type, euser, host);
+               sql = switch_mprintf("select 0,'%q','%q',* from sip_subscriptions where proto='%q' and event='%q' and sub_to_user='%q' and sub_to_host='%q'", 
+                                                        status, rpid, proto, event_type, euser, host);
                break;
        default:
                break;
@@ -4796,13 +4792,6 @@ static void pres_event_handler(switch_event_t *event)
                        switch_core_db_exec(db, sql, sub_callback, profile, &errmsg);
                        switch_mutex_unlock(profile->ireg_mutex);
                        
-                       
-                       if ((sql2 = switch_mprintf("select 'sip+%q@%q',status,rpid from sip_registrations where user='%q' and host='%q'", euser, host, user, host))) {
-                               switch_mutex_lock(profile->ireg_mutex);
-                               switch_core_db_exec(db, sql2, sub_reg_callback, profile, &errmsg);
-                               switch_mutex_unlock(profile->ireg_mutex);
-                               switch_safe_free(sql2);
-                       }
                        switch_core_db_close(db);
                }
        }