Author: ctrix Date: Sat Jan 17 19:03:30 2009 New Revision: 11269 Log: Work in progress Modified: freeswitch/branches/ctrix/mod_airpe/airpe_if_common.c freeswitch/branches/ctrix/mod_airpe/airpe_if_x11.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 Sat Jan 17 19:03:30 2009 @@ -170,6 +170,9 @@ switch_status_t airpe_cmd_write(airpe_interface_t *airpe, char *msg) { switch_status_t status; +//TODO locking + + assert(airpe); if ( airpe->debug ) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "msg to airpe client %s: > %s\n", airpe->name, msg); Modified: freeswitch/branches/ctrix/mod_airpe/airpe_if_x11.c ============================================================================== --- freeswitch/branches/ctrix/mod_airpe/airpe_if_x11.c (original) +++ freeswitch/branches/ctrix/mod_airpe/airpe_if_x11.c Sat Jan 17 19:03:30 2009 @@ -268,7 +268,6 @@ airpe->running = 1; XFlush(disp); x11_fd = ConnectionNumber(disp); - while ( airpe->running ) { FD_ZERO(&rset); FD_SET( x11_fd, &rset); 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 Sat Jan 17 19:03:30 2009 @@ -1,4 +1,5 @@ <configuration name="airpe.conf" description="Airpe Configuration"> + <globals> <param name="audio-tcp-port_start" value="21000"/> @@ -35,6 +36,14 @@ The purpose is restarting the client with those credentials --> <param name="skype-user" value="username"/> <param name="skype-password" value="password"/> + + <!--all variables here will be set on all inbound calls that originate from this client --> + <variables> + <variable name="variable" value="default"/> + <variable name="process_cdr" value="false"/> + </variables> + </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 Sat Jan 17 19:03:30 2009 @@ -59,6 +59,20 @@ TECH STUFF *****************************************************************************/ +static int fetch_next_port(void) { + int port = 0; + + if ( !globals.last_port_used ) + globals.last_port_used = globals.audio_tcp_port_start; + + switch_mutex_lock(globals.mutex); + port = globals.last_port_used; + globals.last_port_used++; + switch_mutex_unlock(globals.mutex); + + return port; +} + static switch_status_t airpe_codec_init(private_object_t * tech_pvt, int sample_rate, int codec_ms) { airpe_interface_t *airpe = NULL; @@ -139,20 +153,6 @@ return new_sock; } -static int fetch_next_port(void) { - int port = 0; - - if ( !globals.last_port_used ) - globals.last_port_used = globals.audio_tcp_port_start; - - switch_mutex_lock(globals.mutex); - port = globals.last_port_used; - globals.last_port_used++; - switch_mutex_unlock(globals.mutex); - - return port; -} - static switch_status_t airpe_audio_sockets_create( airpe_interface_t *airpe ) { switch_socket_t *new_sock; int port; @@ -185,7 +185,7 @@ } -static switch_status_t airpe_start_client(airpe_interface_t *airpe) { +static switch_status_t airpe_create_client(airpe_interface_t *airpe) { switch_threadattr_t *attr_skype = NULL; @@ -198,16 +198,20 @@ switch_threadattr_create(&attr_skype, airpe_module_pool); switch_threadattr_stacksize_set(attr_skype, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&airpe->airpe_thread_skype, + return switch_thread_create(&airpe->airpe_thread_skype, attr_skype, airpe_skype_thread, airpe, airpe_module_pool); - - return SWITCH_STATUS_SUCCESS; } -static switch_status_t airpe_stop_client(airpe_interface_t *airpe) { +static switch_status_t airpe_destroy_client(airpe_interface_t *airpe) { + + if ( airpe->active_call_id ) { + char buf[SKYPE_MSG_LEN] = ""; + snprintf(buf, sizeof(buf), "ALTER CALL %d END HANGUP", airpe->active_call_id ); + airpe_cmd_write(airpe, buf); + } if ( airpe->audio_in_socket ) { if ( airpe->debug ) @@ -229,7 +233,9 @@ airpe_set_mood_text(airpe, NULL); airpe_set_partner_displayname(airpe, NULL); airpe_set_partner_handle(airpe, NULL); - airpe_set_call_id(airpe, 0, NULL); + airpe_clear_call_id(airpe); + + switch_core_hash_destroy(&airpe->variables_hash); return SWITCH_STATUS_SUCCESS; } @@ -632,14 +638,17 @@ CONFIGURATION *****************************************************************************/ -static switch_status_t load_config( int reload ) { +static switch_status_t load_config(void) { switch_xml_t cfg, xml, global_settings, param, clients, - client; + client, + variables, + variable; switch_memory_pool_t *pool; + switch_status_t status; pool = airpe_module_pool; @@ -679,131 +688,112 @@ for (client = switch_xml_child(clients, "client"); client; client = client->next) { - char *name = (char *) switch_xml_attr(client, "name"); - char *context = NULL; - char *dialplan = NULL; - char *destination = NULL; - char *X11_display = NULL; - char *skype_user = NULL; - char *skype_password= NULL; - char *cid_name = NULL; - char *cid_num = NULL; - int auto_auth = 0; - int debug = 0; + airpe_interface_t *newconf = NULL; - airpe_interface_t *newconf = NULL; + char *name = (char *) switch_xml_attr(client, "name"); - if (!name) { + if ( switch_strlen_zero(name) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No name attribute. Skipping unnamed client.\n"); 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; + } + + /* If we don't have a new interface, yet, then create one */ + if ( !newconf ) { + newconf = (airpe_interface_t *) switch_core_alloc( pool, sizeof(airpe_interface_t) ); + if ( newconf ) + memset(newconf, 0, sizeof(airpe_interface_t)); + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot alloc memory for the new interface %s\n", name); + continue; + } + } + + /* Start parsing our parameters */ + + newconf->name = switch_core_strdup(pool, name); + 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"); if (!strcasecmp(var, "debug")) { - debug = switch_true(val) ? 1 : 0; + newconf->debug = switch_true(val) ? 1 : 0; } else if (!strcasecmp(var, "auto-auth")) { - auto_auth = switch_true(val) ? 1 : 0; + newconf->auto_auth = switch_true(val) ? 1 : 0; } else if (!strcasecmp(var, "context")) { - context = val; + newconf->context = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "dialplan")) { - dialplan = val; + newconf->dialplan = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "destination")) { - destination = val; + newconf->destination = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "skype-user")) { - skype_user = val; + newconf->skype_user = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "skype-password")) { - skype_password = val; + newconf->skype_password = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "X11-display")) { - X11_display = val; + newconf->X11_display = switch_core_strdup(pool, val); } else if (!strcasecmp(var, "cid-name")) { - cid_name = val; + //cid_name = val; } else if (!strcasecmp(var, "cid-num")) { - cid_num = val; + //cid_num = val; } else switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown config param %s\n", var); } - if (!skype_user) { + + if (!newconf->skype_user) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No skype-user param for client %s. Skipping\n", name); continue; } - if (!skype_password) { + if (!newconf->skype_password) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No skype-password param for client %s. Skipping\n", name); continue; } - if (!X11_display) { + if (!newconf->X11_display) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No X11-display param for client %s. Skipping\n", name); continue; } - if ( !dialplan ) - dialplan = globals.dialplan; - if ( !context ) - context = globals.context; - if ( !destination ) - destination = globals.destination; + if ( !newconf->dialplan ) + newconf->dialplan = globals.dialplan; + if ( !newconf->context ) + newconf->context = globals.context; + if ( !newconf->destination ) + newconf->destination = globals.destination; + + newconf->audio_in_port = 0; + newconf->audio_in_port = 0; + + switch_core_hash_init(&newconf->variables_hash, pool); + if ((variables = switch_xml_child(client, "variables"))) { + for (variable = switch_xml_child(variables, "variable"); variable; variable = variable->next) + { + char *vname = (char *) switch_xml_attr(variable, "name"); + char *vvalue = (char *) switch_xml_attr(variable, "value"); - 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 ( !switch_strlen_zero(vname) && vvalue ) { + switch_core_hash_insert(newconf->variables_hash, vname, vvalue); + } } } - 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; - - 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->auto_auth = auto_auth; - 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->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 { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Airpe: cannot start client %s.\n", newconf->name); - } + /* Start the thread managing the skype client */ + newconf->skype_window = skype_window_alloc(pool); + if ( newconf->skype_window ) { + status = airpe_create_client(newconf); + if ( status == SWITCH_STATUS_SUCCESS ) { + switch_core_hash_insert(globals.interfaces_hash, name, newconf); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Airpe: cannot alloc client %s.\n", newconf->name); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Airpe: cannot start client %s.\n", newconf->name); } - - - } - else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Airpe: cannot alloc client %s.\n", newconf->name); } + } } @@ -828,7 +818,7 @@ } /* Update the data of each client */ - load_config(1); +// 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)) { @@ -837,10 +827,9 @@ 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); + airpe_destroy_client(airpe); } } - } @@ -882,7 +871,7 @@ switch_core_hash_init(&globals.interfaces_hash, pool); switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, pool); - load_config(0); + load_config(); *module_interface = switch_loadable_module_create_module_interface(pool, modname); @@ -893,14 +882,13 @@ 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)) { + /* Not such severe to prevent loading, so don't abort */ 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 ); - return SWITCH_STATUS_SUCCESS; } @@ -922,7 +910,7 @@ airpe->running = 0; /* Wake up the socket */ airpe_cmd_write(airpe, "PING"); - airpe_stop_client(airpe); + airpe_destroy_client(airpe); /* we won't delete the hash element. we're going to destroy the whole pool switch_core_hash_delete(globals.interfaces_hash, airpe->name); 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 Sat Jan 17 19:03:30 2009 @@ -138,11 +138,12 @@ char *dialplan; char *context; char *destination; + int auto_auth; char *X11_display; char *skype_user; char *skype_password; - int auto_auth; + switch_mutex_t *mutex; int audio_in_port; int audio_out_port; switch_socket_t *audio_in_socket; @@ -153,6 +154,7 @@ switch_thread_t *airpe_thread_skype; skype_window_handler_t *skype_window; + switch_hash_t *variables_hash; int protocol; USER_STATUS user_status; CALL_STATUS call_status; @@ -208,6 +210,7 @@ switch_status_t airpe_set_mood_text(airpe_interface_t *airpe, char *string); switch_status_t airpe_set_partner_displayname(airpe_interface_t *airpe, char *string); switch_status_t airpe_set_partner_handle(airpe_interface_t *airpe, char *string); +void airpe_clear_call_id(airpe_interface_t *airpe); switch_status_t airpe_set_call_id(airpe_interface_t *airpe, int sk_id, char *fs_uuid); switch_status_t airpe_call_shutdown( private_object_t *pvt );