[Freeswitch-branches] [commit] r3683 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference

Freeswitch SVN knhor at freeswitch.org
Sat Dec 16 21:16:40 EST 2006


Author: knhor
Date: Sat Dec 16 21:16:38 2006
New Revision: 3683

Modified:
   freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c

Log:
3652 - hand merged
3653 - already done
3655 - hand merged
3656 - hand merged
3666 - hand merged
3668 - hand merged
3670 - hand merged
3672 - hand merged
3676 - hand merged
3678 - hand merged
3679 - hand merged


Modified: freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c	(original)
+++ freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c	Sat Dec 16 21:16:38 2006
@@ -137,15 +137,15 @@
 	NODE_TYPE_SPEECH
 } node_type_t;
 
-typedef struct confernce_file_node {
+typedef struct conference_file_node {
 	switch_file_handle_t fh;
 	switch_speech_handle_t sh;
 	node_type_t type;
 	uint8_t done;
 	switch_memory_pool_t *pool;
 	uint32_t leadin;
-	struct confernce_file_node *next;
-} confernce_file_node_t;
+	struct conference_file_node *next;
+} conference_file_node_t;
 
 /* conference xml config sections */
 typedef struct conf_xml_cfg {
@@ -187,7 +187,7 @@
 	switch_mutex_t *mutex;
 	conference_member_t *members;
 	switch_mutex_t *member_mutex;
-	confernce_file_node_t *fnode;
+	conference_file_node_t *fnode;
 	switch_memory_pool_t *pool;
 	switch_thread_rwlock_t *rwlock;
 	uint32_t count;
@@ -230,7 +230,7 @@
 	uint32_t native_rate;
 	switch_audio_resampler_t *mux_resampler;
 	switch_audio_resampler_t *read_resampler;
-	confernce_file_node_t *fnode;
+	conference_file_node_t *fnode;
 	conference_relationship_t *relationships;
 	switch_ivr_digit_stream_t *digit_stream;
 	struct conference_member *next;
@@ -507,6 +507,28 @@
 		last = imember;
 	}
 
+	/* Close Unused Handles */
+	if (member->fnode) {
+		conference_file_node_t *fnode, *cur;
+		switch_memory_pool_t *pool;
+
+		fnode = member->fnode;
+		while(fnode) {
+			cur = fnode;
+			fnode = fnode->next;
+
+			if (cur->type == NODE_TYPE_SPEECH) {
+				switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
+				switch_core_speech_close(&cur->sh, &flags);
+			} else {
+				switch_core_file_close(&cur->fh);
+			}
+
+			pool = cur->pool;
+			switch_core_destroy_memory_pool(&pool);
+		}
+	}
+
 	member->conference = NULL;
 
 	if (!switch_test_flag(member, MFLAG_NOCHANNEL)) {
@@ -722,7 +744,7 @@
 		}
 
 		if (conference->fnode && conference->fnode->done) {
-			confernce_file_node_t *fnode;
+			conference_file_node_t *fnode;
 			switch_memory_pool_t *pool;
 
 			if (conference->fnode->type == NODE_TYPE_SPEECH) {
@@ -761,6 +783,29 @@
 
 		switch_mutex_lock(conference->mutex);
 
+		/* Close Unused Handles */ 
+		if (conference->fnode) {
+			conference_file_node_t *fnode, *cur; 
+			switch_memory_pool_t *pool; 
+
+			fnode = conference->fnode; 
+			while (fnode) { 
+				cur = fnode; 
+				fnode = fnode->next; 
+
+				if (cur->type == NODE_TYPE_SPEECH) { 
+					switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; 
+					switch_core_speech_close(&cur->sh, &flags); 
+				} else { 
+					switch_core_file_close(&cur->fh); 
+				} 
+
+				pool = cur->pool; 
+				switch_core_destroy_memory_pool(&pool); 
+			} 
+			conference->fnode = NULL; 
+		} 
+
 		for(imember = conference->members; imember; imember = imember->next) {
 			switch_channel_t *channel;
 
@@ -831,6 +876,7 @@
 static void conference_loop_fn_energy_up(conference_member_t *member, void *data)
 {
 	char msg[512];
+	switch_event_t *event;
 
 	switch_mutex_lock(member->flag_mutex);
 	member->energy_level += 100;
@@ -838,24 +884,50 @@
 		member->energy_level = 1200;
 	}
 	switch_mutex_unlock(member->flag_mutex);
+
 	snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level);
 	conference_member_say(member, msg, 0);
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_t *channel = switch_core_session_get_channel(member->session);
+
+		switch_channel_event_set_data(channel, event);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", member->conference->name);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "energy-level");
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level);
+		switch_event_fire(&event);
+	}
 }
 
 static void conference_loop_fn_energy_equ_conf(conference_member_t *member, void *data)
 {
 	char msg[512];
+	switch_event_t *event;
 
 	switch_mutex_lock(member->flag_mutex);
 	member->energy_level = member->conference->energy_level;
 	switch_mutex_unlock(member->flag_mutex);
+
 	snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level);
 	conference_member_say(member, msg, 0);
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_t *channel = switch_core_session_get_channel(member->session);
+
+		switch_channel_event_set_data(channel, event);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", member->conference->name);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "energy-level");
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level);
+		switch_event_fire(&event);
+	}
 }
 					
 static void conference_loop_fn_energy_dn(conference_member_t *member, void *data)
 {
 	char msg[512];
+	switch_event_t *event;
 
 	switch_mutex_lock(member->flag_mutex);
 	member->energy_level -= 100;
@@ -863,78 +935,168 @@
 		member->energy_level = 0;
 	}
 	switch_mutex_unlock(member->flag_mutex);
+
 	snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level);
 	conference_member_say(member, msg, 0);
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_t *channel = switch_core_session_get_channel(member->session);
+
+		switch_channel_event_set_data(channel, event);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", member->conference->name);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "energy-level");
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level);
+		switch_event_fire(&event);
+	}
 }
 
 static void conference_loop_fn_volume_talk_up(conference_member_t *member, void *data)
 {
 	char msg[512];
+	switch_event_t *event;
 
 	switch_mutex_lock(member->flag_mutex);
 	member->volume_out_level++;
 	switch_normalize_volume(member->volume_out_level);
 	switch_mutex_unlock(member->flag_mutex);
+
 	snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level);
 	conference_member_say(member, msg, 0);
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_t *channel = switch_core_session_get_channel(member->session);
+
+		switch_channel_event_set_data(channel, event);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", member->conference->name);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "volume-level");
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level);
+		switch_event_fire(&event);
+	}
 }
 
 static void conference_loop_fn_volume_talk_zero(conference_member_t *member, void *data)
 {
 	char msg[512];
+	switch_event_t *event;
 
 	switch_mutex_lock(member->flag_mutex);
 	member->volume_out_level = 0;
 	switch_mutex_unlock(member->flag_mutex);
+
 	snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level);
 	conference_member_say(member, msg, 0);
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_t *channel = switch_core_session_get_channel(member->session);
+
+		switch_channel_event_set_data(channel, event);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", member->conference->name);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "volume-level");
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level);
+		switch_event_fire(&event);
+	}
 }
 
 static void conference_loop_fn_volume_talk_dn(conference_member_t *member, void *data)
 {
 	char msg[512];
+	switch_event_t *event;
 
 	switch_mutex_lock(member->flag_mutex);
 	member->volume_out_level--;
 	switch_normalize_volume(member->volume_out_level);
 	switch_mutex_unlock(member->flag_mutex);
+
 	snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level);
 	conference_member_say(member, msg, 0);
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_t *channel = switch_core_session_get_channel(member->session);
+
+		switch_channel_event_set_data(channel, event);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", member->conference->name);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "volume-level");
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level);
+		switch_event_fire(&event);
+	}
 }
 
 static void conference_loop_fn_volume_listen_up(conference_member_t *member, void *data)
 {
 	char msg[512];
+	switch_event_t *event;
 
 	switch_mutex_lock(member->flag_mutex);
 	member->volume_in_level++;
 	switch_normalize_volume(member->volume_in_level);
 	switch_mutex_unlock(member->flag_mutex);
+
 	snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level);
 	conference_member_say(member, msg, 0);
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_t *channel = switch_core_session_get_channel(member->session);
+
+		switch_channel_event_set_data(channel, event);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", member->conference->name);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "gain-level");
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level);
+		switch_event_fire(&event);
+	}
 }
 
 static void conference_loop_fn_volume_listen_zero(conference_member_t *member, void *data)
 {
 	char msg[512];
+	switch_event_t *event;
 
 	switch_mutex_lock(member->flag_mutex);
 	member->volume_in_level = 0;
 	switch_mutex_unlock(member->flag_mutex);
+
 	snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level);
 	conference_member_say(member, msg, 0);
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_t *channel = switch_core_session_get_channel(member->session);
+
+		switch_channel_event_set_data(channel, event);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", member->conference->name);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "gain-level");
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level);
+		switch_event_fire(&event);
+	}
 }
 
 static void conference_loop_fn_volume_listen_dn(conference_member_t *member, void *data)
 {
 	char msg[512];
+	switch_event_t *event;
 
 	switch_mutex_lock(member->flag_mutex);
 	member->volume_in_level--;
 	switch_normalize_volume(member->volume_in_level);
 	switch_mutex_unlock(member->flag_mutex);
+
 	snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level);
 	conference_member_say(member, msg, 0);
+
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_t *channel = switch_core_session_get_channel(member->session);
+
+		switch_channel_event_set_data(channel, event);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", member->conference->name);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id);
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Action", "gain-level");
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level);
+		switch_event_fire(&event);
+	}
 }
 
 static void conference_loop_fn_hangup(conference_member_t *member, void *data)
@@ -1040,15 +1202,15 @@
 			int16_t *data;
 
 			data = read_frame->data;
-			samples = read_frame->datalen / sizeof(*data);
+			if ((samples = read_frame->datalen / sizeof(*data))) {
 
-			for (i = 0; i < samples; i++) {
-				energy += abs(data[j]);
-				j += read_codec->implementation->number_of_channels;
+				for (i = 0; i < samples; i++) {
+					energy += abs(data[j]);
+					j += read_codec->implementation->number_of_channels;
+				}
+				score = energy / samples;
 			}
 
-			score = energy / samples;
-
 			if (score > energy_level) {
 				uint32_t diff = score - energy_level;
 				if (hangover_hits) {
@@ -1286,7 +1448,7 @@
 		if (member->fnode) {
 			/* if we are done, clean it up */
 			if (member->fnode->done) {
-				confernce_file_node_t *fnode;
+				conference_file_node_t *fnode;
 				switch_memory_pool_t *pool;
 
 				if (member->fnode->type == NODE_TYPE_SPEECH) {
@@ -1514,7 +1676,7 @@
 /* Make files stop playing in a conference either the current one or all of them */
 static uint32_t conference_stop_file(conference_obj_t *conference, file_stop_t stop)
 {
-	confernce_file_node_t *nptr;
+	conference_file_node_t *nptr;
 	uint32_t count = 0;
 
 	switch_mutex_lock(conference->mutex);
@@ -1539,7 +1701,7 @@
 /* stop playing a file for the member of the conference */
 static uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop)
 {
-	confernce_file_node_t *nptr;
+	conference_file_node_t *nptr;
 	uint32_t count = 0;
 
 	switch_mutex_lock(member->flag_mutex);
@@ -1564,7 +1726,7 @@
 /* Play a file in the conference room */
 static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel)
 {
-	confernce_file_node_t *fnode, *nptr;
+	conference_file_node_t *fnode, *nptr;
 	switch_memory_pool_t *pool;
 	uint32_t count;
 	char *expanded = NULL;
@@ -1651,7 +1813,7 @@
 /* Play a file in the conference room to a member */
 static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin)
 {
-	confernce_file_node_t *fnode, *nptr;
+	conference_file_node_t *fnode, *nptr;
 	switch_memory_pool_t *pool;
 
 	if (*file != '/') {
@@ -1704,7 +1866,7 @@
 static switch_status_t conference_member_say(conference_member_t *member, char *text, uint32_t leadin)
 {
 	conference_obj_t *conference = (member != NULL ? member->conference : NULL);
-	confernce_file_node_t *fnode, *nptr;
+	conference_file_node_t *fnode, *nptr;
 	switch_memory_pool_t *pool;
 	switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
 
@@ -1743,7 +1905,6 @@
 		return SWITCH_STATUS_FALSE;
 	}
 
-
 	fnode->pool = pool;
 
 	/* Queue the node */
@@ -1755,11 +1916,11 @@
 	} else {
 		member->fnode = fnode;
 	}
-	switch_mutex_unlock(member->flag_mutex);
 
 	/* Begin Generation */
 	switch_sleep(200000);
 	switch_core_speech_feed_tts(&fnode->sh, text, &flags);
+	switch_mutex_unlock(member->flag_mutex);
 
 	return SWITCH_STATUS_SUCCESS;
 }
@@ -1767,7 +1928,7 @@
 /* Say some thing with TTS in the conference room */
 static switch_status_t conference_say(conference_obj_t *conference, char *text, uint32_t leadin)
 {
-	confernce_file_node_t *fnode, *nptr;
+	conference_file_node_t *fnode, *nptr;
 	switch_memory_pool_t *pool;
 	switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
 	uint32_t count;
@@ -1823,11 +1984,11 @@
 	} else {
 		conference->fnode = fnode;
 	}
-	switch_mutex_unlock(conference->mutex);
 
 	/* Begin Generation */
 	switch_sleep(200000);
 	switch_core_speech_feed_tts(&fnode->sh, text, &flags);
+	switch_mutex_unlock(conference->mutex);
 
 	return SWITCH_STATUS_SUCCESS;
 }
@@ -1887,7 +2048,11 @@
 			count++;
 		}
 
-		stream->write_function(stream, "\n");
+		stream->write_function(stream, "%s%d%s%d%s%d\n",
+							delim,
+							member->volume_in_level, delim,
+							member->volume_out_level, delim,
+							member->energy_level);
 	}
 	switch_mutex_unlock(conference->member_mutex);
 }
@@ -2460,7 +2625,7 @@
 {
 	int err = 0;
 
-	if (argc > 3) {
+	if (argc > 3 && !switch_strlen_zero(argv[2])) {
 		int x;
 
 		for (x=3; x<argc; x++) {
@@ -2481,7 +2646,7 @@
 
 			/* build a new conference if it doesn't exist */
 			if (!(new_conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, argv[2]))) {
-				switch_memory_pool_t *pool;
+				switch_memory_pool_t *pool = NULL;
 				char *conf_name;
 				conf_xml_cfg_t xml_cfg;
 
@@ -2522,6 +2687,9 @@
 
 				if (!new_conference) {
 					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+					if (pool != NULL) {
+						switch_core_destroy_memory_pool(&pool);
+					}
 					goto done;
 				}
 
@@ -2539,7 +2707,7 @@
 			conference_del_member(member->last_conference, member);
 			conference_add_member(new_conference, member);
 
-			stream->write_function(stream, "OK Member %u sent to conference %s.\n", id, argv[2]);
+			stream->write_function(stream, "OK Members sent to conference %s.\n", argv[2]);
 
 			/* tell them what happened */
 			if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
@@ -2759,9 +2927,7 @@
 		}
 	}
 
-	if (lbuf) {
-		free(lbuf);
-	}
+	switch_safe_free(lbuf);
 
 	return status;
 
@@ -3936,13 +4102,92 @@
 	return conference;
 }
 
-/* Called by FreeSWITCH when the module loads */
+static void pres_event_handler(switch_event_t *event) 
+{ 
+	char *to = switch_event_get_header(event, "to"); 
+	char *dup_to = NULL, *conf_name, *e; 
+	conference_obj_t *conference; 
+
+	if (!to || strncasecmp(to, "conf+", 5)) { 
+		return; 
+	} 
+
+	if (!(dup_to = strdup(to))) { 
+		return; 
+	} 
+
+	conf_name = dup_to + 5; 
+
+	if ((e = strchr(conf_name, '@'))) { 
+		*e = '\0'; 
+	} 
+
+	if ((conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, conf_name))) { 
+		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", 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); 
+		} 
+	} else 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", conf_name); 
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", to); 
+		switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Idle"); 
+		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); 
+	} 
+
+    switch_safe_free(dup_to); 
+} 
+ 
+static void send_presence(switch_event_types_t id) 
+{ 
+	switch_xml_t cxml, cfg, advertise, room; 
+
+	/* Open the config from the xml registry */ 
+	if (!(cxml = switch_xml_open_cfg(global_cf_name, &cfg, NULL))) { 
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", global_cf_name); 
+		goto done; 
+	} 
+
+	if ((advertise = switch_xml_child(cfg, "advertise"))) { 
+		for (room = switch_xml_child(advertise, "room"); room; room = room->next) { 
+			char *name = (char *) switch_xml_attr_soft(room, "name"); 
+			char *status = (char *) switch_xml_attr_soft(room, "status"); 
+			switch_event_t *event; 
+
+			if (name && switch_event_create(&event, id) == 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", "%s", status ? status : "Available"); 
+				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); 
+			} 
+		} 
+	} 
+
+	done: 
+	/* Release the config registry handle */ 
+	if (cxml) { 
+		switch_xml_free(cxml); 
+		cxml = NULL; 
+	} 
+} 
+
+	/* 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)
 {
 	int i;
 	size_t nl,ol=0;
 	char *p = NULL;
-
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
 
 	memset(&globals, 0, sizeof(globals));
@@ -3986,6 +4231,14 @@
 	switch_mutex_init(&globals.conference_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool);
 	switch_mutex_init(&globals.id_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool);
 	switch_mutex_init(&globals.hash_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool);
+
+	/* Subscribe to presence request events */
+	if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't subscribe to presence request events!\n");
+		return SWITCH_STATUS_GENERR;
+	}
+
+	send_presence(SWITCH_EVENT_PRESENCE_IN);
 
 	globals.running = 1;
 	/* indicate that the module should continue to be loaded */



More information about the Freeswitch-branches mailing list