|
Packit |
16808d |
|
|
Packit |
16808d |
/*
|
|
Packit |
16808d |
Meanwhile - Unofficial Lotus Sametime Community Client Library
|
|
Packit |
16808d |
Copyright (C) 2004 Christopher (siege) O'Brien
|
|
Packit |
16808d |
|
|
Packit |
16808d |
This library is free software; you can redistribute it and/or
|
|
Packit |
16808d |
modify it under the terms of the GNU Library General Public
|
|
Packit |
16808d |
License as published by the Free Software Foundation; either
|
|
Packit |
16808d |
version 2 of the License, or (at your option) any later version.
|
|
Packit |
16808d |
|
|
Packit |
16808d |
This library is distributed in the hope that it will be useful,
|
|
Packit |
16808d |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
16808d |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
16808d |
Library General Public License for more details.
|
|
Packit |
16808d |
|
|
Packit |
16808d |
You should have received a copy of the GNU Library General Public
|
|
Packit |
16808d |
License along with this library; if not, write to the Free
|
|
Packit |
16808d |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
16808d |
*/
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#include <glib.h>
|
|
Packit Service |
a50ce7 |
#include <glib/ghash.h>
|
|
Packit Service |
a50ce7 |
#include <glib/glist.h>
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#include <stdio.h>
|
|
Packit |
16808d |
#include <stdlib.h>
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#include "mw_channel.h"
|
|
Packit |
16808d |
#include "mw_common.h"
|
|
Packit |
16808d |
#include "mw_debug.h"
|
|
Packit |
16808d |
#include "mw_error.h"
|
|
Packit |
16808d |
#include "mw_message.h"
|
|
Packit |
16808d |
#include "mw_service.h"
|
|
Packit |
16808d |
#include "mw_session.h"
|
|
Packit |
16808d |
#include "mw_srvc_place.h"
|
|
Packit |
16808d |
#include "mw_util.h"
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#define PROTOCOL_TYPE 0x00
|
|
Packit |
16808d |
#define PROTOCOL_VER 0x05
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
enum incoming_msg {
|
|
Packit |
16808d |
msg_in_JOIN_RESPONSE = 0x0000, /* ? */
|
|
Packit |
16808d |
msg_in_INFO = 0x0002,
|
|
Packit |
16808d |
msg_in_MESSAGE = 0x0004,
|
|
Packit |
16808d |
msg_in_SECTION = 0x0014, /* see in_section_subtype */
|
|
Packit |
16808d |
msg_in_UNKNOWNa = 0x0015,
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
enum in_section_subtype {
|
|
Packit |
16808d |
msg_in_SECTION_LIST = 0x0000, /* list of section members */
|
|
Packit |
16808d |
msg_in_SECTION_PEER = 0x0001, /* see in_section_peer_subtye */
|
|
Packit |
16808d |
msg_in_SECTION_PART = 0x0003,
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
enum in_section_peer_subtype {
|
|
Packit |
16808d |
msg_in_SECTION_PEER_JOIN = 0x0000,
|
|
Packit |
16808d |
msg_in_SECTION_PEER_PART = 0x0001, /* after msg_in_SECTION_PART */
|
|
Packit |
16808d |
msg_in_SECTION_PEER_CLEAR_ATTR = 0x0003,
|
|
Packit |
16808d |
msg_in_SECTION_PEER_SET_ATTR = 0x0004,
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
enum outgoing_msg {
|
|
Packit |
16808d |
msg_out_JOIN_PLACE = 0x0000, /* ? */
|
|
Packit |
16808d |
msg_out_PEER_INFO = 0x0002, /* ? */
|
|
Packit |
16808d |
msg_out_MESSAGE = 0x0003,
|
|
Packit |
16808d |
msg_out_OLD_INVITE = 0x0005, /* old-style conf. invitation */
|
|
Packit |
16808d |
msg_out_SET_ATTR = 0x000a,
|
|
Packit |
16808d |
msg_out_CLEAR_ATTR = 0x000b,
|
|
Packit |
16808d |
msg_out_SECTION = 0x0014, /* see out_section_subtype */
|
|
Packit |
16808d |
msg_out_UNKNOWNb = 0x001e, /* ? maybe enter stage ? */
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
enum out_section_subtype {
|
|
Packit |
16808d |
msg_out_SECTION_LIST = 0x0002, /* req list of members */
|
|
Packit |
16808d |
msg_out_SECTION_PART = 0x0003,
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/*
|
|
Packit |
16808d |
: allocate section
|
|
Packit |
16808d |
: state = NEW
|
|
Packit |
16808d |
|
|
Packit |
16808d |
: create channel
|
|
Packit |
16808d |
: state = PENDING
|
|
Packit |
16808d |
|
|
Packit |
16808d |
: channel accepted
|
|
Packit |
16808d |
: msg_out_JOIN_PLACE (maybe create?)
|
|
Packit |
16808d |
: state = JOINING
|
|
Packit |
16808d |
|
|
Packit |
16808d |
: msg_in_JOIN_RESPONSE (contains our place member ID and section ID)
|
|
Packit |
16808d |
: msg_in_INFO (for place, not peer)
|
|
Packit |
16808d |
: state = JOINED
|
|
Packit |
16808d |
|
|
Packit |
16808d |
: msg_out_SECTION_LIST (asking for all sections) (optional)
|
|
Packit |
16808d |
: msg_in_SECTION_LIST (listing all sections, as requested above)
|
|
Packit |
16808d |
|
|
Packit |
16808d |
: msg_out_PEER_INFO (with our place member ID) (optional)
|
|
Packit |
16808d |
: msg_in_INFO (peer info as requested above)
|
|
Packit |
16808d |
|
|
Packit |
16808d |
: msg_out_SECTION_LIST (with our section ID) (sorta optional)
|
|
Packit |
16808d |
: msg_in_SECTION_LIST (section listing as requested above)
|
|
Packit |
16808d |
|
|
Packit |
16808d |
: msg_out_UNKNOWNb
|
|
Packit |
16808d |
: msg_in_SECTION_PEER_JOINED (empty, with our place member ID)
|
|
Packit |
16808d |
: state = OPEN
|
|
Packit |
16808d |
|
|
Packit |
16808d |
: stuff... (invites, joins, parts, messages, attr)
|
|
Packit |
16808d |
|
|
Packit |
16808d |
: state = CLOSING
|
|
Packit |
16808d |
: msg_out_SECTION_PART
|
|
Packit |
16808d |
: destroy channel
|
|
Packit |
16808d |
: deallocate section
|
|
Packit |
16808d |
*/
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServicePlace {
|
|
Packit |
16808d |
struct mwService service;
|
|
Packit |
16808d |
struct mwPlaceHandler *handler;
|
|
Packit |
16808d |
GList *places;
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
enum mwPlaceState {
|
|
Packit |
16808d |
mwPlace_NEW,
|
|
Packit |
16808d |
mwPlace_PENDING,
|
|
Packit |
16808d |
mwPlace_JOINING,
|
|
Packit |
16808d |
mwPlace_JOINED,
|
|
Packit |
16808d |
mwPlace_OPEN,
|
|
Packit |
16808d |
mwPlace_CLOSING,
|
|
Packit |
16808d |
mwPlace_ERROR,
|
|
Packit |
16808d |
mwPlace_UNKNOWN,
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwPlace {
|
|
Packit |
16808d |
struct mwServicePlace *service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
enum mwPlaceState state;
|
|
Packit |
16808d |
struct mwChannel *channel;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
char *name;
|
|
Packit |
16808d |
char *title;
|
|
Packit |
16808d |
GHashTable *members; /* mapping of member ID: place_member */
|
|
Packit |
16808d |
guint32 our_id; /* our member ID */
|
|
Packit |
16808d |
guint32 section; /* the section we're using */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32 requests; /* counter for requests */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mw_datum client_data;
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct place_member {
|
|
Packit |
16808d |
guint32 place_id;
|
|
Packit |
16808d |
guint16 member_type;
|
|
Packit |
16808d |
struct mwIdBlock idb;
|
|
Packit |
16808d |
char *login_id;
|
|
Packit |
16808d |
char *name;
|
|
Packit |
16808d |
guint16 login_type;
|
|
Packit |
16808d |
guint32 unknown_a;
|
|
Packit |
16808d |
guint32 unknown_b;
|
|
Packit |
16808d |
};
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#define GET_MEMBER(place, id) \
|
|
Packit |
16808d |
(g_hash_table_lookup(place->members, GUINT_TO_POINTER(id)))
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#define PUT_MEMBER(place, member) \
|
|
Packit |
16808d |
(g_hash_table_insert(place->members, \
|
|
Packit |
16808d |
GUINT_TO_POINTER(member->place_id), member))
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#define REMOVE_MEMBER_ID(place, id) \
|
|
Packit |
16808d |
(g_hash_table_remove(place->members, GUINT_TO_POINTER(id)))
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
#define REMOVE_MEMBER(place, member) \
|
|
Packit |
16808d |
REMOVE_MEMBER_ID(place, member->place_id)
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void member_free(struct place_member *p) {
|
|
Packit |
16808d |
mwIdBlock_clear(&p->idb);
|
|
Packit |
16808d |
g_free(p->login_id);
|
|
Packit |
16808d |
g_free(p->name);
|
|
Packit |
16808d |
g_free(p);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
__attribute__((used))
|
|
Packit |
16808d |
static const struct mwLoginInfo *
|
|
Packit |
16808d |
member_as_login_info(struct place_member *p) {
|
|
Packit |
16808d |
static struct mwLoginInfo li;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
li.login_id = p->login_id;
|
|
Packit |
16808d |
li.type = p->login_type;
|
|
Packit |
16808d |
li.user_id = p->idb.user;
|
|
Packit |
16808d |
li.user_name = p->name;
|
|
Packit |
16808d |
li.community = p->idb.community;
|
|
Packit |
16808d |
li.full = FALSE;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return &li;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static const char *place_state_str(enum mwPlaceState s) {
|
|
Packit |
16808d |
switch(s) {
|
|
Packit |
16808d |
case mwPlace_NEW: return "new";
|
|
Packit |
16808d |
case mwPlace_PENDING: return "pending";
|
|
Packit |
16808d |
case mwPlace_JOINING: return "joining";
|
|
Packit |
16808d |
case mwPlace_JOINED: return "joined";
|
|
Packit |
16808d |
case mwPlace_OPEN: return "open";
|
|
Packit |
16808d |
case mwPlace_CLOSING: return "closing";
|
|
Packit |
16808d |
case mwPlace_ERROR: return "error";
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case mwPlace_UNKNOWN: /* fall-through */
|
|
Packit |
16808d |
default: return "UNKNOWN";
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void place_state(struct mwPlace *place, enum mwPlaceState s) {
|
|
Packit |
16808d |
g_return_if_fail(place != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(place->state == s) return;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place->state = s;
|
|
Packit |
16808d |
g_message("place %s state: %s", NSTR(place->name), place_state_str(s));
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void place_free(struct mwPlace *place) {
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! place) return;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = place->service;
|
|
Packit |
16808d |
g_return_if_fail(srvc != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc->places = g_list_remove_all(srvc->places, place);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mw_datum_clear(&place->client_data);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_hash_table_destroy(place->members);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_free(place->name);
|
|
Packit |
16808d |
g_free(place->title);
|
|
Packit |
16808d |
g_free(place);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_JOIN_RESPONSE(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
guint32 our_id, section;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &our_id);
|
|
Packit |
16808d |
guint32_get(b, §ion);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place->our_id = our_id;
|
|
Packit |
16808d |
place->section = section;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int send_SECTION_LIST(struct mwPlace *place, guint32 section) {
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
struct mwOpaque o = {0, 0};
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
guint16_put(b, msg_out_SECTION_LIST);
|
|
Packit |
16808d |
guint32_put(b, section);
|
|
Packit |
16808d |
gboolean_put(b, FALSE);
|
|
Packit |
16808d |
guint32_put(b, ++place->requests);
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwChannel_send(place->channel, msg_out_SECTION, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_INFO(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
guint32 skip = 0;
|
|
Packit |
16808d |
guint32 section = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &skip);
|
|
Packit |
16808d |
guint32_get(b, §ion);
|
|
Packit |
16808d |
mwGetBuffer_advance(b, skip);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! section) {
|
|
Packit |
16808d |
/* this is a place info rather than member info */
|
|
Packit |
16808d |
if(place->title) g_free(place->title);
|
|
Packit |
16808d |
mwGetBuffer_advance(b, 2);
|
|
Packit |
16808d |
mwString_get(b, &place->title);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place_state(place, mwPlace_JOINED);
|
|
Packit |
16808d |
ret = send_SECTION_LIST(place, place->section);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_MESSAGE(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
guint32 pm_id;
|
|
Packit |
16808d |
guint32 unkn_a, unkn_b, ign;
|
|
Packit |
16808d |
struct place_member *pm;
|
|
Packit |
16808d |
char *msg = NULL;
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = place->service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* no messages before becoming fully open, please */
|
|
Packit |
16808d |
g_return_val_if_fail(place->state == mwPlace_OPEN, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* regarding unkn_a and unkn_b:
|
|
Packit |
16808d |
|
|
Packit |
16808d |
they're probably a section indicator and a message count, I'm
|
|
Packit |
16808d |
just not sure which is which. Until this implementation supports
|
|
Packit |
16808d |
place sections in the API, it really doesn't matter. */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &pm_id);
|
|
Packit |
16808d |
pm = GET_MEMBER(place, pm_id);
|
|
Packit |
16808d |
g_return_val_if_fail(pm != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &unkn_a);
|
|
Packit |
16808d |
guint32_get(b, &ign;; /* actually an opaque length */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! ign) return ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &unkn_b);
|
|
Packit |
16808d |
mwString_get(b, &msg;;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc->handler && srvc->handler->message)
|
|
Packit |
16808d |
srvc->handler->message(place, &pm->idb, msg);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_free(msg);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void place_opened(struct mwPlace *place) {
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place_state(place, mwPlace_OPEN);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = place->service;
|
|
Packit |
16808d |
if(srvc->handler && srvc->handler->opened)
|
|
Packit |
16808d |
srvc->handler->opened(place);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_SECTION_PEER_JOIN(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
struct place_member *pm;
|
|
Packit |
16808d |
guint32 section;
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = place->service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, §ion);
|
|
Packit |
16808d |
if(! section) {
|
|
Packit |
16808d |
g_info("SECTION_PEER_JOIN with section 0x00");
|
|
Packit |
16808d |
return 0;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwGetBuffer_advance(b, 4);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
pm = g_new0(struct place_member, 1);
|
|
Packit |
16808d |
guint32_get(b, &pm->place_id);
|
|
Packit |
16808d |
guint16_get(b, &pm->member_type);
|
|
Packit |
16808d |
mwIdBlock_get(b, &pm->idb);
|
|
Packit |
16808d |
mwString_get(b, &pm->login_id);
|
|
Packit |
16808d |
mwString_get(b, &pm->name);
|
|
Packit |
16808d |
guint16_get(b, &pm->login_type);
|
|
Packit |
16808d |
guint32_get(b, &pm->unknown_a);
|
|
Packit |
16808d |
guint32_get(b, &pm->unknown_b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
PUT_MEMBER(place, pm);
|
|
Packit |
16808d |
if(srvc->handler && srvc->handler->peerJoined)
|
|
Packit |
16808d |
srvc->handler->peerJoined(place, &pm->idb);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(pm->place_id == place->our_id)
|
|
Packit |
16808d |
place_opened(place);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_SECTION_PEER_PART(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
guint32 section, id;
|
|
Packit |
16808d |
struct place_member *pm;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = place->service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, §ion);
|
|
Packit |
16808d |
g_return_val_if_fail(section == place->section, 0);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &id;;
|
|
Packit |
16808d |
pm = GET_MEMBER(place, id);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* SECTION_PART may have been called already */
|
|
Packit |
16808d |
if(! pm) return 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc->handler && srvc->handler->peerParted)
|
|
Packit |
16808d |
srvc->handler->peerParted(place, &pm->idb);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
REMOVE_MEMBER(place, pm);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_SECTION_PEER_CLEAR_ATTR(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
guint32 id, attr;
|
|
Packit |
16808d |
struct place_member *pm;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = place->service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &id;;
|
|
Packit |
16808d |
guint32_get(b, &attr);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
pm = GET_MEMBER(place, id);
|
|
Packit |
16808d |
g_return_val_if_fail(pm != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc->handler && srvc->handler->peerUnsetAttribute)
|
|
Packit |
16808d |
srvc->handler->peerUnsetAttribute(place, &pm->idb, attr);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_SECTION_PEER_SET_ATTR(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
guint32 id, attr;
|
|
Packit |
16808d |
struct mwOpaque o = {0,0};
|
|
Packit |
16808d |
struct place_member *pm;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = place->service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &id;;
|
|
Packit |
16808d |
mwGetBuffer_advance(b, 4);
|
|
Packit |
16808d |
mwOpaque_get(b, &o);
|
|
Packit |
16808d |
mwGetBuffer_advance(b, 4);
|
|
Packit |
16808d |
guint32_get(b, &attr);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
pm = GET_MEMBER(place, id);
|
|
Packit |
16808d |
g_return_val_if_fail(pm != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc->handler && srvc->handler->peerSetAttribute)
|
|
Packit |
16808d |
srvc->handler->peerSetAttribute(place, &pm->idb, attr, &o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_SECTION_PEER(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
guint16 subtype;
|
|
Packit |
16808d |
int res;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint16_get(b, &subtype);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(! mwGetBuffer_error(b), -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
switch(subtype) {
|
|
Packit |
16808d |
case msg_in_SECTION_PEER_JOIN:
|
|
Packit |
16808d |
res = recv_SECTION_PEER_JOIN(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_in_SECTION_PEER_PART:
|
|
Packit |
16808d |
res = recv_SECTION_PEER_PART(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_in_SECTION_PEER_CLEAR_ATTR:
|
|
Packit |
16808d |
res = recv_SECTION_PEER_CLEAR_ATTR(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_in_SECTION_PEER_SET_ATTR:
|
|
Packit |
16808d |
res = recv_SECTION_PEER_SET_ATTR(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
default:
|
|
Packit |
16808d |
res = -1;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return res;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_SECTION_LIST(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
guint32 sec, count;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwGetBuffer_advance(b, 4);
|
|
Packit |
16808d |
guint32_get(b, &sec);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(sec == place->section, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwGetBuffer_advance(b, 8);
|
|
Packit |
16808d |
guint32_get(b, &count);
|
|
Packit |
16808d |
mwGetBuffer_advance(b, 8);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
while(count--) {
|
|
Packit |
16808d |
struct place_member *m;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
m = g_new0(struct place_member, 1);
|
|
Packit |
16808d |
mwGetBuffer_advance(b, 4);
|
|
Packit |
16808d |
guint32_get(b, &m->place_id);
|
|
Packit |
16808d |
guint16_get(b, &m->member_type);
|
|
Packit |
16808d |
mwIdBlock_get(b, &m->idb);
|
|
Packit |
16808d |
mwString_get(b, &m->login_id);
|
|
Packit |
16808d |
mwString_get(b, &m->name);
|
|
Packit |
16808d |
guint16_get(b, &m->login_type);
|
|
Packit |
16808d |
guint32_get(b, &m->unknown_a);
|
|
Packit |
16808d |
guint32_get(b, &m->unknown_b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
PUT_MEMBER(place, m);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(place->state != mwPlace_OPEN)
|
|
Packit |
16808d |
place_opened(place);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_SECTION_PART(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwGetBuffer *b) {
|
|
Packit |
16808d |
/* look up user in place
|
|
Packit |
16808d |
remove user from place
|
|
Packit |
16808d |
trigger event */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
guint32 pm_id;
|
|
Packit |
16808d |
struct place_member *pm;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = place->service;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint32_get(b, &pm_id);
|
|
Packit |
16808d |
pm = GET_MEMBER(place, pm_id);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
/* SECTION_PEER_PART may have been called already */
|
|
Packit |
16808d |
if(! pm) return 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc->handler && srvc->handler->peerParted)
|
|
Packit |
16808d |
srvc->handler->peerParted(place, &pm->idb);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
REMOVE_MEMBER(place, pm);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return 0;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_SECTION(struct mwPlace *place, struct mwGetBuffer *b) {
|
|
Packit |
16808d |
guint16 subtype;
|
|
Packit |
16808d |
int res;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
guint16_get(b, &subtype);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(! mwGetBuffer_error(b), -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
switch(subtype) {
|
|
Packit |
16808d |
case msg_in_SECTION_LIST:
|
|
Packit |
16808d |
res = recv_SECTION_LIST(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_in_SECTION_PEER:
|
|
Packit |
16808d |
res = recv_SECTION_PEER(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_in_SECTION_PART:
|
|
Packit |
16808d |
res = recv_SECTION_PART(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
default:
|
|
Packit |
16808d |
res = -1;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return res;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int recv_UNKNOWNa(struct mwPlace *place, struct mwGetBuffer *b) {
|
|
Packit |
16808d |
int res = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(place->state == mwPlace_JOINING) {
|
|
Packit |
16808d |
;
|
|
Packit |
16808d |
/* place_state(place, mwPlace_JOINED);
|
|
Packit |
16808d |
res = send_SECTION_LIST(place, place->section); */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
} else if(place->state == mwPlace_JOINED) {
|
|
Packit |
16808d |
;
|
|
Packit |
16808d |
/* if(GET_MEMBER(place, place->our_id))
|
|
Packit |
16808d |
place_opened(place); */
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return res;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv(struct mwService *service, struct mwChannel *chan,
|
|
Packit |
16808d |
guint16 type, struct mwOpaque *data) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwPlace *place;
|
|
Packit |
16808d |
struct mwGetBuffer *b;
|
|
Packit |
16808d |
int res = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place = mwChannel_getServiceData(chan);
|
|
Packit |
16808d |
g_return_if_fail(place != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwGetBuffer_wrap(data);
|
|
Packit |
16808d |
switch(type) {
|
|
Packit |
16808d |
case msg_in_JOIN_RESPONSE:
|
|
Packit |
16808d |
res = recv_JOIN_RESPONSE(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_in_INFO:
|
|
Packit |
16808d |
res = recv_INFO(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_in_MESSAGE:
|
|
Packit |
16808d |
res = recv_MESSAGE(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_in_SECTION:
|
|
Packit |
16808d |
res = recv_SECTION(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
case msg_in_UNKNOWNa:
|
|
Packit |
16808d |
res = recv_UNKNOWNa(place, b);
|
|
Packit |
16808d |
break;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
default:
|
|
Packit |
16808d |
mw_mailme_opaque(data, "Received unknown message type 0x%x on place %s",
|
|
Packit |
16808d |
type, NSTR(place->name));
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(res) {
|
|
Packit |
16808d |
mw_mailme_opaque(data, "Troubling parsing message type 0x0%x on place %s",
|
|
Packit |
16808d |
type, NSTR(place->name));
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwGetBuffer_free(b);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void stop(struct mwServicePlace *srvc) {
|
|
Packit |
16808d |
while(srvc->places)
|
|
Packit |
16808d |
mwPlace_destroy(srvc->places->data, ERR_SUCCESS);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwService_stopped(MW_SERVICE(srvc));
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static int send_JOIN_PLACE(struct mwPlace *place) {
|
|
Packit |
16808d |
struct mwOpaque o = {0, 0};
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
gboolean_put(b, FALSE);
|
|
Packit |
16808d |
guint16_put(b, 0x01);
|
|
Packit |
16808d |
guint16_put(b, 0x02); /* 0x01 */
|
|
Packit |
16808d |
guint16_put(b, 0x01); /* 0x00 */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwChannel_send(place->channel, msg_out_JOIN_PLACE, &o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(ret) {
|
|
Packit |
16808d |
place_state(place, mwPlace_ERROR);
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
place_state(place, mwPlace_JOINING);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv_channelAccept(struct mwService *service,
|
|
Packit |
16808d |
struct mwChannel *chan,
|
|
Packit |
16808d |
struct mwMsgChannelAccept *msg) {
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
struct mwPlace *place;
|
|
Packit |
16808d |
int res;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = (struct mwServicePlace *) service;
|
|
Packit |
16808d |
g_return_if_fail(srvc != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place = mwChannel_getServiceData(chan);
|
|
Packit |
16808d |
g_return_if_fail(place != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
res = send_JOIN_PLACE(place);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void recv_channelDestroy(struct mwService *service,
|
|
Packit |
16808d |
struct mwChannel *chan,
|
|
Packit |
16808d |
struct mwMsgChannelDestroy *msg) {
|
|
Packit |
16808d |
struct mwServicePlace *srvc;
|
|
Packit |
16808d |
struct mwPlace *place;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = (struct mwServicePlace *) service;
|
|
Packit |
16808d |
g_return_if_fail(srvc != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place = mwChannel_getServiceData(chan);
|
|
Packit |
16808d |
g_return_if_fail(place != NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place_state(place, mwPlace_ERROR);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place->channel = NULL;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc->handler && srvc->handler->closed)
|
|
Packit |
16808d |
srvc->handler->closed(place, msg->reason);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPlace_destroy(place, msg->reason);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static void clear(struct mwServicePlace *srvc) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(srvc->handler && srvc->handler->clear)
|
|
Packit |
16808d |
srvc->handler->clear(srvc);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
while(srvc->places)
|
|
Packit |
16808d |
place_free(srvc->places->data);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static const char *get_name(struct mwService *srvc) {
|
|
Packit |
16808d |
return "Places Conferencing";
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static const char *get_desc(struct mwService *srvc) {
|
|
Packit |
16808d |
return "Barebones conferencing via Places";
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServicePlace *
|
|
Packit |
16808d |
mwServicePlace_new(struct mwSession *session,
|
|
Packit |
16808d |
struct mwPlaceHandler *handler) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServicePlace *srvc_place;
|
|
Packit |
16808d |
struct mwService *srvc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(session != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(handler != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc_place = g_new0(struct mwServicePlace, 1);
|
|
Packit |
16808d |
srvc_place->handler = handler;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc = MW_SERVICE(srvc_place);
|
|
Packit |
16808d |
mwService_init(srvc, session, mwService_PLACE);
|
|
Packit |
16808d |
srvc->start = NULL;
|
|
Packit |
16808d |
srvc->stop = (mwService_funcStop) stop;
|
|
Packit |
16808d |
srvc->recv_create = NULL;
|
|
Packit |
16808d |
srvc->recv_accept = recv_channelAccept;
|
|
Packit |
16808d |
srvc->recv_destroy = recv_channelDestroy;
|
|
Packit |
16808d |
srvc->recv = recv;
|
|
Packit |
16808d |
srvc->clear = (mwService_funcClear) clear;
|
|
Packit |
16808d |
srvc->get_name = get_name;
|
|
Packit |
16808d |
srvc->get_desc = get_desc;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return srvc_place;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwPlaceHandler *
|
|
Packit |
16808d |
mwServicePlace_getHandler(struct mwServicePlace *srvc) {
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, NULL);
|
|
Packit |
16808d |
return srvc->handler;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
const GList *mwServicePlace_getPlaces(struct mwServicePlace *srvc) {
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, NULL);
|
|
Packit |
16808d |
return srvc->places;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwPlace *mwPlace_new(struct mwServicePlace *srvc,
|
|
Packit |
16808d |
const char *name, const char *title) {
|
|
Packit |
16808d |
struct mwPlace *place;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(srvc != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place = g_new0(struct mwPlace, 1);
|
|
Packit |
16808d |
place->service = srvc;
|
|
Packit |
16808d |
place->name = g_strdup(name);
|
|
Packit |
16808d |
place->title = g_strdup(title);
|
|
Packit |
16808d |
place->state = mwPlace_NEW;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place->members = g_hash_table_new_full(g_direct_hash, g_direct_equal,
|
|
Packit |
16808d |
NULL, (GDestroyNotify) member_free);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srvc->places = g_list_prepend(srvc->places, place);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return place;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwServicePlace *mwPlace_getService(struct mwPlace *place) {
|
|
Packit |
16808d |
g_return_val_if_fail(place != NULL, NULL);
|
|
Packit |
16808d |
return place->service;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static char *place_generate_name(const char *user) {
|
|
Packit |
16808d |
guint a, b;
|
|
Packit |
16808d |
char *ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
user = user? user: "meanwhile";
|
|
Packit |
16808d |
|
|
Packit |
16808d |
srand(clock() + rand());
|
|
Packit |
16808d |
a = ((rand() & 0xff) << 8) | (rand() & 0xff);
|
|
Packit |
16808d |
b = time(NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = g_strdup_printf("%s(%08x,%04x)", user, b, a);
|
|
Packit |
16808d |
g_debug("generated random conference name: '%s'", ret);
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
const char *mwPlace_getName(struct mwPlace *place) {
|
|
Packit |
16808d |
g_return_val_if_fail(place != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! place->name) {
|
|
Packit |
16808d |
struct mwSession *session;
|
|
Packit |
16808d |
struct mwLoginInfo *li;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
session = mwService_getSession(MW_SERVICE(place->service));
|
|
Packit |
16808d |
li = mwSession_getLoginInfo(session);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place->name = place_generate_name(li? li->user_id: NULL);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return place->name;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
static char *place_generate_title(const char *user) {
|
|
Packit |
16808d |
char *ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
user = user? user: "Meanwhile";
|
|
Packit |
16808d |
ret = g_strdup_printf("%s's Conference", user);
|
|
Packit |
16808d |
g_debug("generated conference title: %s", ret);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
const char *mwPlace_getTitle(struct mwPlace *place) {
|
|
Packit |
16808d |
g_return_val_if_fail(place != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(! place->title) {
|
|
Packit |
16808d |
struct mwSession *session;
|
|
Packit |
16808d |
struct mwLoginInfo *li;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
session = mwService_getSession(MW_SERVICE(place->service));
|
|
Packit |
16808d |
li = mwSession_getLoginInfo(session);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place->title = place_generate_title(li? li->user_name: NULL);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return place->title;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwPlace_open(struct mwPlace *p) {
|
|
Packit |
16808d |
struct mwSession *session;
|
|
Packit |
16808d |
struct mwChannelSet *cs;
|
|
Packit |
16808d |
struct mwChannel *chan;
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(p != NULL, -1);
|
|
Packit |
16808d |
g_return_val_if_fail(p->service != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
session = mwService_getSession(MW_SERVICE(p->service));
|
|
Packit |
16808d |
g_return_val_if_fail(session != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
cs = mwSession_getChannels(session);
|
|
Packit |
16808d |
g_return_val_if_fail(cs != NULL, -1);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
chan = mwChannel_newOutgoing(cs);
|
|
Packit |
16808d |
mwChannel_setService(chan, MW_SERVICE(p->service));
|
|
Packit |
16808d |
mwChannel_setProtoType(chan, PROTOCOL_TYPE);
|
|
Packit |
16808d |
mwChannel_setProtoVer(chan, PROTOCOL_VER);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwChannel_populateSupportedCipherInstances(chan);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
mwString_put(b, mwPlace_getName(p));
|
|
Packit |
16808d |
mwString_put(b, mwPlace_getTitle(p));
|
|
Packit |
16808d |
guint32_put(b, 0x00); /* ? */
|
|
Packit |
16808d |
|
|
Packit |
16808d |
mwPutBuffer_finalize(mwChannel_getAddtlCreate(chan), b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwChannel_create(chan);
|
|
Packit |
16808d |
if(ret) {
|
|
Packit |
16808d |
place_state(p, mwPlace_ERROR);
|
|
Packit |
16808d |
} else {
|
|
Packit |
16808d |
place_state(p, mwPlace_PENDING);
|
|
Packit |
16808d |
p->channel = chan;
|
|
Packit |
16808d |
mwChannel_setServiceData(chan, p, NULL);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwPlace_destroy(struct mwPlace *p, guint32 code) {
|
|
Packit |
16808d |
int ret = 0;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place_state(p, mwPlace_CLOSING);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
if(p->channel) {
|
|
Packit |
16808d |
ret = mwChannel_destroy(p->channel, code, NULL);
|
|
Packit |
16808d |
p->channel = NULL;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
place_free(p);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
GList *mwPlace_getMembers(struct mwPlace *place) {
|
|
Packit |
16808d |
GList *l, *ll;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_val_if_fail(place != NULL, NULL);
|
|
Packit |
16808d |
g_return_val_if_fail(place->members != NULL, NULL);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ll = map_collect_values(place->members);
|
|
Packit |
16808d |
for(l = ll; l; l = l->next) {
|
|
Packit |
16808d |
struct place_member *pm = l->data;
|
|
Packit |
16808d |
l->data = &pm->idb;
|
|
Packit |
16808d |
g_info("collected member %u: %s, %s", pm->place_id,
|
|
Packit |
16808d |
NSTR(pm->idb.user), NSTR(pm->idb.community));
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
return ll;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwPlace_sendText(struct mwPlace *place, const char *msg) {
|
|
Packit |
16808d |
struct mwOpaque o = {0,0};
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
guint32_put(b, 0x01); /* probably a message type */
|
|
Packit |
16808d |
mwString_put(b, msg);
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
guint32_put(b, place->section);
|
|
Packit |
16808d |
mwOpaque_put(b, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwChannel_send(place->channel, msg_out_MESSAGE, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwPlace_legacyInvite(struct mwPlace *place,
|
|
Packit |
16808d |
struct mwIdBlock *idb,
|
|
Packit |
16808d |
const char *message) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwOpaque o = {0,0};
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
mwIdBlock_put(b, idb);
|
|
Packit |
16808d |
mwString_put(b, idb->user);
|
|
Packit |
16808d |
mwString_put(b, idb->user);
|
|
Packit |
16808d |
mwString_put(b, message);
|
|
Packit |
16808d |
gboolean_put(b, FALSE);
|
|
Packit |
16808d |
mwPutBuffer_finalize(&o, b);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwChannel_send(place->channel, msg_out_OLD_INVITE, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwPlace_setAttribute(struct mwPlace *place, guint32 attrib,
|
|
Packit |
16808d |
struct mwOpaque *data) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
struct mwOpaque o = {0,0};
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
guint32_put(b, place->our_id);
|
|
Packit |
16808d |
guint32_put(b, 0x00);
|
|
Packit |
16808d |
guint32_put(b, attrib);
|
|
Packit |
16808d |
mwOpaque_put(b, data);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwChannel_send(place->channel, msg_out_SET_ATTR, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
int mwPlace_unsetAttribute(struct mwPlace *place, guint32 attrib) {
|
|
Packit |
16808d |
struct mwOpaque o = {0,0};
|
|
Packit |
16808d |
struct mwPutBuffer *b;
|
|
Packit |
16808d |
int ret;
|
|
Packit |
16808d |
|
|
Packit |
16808d |
b = mwPutBuffer_new();
|
|
Packit |
16808d |
guint32_put(b, place->our_id);
|
|
Packit |
16808d |
guint32_put(b, attrib);
|
|
Packit |
16808d |
|
|
Packit |
16808d |
ret = mwChannel_send(place->channel, msg_out_SET_ATTR, &o);
|
|
Packit |
16808d |
mwOpaque_clear(&o);
|
|
Packit |
16808d |
return ret;
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
void mwPlace_setClientData(struct mwPlace *place,
|
|
Packit |
16808d |
gpointer data, GDestroyNotify clear) {
|
|
Packit |
16808d |
|
|
Packit |
16808d |
g_return_if_fail(place != NULL);
|
|
Packit |
16808d |
mw_datum_set(&place->client_data, data, clear);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
gpointer mwPlace_getClientData(struct mwPlace *place) {
|
|
Packit |
16808d |
g_return_val_if_fail(place != NULL, NULL);
|
|
Packit |
16808d |
return mw_datum_get(&place->client_data);
|
|
Packit |
16808d |
}
|
|
Packit |
16808d |
|
|
Packit |
16808d |
|
|
Packit |
16808d |
void mwPlace_removeClientData(struct mwPlace *place) {
|
|
Packit |
16808d |
g_return_if_fail(place != NULL);
|
|
Packit |
16808d |
mw_datum_clear(&place->client_data);
|
|
Packit |
16808d |
}
|