]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add avatars for dingalaing
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 4 Apr 2007 22:22:55 +0000 (22:22 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 4 Apr 2007 22:22:55 +0000 (22:22 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4850 d0543943-73ff-0310-b7d9-9358b9ac24b2

libs/libdingaling/src/libdingaling.c
libs/libdingaling/src/libdingaling.h
src/mod/endpoints/mod_dingaling/mod_dingaling.c
src/mod/endpoints/mod_sofia/mod_sofia.h

index c26df29807b1818b56d171fa84855a9542f42fcf..23fa21c29fa1c04572b4f53e1a0d595f5922c6d0 100644 (file)
 
 #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 @@ static struct {
        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 @@ struct ldl_session {
        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 @@ static int on_presence(void *user_data, ikspak *pak)
        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 @@ static void do_presence(ldl_handle_t *handle, char *from, char *to, char *type,
                }
 
                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 int on_result(void *user_data, ikspak *pak)
 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 @@ static int b64encode(unsigned char *in, uint32_t ilen, unsigned char *out, uint3
                        if(++y!=72) {
                                continue;
                        }
-                       out[bytes++] = '\n';
+                       //out[bytes++] = '\n';
                        y=0;
                }
        }
@@ -1629,15 +1708,65 @@ char *ldl_handle_get_login(ldl_handle_t *handle)
        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);
+       do_presence(handle, from, to, type, rpid, message, avatar);
 }
 
+static void ldl_random_string(char *buf, uint16_t len, char *set)
+{
+    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 @@ ldl_status ldl_global_init(int debug)
        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;
index 37317fe99dfa87cb1a5af898b92de12d65d40b43..67f841d19a7839f080934bff9a786e533ba806c3 100644 (file)
@@ -439,8 +439,9 @@ void ldl_session_send_msg(ldl_session_t *session, char *subject, char *body);
   \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
index 4db887924689f5949a43aefab964ecb46dafd9ac..a9e0c93732434fac2ac5e261514b9cbd11b41ecd 100644 (file)
@@ -118,11 +118,17 @@ struct mdl_profile {
        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 @@ static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
        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 @@ static int rost_callback(void *pArg, int argc, char **argv, char **columnNames)
                }
        }
 
-       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 @@ static int so_callback(void *pArg, int argc, char **argv, char **columnNames)
        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 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
           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 @@ static void set_profile_val(mdl_profile_t *profile, char *var, char *val)
                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 switch_status_t load_config(void)
 }
 
 
-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 @@ static void do_vcard(ldl_handle_t * handle, char *to, char *from, char *id)
 
 
        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 @@ static void do_vcard(ldl_handle_t * handle, char *to, char *from, char *id)
 
        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 @@ static ldl_status handle_signalling(ldl_handle_t * handle, ldl_session_t * dlses
                                        }
                                        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 @@ static ldl_status handle_signalling(ldl_handle_t * handle, ldl_session_t * dlses
                                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 @@ static ldl_status handle_signalling(ldl_handle_t * handle, ldl_session_t * dlses
 
 
                                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)) {
index 05a17e08e66a75b73197275bc73904daf546d592..7253e820bf8b4127c0dbe550d22fa473f2eff0c4 100644 (file)
@@ -230,6 +230,11 @@ struct sofia_profile {
        char *odbc_user;
        char *odbc_pass;
        switch_odbc_handle_t *master_odbc;
+#else
+       void *filler1;
+       void *filler2;
+       void *filler3;
+       void *filler4;
 #endif
 };