Revision
14367
Author
gmaruzz
Date
2009-07-26 18:45:27 -0500 (Sun, 26 Jul 2009)

Log Message

skypiax: patch from Muhammad Shahzad for adding and removing interfaces on the fly: It basically adds two sk commands, sk reload => this re-reads Skypiax configuration file skypiax.conf.xml and adds ONLY new interfaces it found in conf. All existing interfaces are not touched. sk remove <skype-user> => this remove skypiax interface associated with given Skype user account, if it is idle. 

Modified Paths

Diff

Modified: freeswitch/trunk/src/mod/endpoints/mod_skypiax/mod_skypiax.c (14366 => 14367)


--- freeswitch/trunk/src/mod/endpoints/mod_skypiax/mod_skypiax.c	2009-07-26 16:31:03 UTC (rev 14366)
+++ freeswitch/trunk/src/mod/endpoints/mod_skypiax/mod_skypiax.c	2009-07-26 23:45:27 UTC (rev 14367)
@@ -95,10 +95,17 @@
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skypiax_shutdown);
 SWITCH_MODULE_DEFINITION(mod_skypiax, mod_skypiax_load, mod_skypiax_shutdown, NULL);
 SWITCH_STANDARD_API(sk_function);
-#define SK_SYNTAX "list || console || skype_API_msg"
+/* BEGIN: Changes here */
+#define SK_SYNTAX "list || reload || console || remove interface_name || skype_API_msg"
+/* END: Changes heres */
 SWITCH_STANDARD_API(skypiax_function);
 #define SKYPIAX_SYNTAX "interface_name skype_API_msg"
 
+/* BEGIN: Changes here */
+#define FULL_RELOAD 0
+#define SOFT_RELOAD 1
+/* END: Changes heres */
+
 static struct {
   int debug;
   char *ip;
@@ -132,6 +139,11 @@
 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string,
                                   globals.codec_rates_string);
 
+/* BEGIN: Changes here */
+static switch_status_t interface_exists(char* skype_user);
+static switch_status_t remove_interface(char* skype_user);
+/* END: Changes here */
+
 static switch_status_t channel_on_init(switch_core_session_t * session);
 static switch_status_t channel_on_hangup(switch_core_session_t * session);
 static switch_status_t channel_on_destroy(switch_core_session_t * session);
@@ -208,6 +220,96 @@
 
 }
 
+/* BEGIN: Changes here */
+static switch_status_t interface_exists(char* skype_user) {
+	int i;
+	for (i = 0; i < SKYPIAX_MAX_INTERFACES; i++) {
+		if (strlen(globals.SKYPIAX_INTERFACES[i].name)) {
+			if(strcmp(globals.SKYPIAX_INTERFACES[i].skype_user, skype_user) == 0) {
+				return SWITCH_STATUS_SUCCESS;
+			}
+		}
+	}
+	return SWITCH_STATUS_FALSE;
+}
+
+static switch_status_t remove_interface(char* skype_user) {
+	int x = 100;
+	unsigned int howmany = 8;
+	int interface_id = -1;
+	private_t *tech_pvt = NULL;
+	switch_status_t status;
+
+	running = 0;
+
+	for (interface_id = 0; interface_id < SKYPIAX_MAX_INTERFACES; interface_id++) {
+		if(strcmp(globals.SKYPIAX_INTERFACES[interface_id].skype_user, skype_user) == 0) {
+			tech_pvt = &globals.SKYPIAX_INTERFACES[interface_id];
+			break;
+		}
+	}
+
+	if(!tech_pvt) {
+		DEBUGA_SKYPE("interface for skype user '%s' does not exist\n", SKYPIAX_P_LOG, skype_user);
+		goto end;
+	}
+
+	if (strlen(globals.SKYPIAX_INTERFACES[interface_id].session_uuid_str)) {
+		DEBUGA_SKYPE("interface for skype user '%s' is busy\n", SKYPIAX_P_LOG, skype_user);
+		goto end;
+	}
+
+	if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread) {
+#ifdef WIN32
+		switch_file_write(tech_pvt->SkypiaxHandles.fdesc[1], "sciutati", &howmany);   // let's the controldev_thread die
+#else /* WIN32 */
+		howmany = write(tech_pvt->SkypiaxHandles.fdesc[1], "sciutati", howmany);
+#endif /* WIN32 */
+	}
+
+	if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread) {
+#ifdef WIN32
+		if (SendMessage(tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, WM_DESTROY, 0, 0) == FALSE) {  // let's the skypiax_api_thread_func die
+			DEBUGA_SKYPE("got FALSE here, thread probably was already dead. GetLastError returned: %d\n",
+					SKYPIAX_P_LOG, GetLastError());
+			globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread = NULL;
+		}
+#else
+		XEvent e;
+		Atom atom1 = XInternAtom(tech_pvt->SkypiaxHandles.disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False);
+		memset(&e, 0, sizeof(e));
+		e.xclient.type = ClientMessage;
+		e.xclient.message_type = atom1;   /*  leading message */
+		e.xclient.display = tech_pvt->SkypiaxHandles.disp;
+		e.xclient.window = tech_pvt->SkypiaxHandles.skype_win;
+		e.xclient.format = 8;
+
+		XSendEvent(tech_pvt->SkypiaxHandles.disp, tech_pvt->SkypiaxHandles.win, False, 0, &e);
+		XSync(tech_pvt->SkypiaxHandles.disp, False);
+#endif
+	}
+
+	while (x) {                 //FIXME 2 seconds?
+		x--;
+		switch_yield(20000);
+	}
+
+	if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread) {
+		switch_thread_join(&status, globals.SKYPIAX_INTERFACES[interface_id].skypiax_signaling_thread);
+	}
+
+	if (globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread) {
+		switch_thread_join(&status, globals.SKYPIAX_INTERFACES[interface_id].skypiax_api_thread);
+	}
+
+	memset(&globals.SKYPIAX_INTERFACES[interface_id], '\0',sizeof(private_t));
+	DEBUGA_SKYPE("interface for skype user '%s' deleted successfully\n", SKYPIAX_P_LOG, skype_user);
+end:
+	running = 1;
+	return SWITCH_STATUS_SUCCESS;
+}
+/* END: Changes here */
+
 /* 
    State methods they get called when the state changes to the specific state 
    returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
@@ -749,7 +851,9 @@
   return NULL;
 }
 
-static switch_status_t load_config(void)
+/* BEGIN: Changes heres */
+static switch_status_t load_config(int reload_type)
+/* END: Changes heres */
 {
   char *cf = "skypiax.conf";
   switch_xml_t cfg, xml, global_settings, param, interfaces, myinterface;
@@ -878,6 +982,14 @@
         continue;
       }
 
+      /* BEGIN: Changes here */
+      if(reload_type == SOFT_RELOAD) {
+        if(interface_exists(skype_user) == SWITCH_STATUS_SUCCESS) {
+	  continue;
+	}
+      }
+      /* END: Changes here */
+
       if (!X11_display) {
         ERRORA("interface missing REQUIRED param 'X11_display'\n", SKYPIAX_P_LOG);
         continue;
@@ -1112,7 +1224,7 @@
 
   running = 1;
 
-  if (load_config() != SWITCH_STATUS_SUCCESS) {
+  if (load_config(FULL_RELOAD) != SWITCH_STATUS_SUCCESS) {
     running = 0;
     return SWITCH_STATUS_FALSE;
   }
@@ -1130,6 +1242,7 @@
                    SK_SYNTAX);
     SWITCH_ADD_API(commands_api_interface, "skypiax", "Skypiax interface commands",
                    skypiax_function, SKYPIAX_SYNTAX);
+
     /* indicate that the module should continue to be loaded */
     return SWITCH_STATUS_SUCCESS;
   } else
@@ -1507,6 +1620,28 @@
 
   } else if (!strcasecmp(argv[0], "ciapalino")) {
 
+/* BEGIN: Changes heres */
+  } else if (!strcasecmp(argv[0], "reload")) {
+    if(load_config(SOFT_RELOAD) != SWITCH_STATUS_SUCCESS) {
+      stream->write_function(stream, "sk reload failed\n");
+    } else {
+      stream->write_function(stream, "sk reload success\n");
+    }
+  } else if (!strcasecmp(argv[0], "remove")) {
+    if(argc == 2) {
+      if(remove_interface(argv[1]) == SWITCH_STATUS_SUCCESS) {
+	if(interface_exists(argv[1]) == SWITCH_STATUS_SUCCESS) {
+          stream->write_function(stream, "sk remove '%s' failed\n", argv[1]);
+	} else {
+          stream->write_function(stream, "sk remove '%s' success\n",argv[1]);
+	}
+      }
+    } else {
+      stream->write_function(stream, "-ERR Usage: sk remove interface_name\n");
+      goto end;
+    }
+/* END: Changes heres */
+
   } else {
     if (globals.sk_console)
       skypiax_signaling_write(globals.sk_console, (char *) cmd);