add avatars for dingalaing

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4850 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2007-04-04 22:22:55 +00:00
parent ceb98915bb
commit 098d7274a0
4 changed files with 168 additions and 17 deletions

View File

@ -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 @@ 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;

View 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

View 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)) {

View 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
};