[Freeswitch-svn] [commit] r4850 - in freeswitch/trunk: libs/libdingaling/src src/mod/endpoints/mod_dingaling src/mod/endpoints/mod_sofia

Freeswitch SVN anthm at freeswitch.org
Wed Apr 4 18:22:55 EDT 2007


Author: anthm
Date: Wed Apr  4 18:22:55 2007
New Revision: 4850

Modified:
   freeswitch/trunk/libs/libdingaling/src/libdingaling.c
   freeswitch/trunk/libs/libdingaling/src/libdingaling.h
   freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h

Log:
add avatars for dingalaing

Modified: freeswitch/trunk/libs/libdingaling/src/libdingaling.c
==============================================================================
--- freeswitch/trunk/libs/libdingaling/src/libdingaling.c	(original)
+++ freeswitch/trunk/libs/libdingaling/src/libdingaling.c	Wed Apr  4 18:22:55 2007
@@ -31,6 +31,11 @@
 
 #ifndef  _MSC_VER
 #include <config.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
 #endif
 
 #include <string.h>
@@ -74,6 +79,8 @@
 
 static int opt_timeout = 30;
 
+static void sha1_hash(char *out, char *in);
+static int b64encode(unsigned char *in, uint32_t ilen, unsigned char *out, uint32_t olen);
 
 static struct {
 	unsigned int flags;
@@ -82,6 +89,7 @@
 	apr_pool_t *memory_pool;
 	unsigned int id;
 	ldl_logger_t logger;
+	apr_hash_t *avatar_hash;
 	apr_thread_mutex_t *flag_mutex;
 } globals;
 
@@ -152,6 +160,15 @@
 	void *private_data;
 };
 
+struct ldl_avatar {
+	char *path;
+	char *from;
+	char *base64;
+	char hash[256];
+};
+
+typedef struct ldl_avatar ldl_avatar_t;
+
 
 static void lowercase(char *str) 
 {
@@ -750,7 +767,54 @@
 	return IKS_FILTER_EAT;
 }
 
-static void do_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message) 
+static ldl_avatar_t *ldl_get_avatar(char *path, char *from)
+{
+	ldl_avatar_t *ap;
+	uint8_t image[8192];
+	unsigned char base64[9216] = "";
+	int fd = -1;
+	size_t bytes;
+	char *p;
+
+	if (path && (ap = (ldl_avatar_t *) apr_hash_get(globals.avatar_hash, path, APR_HASH_KEY_STRING))) {
+		return ap;
+	}
+
+	if (from && (ap = (ldl_avatar_t *) apr_hash_get(globals.avatar_hash, from, APR_HASH_KEY_STRING))) {
+		return ap;
+	}
+
+	if (!(path && from)) {
+		return NULL;
+	}
+
+	if ((fd = open(path, O_RDONLY, 0)) < 0) {
+		globals.logger(DL_LOG_ERR, "File %s does not exist!\n", path);
+		return NULL;
+	}
+	
+	bytes = read(fd, image, sizeof(image));
+	close(fd);
+	fd = -1;
+
+	ap = malloc(sizeof(*ap));
+	assert(ap != NULL);
+	memset(ap, 0, sizeof(*ap));
+	sha1_hash(ap->hash, (char *)image);
+	ap->path = strdup(path);
+	ap->from = strdup(from);
+	if ((p = strchr(ap->from, '/'))) {
+		*p = '\0';
+	}
+	b64encode((unsigned char *)image, bytes, base64, sizeof(base64));
+	ap->base64 = strdup(base64);
+	apr_hash_set(globals.avatar_hash, ap->path, APR_HASH_KEY_STRING, ap);
+	apr_hash_set(globals.avatar_hash, ap->from, APR_HASH_KEY_STRING, ap);
+	return ap;
+}
+
+
+static void do_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message, char *avatar) 
 {
 	iks *pres;
 	char buf[512];
@@ -791,6 +855,20 @@
 		}
 
 		if (message || rpid) {
+			ldl_avatar_t *ap;
+
+			if (avatar) {
+				if ((ap = ldl_get_avatar(avatar, from))) {
+					if ((tag = iks_insert(pres, "x"))) {
+						iks *hash;
+						iks_insert_attrib(tag, "xmlns", "vcard-temp:x:update");
+						if ((hash = iks_insert(tag, "photo"))) {
+							iks_insert_cdata(hash, ap->hash, 0);
+						}
+					}
+				}
+			}
+
 			if ((tag = iks_insert(pres, "c"))) {
 				iks_insert_attrib(tag, "node", "http://www.freeswitch.org/xmpp/client/caps");
 				iks_insert_attrib(tag, "ver", "1.0.0.1");
@@ -975,7 +1053,8 @@
 static const char c64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 #define B64BUFFLEN 1024
 
-static int b64encode(unsigned char *in, uint32_t ilen, unsigned char *out, uint32_t olen) {
+static int b64encode(unsigned char *in, uint32_t ilen, unsigned char *out, uint32_t olen) 
+{
 	int y=0,bytes=0;
 	uint32_t x=0;
 	unsigned int b=0,l=0;
@@ -988,7 +1067,7 @@
 			if(++y!=72) {
 				continue;
 			}
-			out[bytes++] = '\n';
+			//out[bytes++] = '\n';
 			y=0;
 		}
 	}
@@ -1629,15 +1708,65 @@
 	return handle->login;
 }
 
-void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message)
+void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message, char *avatar)
+{
+	do_presence(handle, from, to, type, rpid, message, avatar);
+}
+
+static void ldl_random_string(char *buf, uint16_t len, char *set)
 {
-	do_presence(handle, from, to, type, rpid, message);
+    char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    int max;
+    uint16_t x;
+
+    if (!set) {
+        set = chars;
+    }
+
+    max = (int) strlen(set);
+
+    srand((unsigned int) time(NULL));
+
+    for (x = 0; x < len; x++) {
+        int j = (int) (max * 1.0 * rand() / (RAND_MAX + 1.0));
+        buf[x] = set[j];
+    }
 }
 
+
 void ldl_handle_send_vcard(ldl_handle_t *handle, char *from, char *to, char *id, char *vcard)
 {
 	iks *vxml, *iq;
 	int e = 0;
+	ldl_avatar_t *ap;
+
+	ap = ldl_get_avatar(NULL, from);
+
+	if (!vcard) {
+		char text[8192];
+		char *ext;
+		if (!ap) {
+			return;
+		}
+		
+		if ((ext = strrchr(ap->path, '.'))) {
+			ext++;
+		} else {
+			ext = "png";
+		}
+
+		snprintf(text, sizeof(text),
+				 "<vCard xmlns='vcard-temp'><PHOTO><TYPE>image/%s</TYPE><BINVAL>%s</BINVAL></PHOTO></vCard>",
+				 ext,
+				 ap->base64
+				 );
+		vcard = text;
+	} else {
+		if (ap && (strstr(vcard, "photo") || strstr(vcard, "PHOTO"))) {
+			ldl_random_string(ap->hash, sizeof(ap->hash), NULL);
+		}
+	}
+
 
 	if (!(vxml = iks_tree(vcard, 0, &e))) {
 		globals.logger(DL_LOG_ERR, "Parse returned error [%d]\n", e);
@@ -2016,6 +2145,7 @@
 	globals.debug = debug;
 	globals.id = 300;
 	globals.logger = default_logger;
+	globals.avatar_hash = apr_hash_make(globals.memory_pool);
 	ldl_set_flag_locked((&globals), LDL_FLAG_INIT);
 	
 	return LDL_STATUS_SUCCESS;

Modified: freeswitch/trunk/libs/libdingaling/src/libdingaling.h
==============================================================================
--- freeswitch/trunk/libs/libdingaling/src/libdingaling.h	(original)
+++ freeswitch/trunk/libs/libdingaling/src/libdingaling.h	Wed Apr  4 18:22:55 2007
@@ -439,8 +439,9 @@
   \param type the type of presence
   \param rpid data for the icon
   \param message a status message
+  \param avatar the path to an avatar image
 */
-void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message);
+void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message, char *avatar);
 
 /*!
   \brief Send a vcard

Modified: freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c	Wed Apr  4 18:22:55 2007
@@ -118,11 +118,17 @@
 	char *context;
 	char *timer_name;
 	char *dbname;
+	char *avatar;
 #ifdef SWITCH_HAVE_ODBC
 	char *odbc_dsn;
 	char *odbc_user;
 	char *odbc_pass;
 	switch_odbc_handle_t *master_odbc;
+#else
+	void *filler1;
+	void *filler2;
+	void *filler3;
+	void *filler4;
 #endif
 	switch_mutex_t *mutex;
 	ldl_handle_t *handle;
@@ -361,7 +367,7 @@
 	rpid = translate_rpid(rpid, status);
 
 	//ldl_handle_send_presence(profile->handle, sub_to, sub_from, "probe", rpid, status);
-	ldl_handle_send_presence(profile->handle, sub_to, sub_from, type, rpid, status);
+	ldl_handle_send_presence(profile->handle, sub_to, sub_from, type, rpid, status, profile->avatar);
 
 
 	return 0;
@@ -384,7 +390,7 @@
 		}
 	}
 
-	ldl_handle_send_presence(profile->handle, sub_to, sub_from, NULL, show, status);
+	ldl_handle_send_presence(profile->handle, sub_to, sub_from, NULL, show, status, profile->avatar);
 
 	return 0;
 }
@@ -588,7 +594,7 @@
 	char *sub_to = argv[1];
 
 
-	ldl_handle_send_presence(profile->handle, sub_to, sub_from, "unavailable", "dnd", "Bub-Bye");
+	ldl_handle_send_presence(profile->handle, sub_to, sub_from, "unavailable", "dnd", "Bub-Bye", profile->avatar);
 
 	return 0;
 }
@@ -1180,7 +1186,7 @@
 	   We should find out why.....
 	 */
 	if ((tech_pvt->profile->user_flags & LDL_FLAG_COMPONENT) && is_special(tech_pvt->them)) {
-		ldl_handle_send_presence(tech_pvt->profile->handle, tech_pvt->them, tech_pvt->us, NULL, NULL, "Click To Call");
+		ldl_handle_send_presence(tech_pvt->profile->handle, tech_pvt->them, tech_pvt->us, NULL, NULL, "Click To Call", tech_pvt->profile->avatar);
 	}
 	if (tech_pvt->dlsession) {
 		if (!switch_test_flag(tech_pvt, TFLAG_TERM)) {
@@ -1881,6 +1887,8 @@
 		profile->login = switch_core_strdup(module_pool, val);
 	} else if (!strcasecmp(var, "password")) {
 		profile->password = switch_core_strdup(module_pool, val);
+	} else if (!strcasecmp(var, "avatar")) {
+		profile->avatar = switch_core_strdup(module_pool, val);
 	} else if (!strcasecmp(var, "odbc-dsn")) {
 #ifdef SWITCH_HAVE_ODBC
 		profile->odbc_dsn = switch_core_strdup(module_pool, val);
@@ -2164,10 +2172,11 @@
 }
 
 
-static void do_vcard(ldl_handle_t * handle, char *to, char *from, char *id)
+static void do_vcard(ldl_handle_t *handle, char *to, char *from, char *id)
 {
 	char *params = NULL, *real_to, *to_user, *xmlstr = NULL, *to_host = NULL;
 	switch_xml_t domain, xml = NULL, user, vcard;
+	int sent = 0;
 
 	if (!strncasecmp(to, "user+", 5)) {
 		real_to = to + 5;
@@ -2197,17 +2206,17 @@
 
 
 	if (switch_xml_locate("directory", "domain", "name", to_host, &xml, &domain, params) != SWITCH_STATUS_SUCCESS) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't find domain for [%s@%s]\n", to_user, to_host);
+		//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't find domain for [%s@%s]\n", to_user, to_host);
 		goto end;
 	}
 
 	if (!(user = switch_xml_find_child(domain, "user", "id", to_user))) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", to_user, to_host);
+		//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", to_user, to_host);
 		goto end;
 	}
 
 	if (!(vcard = switch_xml_child(user, "vcard"))) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find <vcard> tag for user [%s@%s]\n", to_user, to_host);
+		//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find <vcard> tag for user [%s@%s]\n", to_user, to_host);
 		goto end;
 	}
 
@@ -2215,11 +2224,17 @@
 
 	if ((xmlstr = switch_xml_toxml(vcard))) {
 		ldl_handle_send_vcard(handle, to, from, id, xmlstr);
+		sent = 1;
 	} else {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
 	}
 
   end:
+
+	if (!sent) {
+		ldl_handle_send_vcard(handle, to, from, id, NULL);
+	}
+
 	if (xml)
 		switch_xml_free(xml);
 	switch_safe_free(to_user);
@@ -2280,7 +2295,7 @@
 					}
 					switch_mutex_unlock(profile->mutex);
 					if (is_special(to)) {
-						ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call");
+						ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call", profile->avatar);
 					}
 #if 0
 					if (is_special(to)) {
@@ -2305,7 +2320,7 @@
 				break;
 			case LDL_SIGNAL_PRESENCE_PROBE:
 				if (is_special(to)) {
-					ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call");
+					ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call", profile->avatar);
 				} else {
 					if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
 						switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
@@ -2335,7 +2350,7 @@
 
 
 				if (is_special(to)) {
-					ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call");
+					ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call", profile->avatar);
 				}
 #if 0
 				if (is_special(to)) {

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h	Wed Apr  4 18:22:55 2007
@@ -230,6 +230,11 @@
 	char *odbc_user;
 	char *odbc_pass;
 	switch_odbc_handle_t *master_odbc;
+#else
+	void *filler1;
+	void *filler2;
+	void *filler3;
+	void *filler4;
 #endif
 };
 



More information about the Freeswitch-svn mailing list