]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add auto ip-change detection and some other goodies
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 22 Jul 2008 22:23:50 +0000 (22:23 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 22 Jul 2008 22:23:50 +0000 (22:23 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9138 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_event.h
src/include/switch_types.h
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/event_handlers/mod_event_socket/mod_event_socket.c
src/switch_console.c
src/switch_core.c
src/switch_event.c

index c6df3f5c0d43b993d3507452aeedfcf04f61f3ac..a8e0164068ae6a9897f773d1ab9a340a7d9b614a 100644 (file)
@@ -225,6 +225,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_bind_removable(const char *id, swit
   \return SWITCH_STATUS_SUCCESS if the consumer was unbinded
 */
 SWITCH_DECLARE(switch_status_t) switch_event_unbind(switch_event_node_t **node);
+SWITCH_DECLARE(switch_status_t) switch_event_unbind_callback(switch_event_callback_t callback);
 
 /*!
   \brief Render the name of an event id enumeration
index bfcce98064d06266937cf7b172222c7a354ec1e6..2f94359430e21dd700b9d7d0777bffae31ac6fa3 100644 (file)
@@ -1055,6 +1055,8 @@ typedef uint32_t switch_io_flag_t;
        SWITCH_EVENT_EXE_SCHEDULE               - Something scheduled has been executed
        SWITCH_EVENT_RE_SCHEDULE                - Something scheduled has been rescheduled
        SWITCH_EVENT_RELOADXML                  - XML registry has been reloaded
+       SWITCH_EVENT_NOTIFY                             - Notification
+       SWITCH_EVENT_SEND_MESSAGE               - Message
     SWITCH_EVENT_ALL                           - All events at once
 </pre>
 
@@ -1109,6 +1111,8 @@ typedef enum {
        SWITCH_EVENT_EXE_SCHEDULE,
        SWITCH_EVENT_RE_SCHEDULE,
        SWITCH_EVENT_RELOADXML,
+       SWITCH_EVENT_NOTIFY,
+       SWITCH_EVENT_SEND_MESSAGE,
        SWITCH_EVENT_ALL
 } switch_event_types_t;
 
index 8143d40af7db248a94300d53623691e1c59a0caa..e4358a142792529499d368882b25a02b972918d9 100644 (file)
@@ -1388,6 +1388,11 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
                return SWITCH_STATUS_SUCCESS;
        }
 
+       if (argv[1] && !strcasecmp(argv[0], "restart") && !strcasecmp(argv[1], "all")) {
+               sofia_glue_restart_all_profiles();
+               return SWITCH_STATUS_SUCCESS;
+       }
+       
        if (switch_strlen_zero(profile_name) || !(profile = sofia_glue_find_profile(profile_name))) {
                stream->write_function(stream, "Invalid Profile [%s]", switch_str_nil(profile_name));
                return SWITCH_STATUS_SUCCESS;
@@ -2050,6 +2055,118 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
        return cause;
 }
 
+static void general_event_handler(switch_event_t *event)
+{
+       switch (event->event_id) {
+       case SWITCH_EVENT_NOTIFY:
+               {
+                       const char *profile_name = switch_event_get_header(event, "profile");
+                       const char *ct = switch_event_get_header(event, "content-type");
+                       const char *es = switch_event_get_header(event, "event-string");
+                       const char *user = switch_event_get_header(event, "user");
+                       const char *host = switch_event_get_header(event, "host");
+                       const char *body = switch_event_get_body(event);
+                       sofia_profile_t *profile;
+                       nua_handle_t *nh;
+
+                       if (profile_name && ct && es && body && user && host && (profile = sofia_glue_find_profile(profile_name))) {
+                               char *id = NULL;
+                               char *contact;
+                               char buf[512] = "";
+
+                               if (!sofia_reg_find_reg_url(profile, user, host, buf, sizeof(buf))) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find user %s@%s\n", user, host);
+                                       return;
+                               }
+
+                               id = switch_mprintf("sip:%s@%s", user, host);
+
+                               switch_assert(id);
+                               contact = sofia_glue_get_url_from_contact(buf, 0);
+                               
+                               nh = nua_handle(profile->nua, 
+                                                               NULL, 
+                                                               NUTAG_URL(contact), 
+                                                               SIPTAG_FROM_STR(id), 
+                                                               SIPTAG_TO_STR(id), 
+                                                               SIPTAG_CONTACT_STR(profile->url), 
+                                                               TAG_END());
+                               
+                               nua_notify(nh,
+                                                  NUTAG_NEWSUB(1),
+                                                  SIPTAG_EVENT_STR(es), 
+                                                  SIPTAG_CONTENT_TYPE_STR(ct), 
+                                                  SIPTAG_PAYLOAD_STR(body), 
+                                                  TAG_END());
+
+                               
+                               free(id);
+                               sofia_glue_release_profile(profile);
+                       }
+
+               }
+               break;
+       case SWITCH_EVENT_SEND_MESSAGE:
+               {
+                       const char *profile_name = switch_event_get_header(event, "profile");
+                       const char *ct = switch_event_get_header(event, "content-type");
+                       const char *user = switch_event_get_header(event, "user");
+                       const char *host = switch_event_get_header(event, "host");
+                       const char *body = switch_event_get_body(event);
+                       sofia_profile_t *profile;
+                       nua_handle_t *nh;
+
+                       if (profile_name && ct && body && user && host && (profile = sofia_glue_find_profile(profile_name))) {
+                               char *id = NULL;
+                               char *contact;
+                               char buf[512] = "";
+
+                               if (!sofia_reg_find_reg_url(profile, user, host, buf, sizeof(buf))) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find user %s@%s\n", user, host);
+                                       return;
+                               }
+
+                               id = switch_mprintf("sip:%s@%s", user, host);
+
+                               switch_assert(id);
+                               contact = sofia_glue_get_url_from_contact(buf, 0);
+                               
+                               nh = nua_handle(profile->nua, 
+                                                               NULL, 
+                                                               NUTAG_URL(contact), 
+                                                               SIPTAG_FROM_STR(id), 
+                                                               SIPTAG_TO_STR(id), 
+                                                               SIPTAG_CONTACT_STR(profile->url), 
+                                                               TAG_END());
+                               
+                               nua_message(nh,
+                                                       NUTAG_NEWSUB(1),
+                                                       SIPTAG_CONTENT_TYPE_STR(ct), 
+                                                       SIPTAG_PAYLOAD_STR(body), 
+                                                       TAG_END());
+
+                               
+                               free(id);
+                               sofia_glue_release_profile(profile);
+                       }
+
+               }
+               break;
+       case SWITCH_EVENT_TRAP:
+               {
+                       const char *cond = switch_event_get_header(event, "condition");
+
+                       if (cond && !strcmp(cond, "network-address-change")) {
+                               sofia_glue_restart_all_profiles();
+                       }
+                       
+               }
+               break;
+       default:
+               break;
+       }
+}
+
 SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
 {
        switch_chat_interface_t *chat_interface;
@@ -2087,37 +2204,53 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for profiles to start\n");
        switch_yield(1500000);
 
-       if (switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL, &mod_sofia_globals.custom_node) != SWITCH_STATUS_SUCCESS) {
+       if (switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL,
+                                                                       &mod_sofia_globals.custom_node) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
                return SWITCH_STATUS_TERM;
        }
 
-       if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL, &mod_sofia_globals.in_node)
-               != SWITCH_STATUS_SUCCESS) {
+       if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL,
+                                                                       &mod_sofia_globals.in_node) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
                return SWITCH_STATUS_GENERR;
        }
 
-       if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL, &mod_sofia_globals.out_node)
-               != SWITCH_STATUS_SUCCESS) {
+       if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL,
+                                                                       &mod_sofia_globals.out_node) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
                return SWITCH_STATUS_GENERR;
        }
 
-       if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL, &mod_sofia_globals.probe_node)
-               != SWITCH_STATUS_SUCCESS) {
+       if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL,
+                                                                       &mod_sofia_globals.probe_node) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
                return SWITCH_STATUS_GENERR;
        }
 
-       if (switch_event_bind_removable(modname, SWITCH_EVENT_ROSTER, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL, &mod_sofia_globals.roster_node)
-               != SWITCH_STATUS_SUCCESS) {
+       if (switch_event_bind_removable(modname, SWITCH_EVENT_ROSTER, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL,
+                                                                       &mod_sofia_globals.roster_node) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
                return SWITCH_STATUS_GENERR;
        }
 
-       if (switch_event_bind_removable(modname, SWITCH_EVENT_MESSAGE_WAITING, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_mwi_event_handler, NULL, &mod_sofia_globals.mwi_node)
-               != SWITCH_STATUS_SUCCESS) {
+       if (switch_event_bind_removable(modname, SWITCH_EVENT_MESSAGE_WAITING, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_mwi_event_handler, NULL,
+                                                                       &mod_sofia_globals.mwi_node) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
+               return SWITCH_STATUS_GENERR;
+       }
+
+       if (switch_event_bind(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
+               return SWITCH_STATUS_GENERR;
+       }
+
+       if (switch_event_bind(modname, SWITCH_EVENT_NOTIFY, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
+               return SWITCH_STATUS_GENERR;
+       }
+
+       if (switch_event_bind(modname, SWITCH_EVENT_SEND_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
                return SWITCH_STATUS_GENERR;
        }
@@ -2138,6 +2271,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
        switch_console_set_complete("add sofia status");
        switch_console_set_complete("add sofia loglevel");
        switch_console_set_complete("add sofia profile");
+       switch_console_set_complete("add sofia profile restart all");
 
        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);
@@ -2162,7 +2296,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
        switch_event_unbind(&mod_sofia_globals.roster_node);
        switch_event_unbind(&mod_sofia_globals.custom_node);
        switch_event_unbind(&mod_sofia_globals.mwi_node);
-
+       switch_event_unbind_callback(general_event_handler);
+       
        while (mod_sofia_globals.threads) {
                switch_yield(1000);
                if (++sanity >= 10000) {
index f745bfdf027de50b6b0ae15179653148dc7c7afc..fc2e19e940a36e8aa62ea5cec01a9fb8412817e4 100644 (file)
@@ -610,7 +610,7 @@ switch_status_t sofia_glue_add_profile(char *key, sofia_profile_t *profile);
 void sofia_glue_release_profile__(const char *file, const char *func, int line, sofia_profile_t *profile);
 #define sofia_glue_release_profile(x) sofia_glue_release_profile__(__FILE__, __SWITCH_FUNC__, __LINE__,  x)
 
-sofia_profile_t *sofia_glue_find_profile__(const char *file, const char *func, int line, char *key);
+sofia_profile_t *sofia_glue_find_profile__(const char *file, const char *func, int line, const char *key);
 #define sofia_glue_find_profile(x) sofia_glue_find_profile__(__FILE__, __SWITCH_FUNC__, __LINE__,  x)
 
 switch_status_t sofia_reg_add_gateway(char *key, sofia_gateway_t *gateway);
@@ -672,3 +672,4 @@ const char *sofia_glue_strip_proto(const char *uri);
 switch_status_t reconfig_sofia(sofia_profile_t *profile);
 void sofia_glue_del_gateway(sofia_gateway_t *gp);
 void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent);
+void sofia_glue_restart_all_profiles(void);
index 9fd82ecde8d30be2d3b7236a44d6a32f03821856..a79bc59aa3a65ef9cd90fe7f79a72f608cc4dd62 100644 (file)
@@ -528,7 +528,14 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
        profile->nua = nua_create(profile->s_root,      /* Event loop */
                                                          sofia_event_callback, /* Callback for processing events */
                                                          profile,      /* Additional data to pass to callback */
-                                                         NUTAG_URL(profile->bindurl), TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), NUTAG_SIPS_URL(profile->tls_bindurl)), TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), NUTAG_CERTIFICATE_DIR(profile->tls_cert_dir)), TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), TPTAG_TLS_VERSION(profile->tls_version)), NTATAG_UDP_MTU(65536), NTATAG_SERVER_RPORT(profile->rport_level), TAG_IF(tportlog, TPTAG_LOG(1)), TAG_END());     /* Last tag should always finish the sequence */
+                                                         NUTAG_URL(profile->bindurl),
+                                                         TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), NUTAG_SIPS_URL(profile->tls_bindurl)), 
+                                                         TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), NUTAG_CERTIFICATE_DIR(profile->tls_cert_dir)), 
+                                                         TAG_IF(sofia_test_pflag(profile, PFLAG_TLS), TPTAG_TLS_VERSION(profile->tls_version)), 
+                                                         NTATAG_UDP_MTU(65536), 
+                                                         NTATAG_SERVER_RPORT(profile->rport_level), 
+                                                         TAG_IF(tportlog, TPTAG_LOG(1)), 
+                                                         TAG_END());   /* Last tag should always finish the sequence */
 
        if (!profile->nua) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Creating SIP UA for profile: %s\n", profile->name);
index 73c2bf712d589c4a868ca55e7d6c898ff17f3dd9..216e54a6a7b84bc50fa2511b414c724db18a46b6 100644 (file)
@@ -2549,7 +2549,7 @@ char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup)
        return url;
 }
 
-sofia_profile_t *sofia_glue_find_profile__(const char *file, const char *func, int line, char *key)
+sofia_profile_t *sofia_glue_find_profile__(const char *file, const char *func, int line, const char *key)
 {
        sofia_profile_t *profile;
 
@@ -2620,6 +2620,34 @@ void sofia_glue_del_gateway(sofia_gateway_t *gp)
        }
 }
 
+void sofia_glue_restart_all_profiles(void) 
+{
+       switch_hash_index_t *hi;
+       const void *var;
+    void *val;
+    sofia_profile_t *pptr;
+       switch_xml_t xml_root;
+       const char *err;
+
+       if ((xml_root = switch_xml_open_root(1, &err))) {
+               switch_xml_free(xml_root);
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Reload XML [%s]\n", err);
+       }
+
+       switch_mutex_lock(mod_sofia_globals.hash_mutex);
+       if (mod_sofia_globals.profile_hash) {
+        for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+                       switch_hash_this(hi, &var, NULL, &val);
+            if ((pptr = (sofia_profile_t *) val)) {
+                               sofia_set_pflag_locked(pptr, PFLAG_RESPAWN);
+                               sofia_clear_pflag_locked(pptr, PFLAG_RUNNING);
+                       }
+               }
+       }
+       switch_mutex_unlock(mod_sofia_globals.hash_mutex);
+
+}
+
 void sofia_glue_del_profile(sofia_profile_t *profile)
 {
        sofia_gateway_t *gp;
index 3bcb39ef4ca3e6ef2420e27750e818d0b9f90cf7..140bfb7f7d7f97d41117edfd468a890cf560cfee 100644 (file)
@@ -408,6 +408,8 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event,
        uint8_t crcount = 0;
        uint32_t max_len = sizeof(mbuf);
        switch_channel_t *channel = NULL;
+       int clen = 0;
+       
        *event = NULL;
        start = switch_timestamp(NULL);
        ptr = mbuf;
@@ -480,16 +482,50 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event,
                                                        }
                                                        if (var && val) {
                                                                switch_event_add_header(*event, SWITCH_STACK_BOTTOM, var, "%s", val);
+                                                               if (!strcasecmp(var, "content-length")) {
+                                                                       clen = atoi(val);
+                                                                       
+                                                                       if (clen > 0) {
+                                                                               char *body = malloc(clen + 1);
+                                                                               char *ptr = body;
+                                                                               
+                                                                               switch_assert(body);
+
+                                                                               while(clen > 0) {
+                                                                                       mlen = clen;
+                                                                                       
+                                                                                       status = switch_socket_recv(listener->sock, ptr, &mlen);
+
+                                                                                       if (!SWITCH_STATUS_IS_BREAK(status) && status != SWITCH_STATUS_SUCCESS) {
+                                                                                               return SWITCH_STATUS_FALSE;
+                                                                                       }
+                               
+                                                                                       if (channel && !switch_channel_ready(channel)) {
+                                                                                               status = SWITCH_STATUS_FALSE;
+                                                                                               break;
+                                                                                       }
+
+                                                                                       clen -= (int) mlen;
+                                                                                       ptr += mlen;
+                                                                               }
+
+                                                                               switch_event_add_body(*event, "%s", body);
+                                                                               free(body);
+                                                                       }
+
+
+
+                                                               }
                                                        }
                                                }
                                        }
-
+                                       
                                        cur = next;
                                }
                                break;
                        }
                }
-
+               
                if (timeout) {
                        elapsed = (uint32_t) (switch_timestamp(NULL) - start);
                        if (elapsed >= timeout) {
index e70dfb0f5464dfade9f73e8065c3286ebbc85ea9..211afeb34ef13d5dd6f88aa5bb3d841eae234b1f 100644 (file)
@@ -467,12 +467,14 @@ static int comp_callback(void *pArg, int argc, char **argv, char **columnNames)
                return -1;
        }
 
-       fprintf(h->out, "%20s\t", target);
+       fprintf(h->out, "[%20s]\t", target);
 
        switch_copy_string(h->last, target, sizeof(h->last));
 
-       if ((++h->hits % 4) == 0) {
-               fprintf(h->out, "\n");
+       if (!switch_strlen_zero(target)) {
+               if ((++h->hits % 4) == 0) {
+                       fprintf(h->out, "\n");
+               }
        }
 
        return 0;
index 9a6801ed456617102fac123fc9bb11ea3143f963..ee6ed580e4207f348ad262085e91a946957ef233 100644 (file)
@@ -76,9 +76,55 @@ static void send_heartbeat(void)
        }
 }
 
+static char main_ip4[256] = "";
+static char main_ip6[256] = "";
+
+static void check_ip(void) {
+       char guess_ip4[256] = "";
+       char guess_ip6[256] = "";
+       int ok4 = 1, ok6 = 1;
+       
+       switch_find_local_ip(guess_ip4, sizeof(guess_ip4), AF_INET);
+       switch_find_local_ip(guess_ip6, sizeof(guess_ip6), AF_INET6);
+
+       if (!*main_ip4) {
+               switch_set_string(main_ip4, guess_ip4);
+       } else {
+               if (!(ok4 = !strcmp(main_ip4, guess_ip4))) {
+                       switch_set_string(main_ip4, guess_ip4);
+                       switch_core_set_variable("local_ip_v4", guess_ip4);
+               }
+       }
+
+       if (!*main_ip6) {
+               switch_set_string(main_ip6, guess_ip6);
+       } else {
+               if (!(ok6 = !strcmp(main_ip6, guess_ip6))) {
+                       switch_set_string(main_ip6, guess_ip6);
+                       switch_core_set_variable("local_ip_v4", guess_ip6);
+               }
+       }
+       
+       if (!ok4 || !ok6) {
+               switch_event_t *event;
+
+               if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "condition", "network-address-change");
+                       if (!ok4) {
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "network-address-change-v4", "%s", main_ip4);
+                       }
+                       if (!ok6) {
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "network-address-change-v6", "%s", main_ip6);
+                       }
+                       switch_event_fire(&event);
+               }
+       }
+}
+
 SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback)
 {
        send_heartbeat();
+       check_ip();
 
        /* reschedule this task */
        task->runtime = switch_timestamp(NULL) + 20;
index adc9c21b948b289da07471e6711c5b2589dea725..b2cf83bf9dbe95c733511ecbe4679ee83464b6c5 100644 (file)
@@ -155,6 +155,8 @@ static char *EVENT_NAMES[] = {
        "EXE_SCHEDULE",
        "RE_SCHEDULE",
        "RELOADXML",
+       "NOTIFY",
+       "SEND_MESSAGE",
        "ALL"
 };
 
@@ -1068,6 +1070,46 @@ SWITCH_DECLARE(switch_status_t) switch_event_bind(const char *id, switch_event_t
 }
 
 
+SWITCH_DECLARE(switch_status_t) switch_event_unbind_callback(switch_event_callback_t callback)
+{
+       switch_event_node_t *n, *np, *lnp = NULL;
+       switch_status_t status = SWITCH_STATUS_FALSE;
+       int id;
+
+       switch_thread_rwlock_wrlock(RWLOCK);
+       switch_mutex_lock(BLOCK);
+       /* <LOCKED> ----------------------------------------------- */
+       for (id = 0; id < SWITCH_EVENT_ALL; id++) {
+               lnp = NULL;
+
+               for (np = EVENT_NODES[id]; np;) {
+                       n = np;
+                       np = np->next;
+                       if (n->callback == callback) {
+                               if (lnp) {
+                                       lnp->next = n->next;
+                               } else {
+                                       EVENT_NODES[n->event_id] = n->next;
+                               }
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Event Binding deleted for %s:%s\n", n->id, switch_event_name(n->event_id));
+                               n->subclass = NULL;
+                               FREE(n->id);
+                               FREE(n);
+                               status = SWITCH_STATUS_SUCCESS;
+                       } else {
+                               lnp = n;
+                       }
+               }
+       }
+       switch_mutex_unlock(BLOCK);
+       switch_thread_rwlock_unlock(RWLOCK);
+       /* </LOCKED> ----------------------------------------------- */
+
+       return status;
+}
+
+
+
 SWITCH_DECLARE(switch_status_t) switch_event_unbind(switch_event_node_t **node)
 {
        switch_event_node_t *n, *np, *lnp = NULL;