Author: ctrix Date: Wed Jan 14 17:39:21 2009 New Revision: 11206 Log: Airpe: reloadxml configuration event - bindings and handler Modified: freeswitch/branches/ctrix/mod_airpe/airpe_if_common.c freeswitch/branches/ctrix/mod_airpe/config/airpe.conf.xml freeswitch/branches/ctrix/mod_airpe/mod_airpe.c freeswitch/branches/ctrix/mod_airpe/mod_airpe.h Modified: freeswitch/branches/ctrix/mod_airpe/airpe_if_common.c ============================================================================== --- freeswitch/branches/ctrix/mod_airpe/airpe_if_common.c (original) +++ freeswitch/branches/ctrix/mod_airpe/airpe_if_common.c Wed Jan 14 17:39:21 2009 @@ -175,6 +175,8 @@ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "msg to airpe client %s: > %s\n", airpe->name, msg); status = airpe_skype_send_message(airpe->skype_window, msg); + /* Relax and calm down. Some skype clients don't like fast messages */ + switch_sleep(10000); return status; } Modified: freeswitch/branches/ctrix/mod_airpe/config/airpe.conf.xml ============================================================================== --- freeswitch/branches/ctrix/mod_airpe/config/airpe.conf.xml (original) +++ freeswitch/branches/ctrix/mod_airpe/config/airpe.conf.xml Wed Jan 14 17:39:21 2009 @@ -12,13 +12,17 @@ <clients> <client name="airpe1"> <!-- Print out as notices the client messages --> - <param name="debug" value="1"/> + <param name="debug" value="false"/> <!-- Where our calls will land --> <param name="dialplan" value="XML"/> <param name="context" value="default"/> <param name="destination" value="4321"/> + <!-- + The following params won't be affected by reloading xml + --> + <!-- Linux only --> <param name="X11-display" value=":101"/> @@ -32,5 +36,4 @@ <param name="skype-password" value="password"/> </client> </clients> - </configuration> Modified: freeswitch/branches/ctrix/mod_airpe/mod_airpe.c ============================================================================== --- freeswitch/branches/ctrix/mod_airpe/mod_airpe.c (original) +++ freeswitch/branches/ctrix/mod_airpe/mod_airpe.c Wed Jan 14 17:39:21 2009 @@ -630,7 +630,7 @@ CONFIGURATION *****************************************************************************/ -static switch_status_t load_config(void) { +static switch_status_t load_config( int reload ) { switch_xml_t cfg, xml, global_settings, @@ -695,11 +695,6 @@ continue; } - if ( (newconf = switch_core_hash_find(globals.interfaces_hash, name)) ) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Duplicated client %s. Skipping\n", name); - continue; - } - for (param = switch_xml_child(client, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); @@ -746,43 +741,62 @@ if ( !destination ) destination = globals.destination; - newconf = (airpe_interface_t *) switch_core_alloc( pool, sizeof(airpe_interface_t) ); + if ( reload ) { + newconf = airpe_find_interface(name); + } + else { + if ( (newconf = switch_core_hash_find(globals.interfaces_hash, name)) ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Duplicated client %s. Skipping\n", name); + continue; + } + } + + if ( !newconf ) { + newconf = (airpe_interface_t *) switch_core_alloc( pool, sizeof(airpe_interface_t) ); + if ( newconf ) + memset(newconf, 0, sizeof(airpe_interface_t)); + } + if ( newconf ) { switch_status_t status; - memset(newconf, 0, sizeof(airpe_interface_t)); - newconf->name = switch_core_strdup(pool, name); newconf->dialplan = switch_core_strdup(pool, dialplan); newconf->context = switch_core_strdup(pool, context); newconf->destination = switch_core_strdup(pool, destination); + newconf->debug = debug; + + if ( reload ) { + /* We won't update any other value on reload. */ + newconf->should_reload = 0; + continue; + } + newconf->skype_user = switch_core_strdup(pool, skype_user); newconf->skype_password = switch_core_strdup(pool, skype_password); newconf->X11_display = switch_core_strdup(pool, X11_display); newconf->audio_in_port = 0; newconf->audio_in_port = 0; - newconf->debug = debug; - newconf->skype_window = skype_window_alloc(pool); if ( newconf->skype_window ) { status = airpe_start_client(newconf); - if ( status == SWITCH_STATUS_SUCCESS ) { switch_core_hash_insert(globals.interfaces_hash, name, newconf); } else { - // LOG OUR ERROR + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Airpe: cannot start client %s.\n", newconf->name); } } else { - // LOG OUR ERROR + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Airpe: cannot alloc client %s.\n", newconf->name); } + } else { - //TODO LOG ERROR ABOUT CREATING INTERFACE + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Airpe: cannot alloc client %s.\n", newconf->name); } } @@ -792,11 +806,44 @@ return SWITCH_STATUS_SUCCESS; } +static void reloadxml_event_handler(switch_event_t *event) +{ + airpe_interface_t *airpe; + switch_hash_index_t *hi; + void *val; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reloading airpe configuration.\n"); + + /* First, mark all of them to be reloaded */ + for (hi = switch_hash_first(NULL, globals.interfaces_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, NULL, NULL, &val); + airpe = ( airpe_interface_t *) val; + airpe->should_reload = 1; + } + + /* Update the data of each client */ + load_config(1); + + /* Find eventual clients not updated and stop them */ + for (hi = switch_hash_first(NULL, globals.interfaces_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, NULL, NULL, &val); + airpe = ( airpe_interface_t *) val; + if ( airpe->should_reload ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Stopping airpe client %s.\n", airpe->name); + switch_core_hash_delete(globals.interfaces_hash, airpe->name); + airpe_stop_client(airpe); + } + } + +} + /***************************************************************************** MODULE INITIALIZATION FUNCTIONS *****************************************************************************/ +static switch_event_node_t *EVENT_NODE = NULL; + static switch_state_handler_table_t airpe_state_handlers = { /*.on_init */ channel_on_init, /*.on_routing */ channel_on_routing, @@ -829,7 +876,7 @@ switch_core_hash_init(&globals.interfaces_hash, pool); switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, pool); - load_config(); + load_config(0); *module_interface = switch_loadable_module_create_module_interface(pool, modname); @@ -839,6 +886,11 @@ airpe_endpoint_interface->io_routines = &airpe_io_routines; airpe_endpoint_interface->state_handler = &airpe_state_handlers; + if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, reloadxml_event_handler, NULL, &EVENT_NODE) != SWITCH_STATUS_SUCCESS)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind our reloadxml handler!\n"); + /* Not such severe to prevent loading */ + } + airpe_register_api( &*module_interface ); airpe_register_apps( &*module_interface ); @@ -855,6 +907,8 @@ pool = airpe_module_pool; + switch_event_unbind(&EVENT_NODE); + for (hi = switch_hash_first(NULL, globals.interfaces_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, NULL, NULL, &val); airpe = ( airpe_interface_t *) val; Modified: freeswitch/branches/ctrix/mod_airpe/mod_airpe.h ============================================================================== --- freeswitch/branches/ctrix/mod_airpe/mod_airpe.h (original) +++ freeswitch/branches/ctrix/mod_airpe/mod_airpe.h Wed Jan 14 17:39:21 2009 @@ -154,6 +154,7 @@ CALL_STATUS call_status; CONN_STATUS conn_status; + int should_reload; char *skype_version; char *mood_text; int active_call_id;