[commit] r4850 - in freeswitch/trunk: libs/libdingaling/src src/mod/endpoints/mod_dingaling src/mod/endpoints/mod_sofia
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 };
participants (1)
-
Freeswitch SVN