mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-13 15:50:59 +00:00
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:
parent
ceb98915bb
commit
098d7274a0
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user