c-chat-room.cpp 11.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * c-chat-room.cpp
 * Copyright (C) 2017  Belledonne Communications SARL
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

19
// TODO: Remove me later.
20
#include "linphone/chat.h"
Ronan's avatar
Ronan committed
21

22
#include "linphone/wrapper_utils.h"
23
#include "linphone/api/c-chat-room.h"
24

25
#include "c-wrapper/c-wrapper.h"
26 27 28 29
#include "chat/basic-chat-room.h"
#include "chat/client-group-chat-room.h"
#include "chat/real-time-text-chat-room-p.h"

Ronan's avatar
Ronan committed
30
// =============================================================================
31

32
#define GET_CPP_PTR(obj) L_GET_CPP_PTR_FROM_C_OBJECT(obj)
33
#define GET_CPP_PRIVATE_PTR(obj) L_GET_PRIVATE_FROM_C_OBJECT(obj)
34

Ronan's avatar
Ronan committed
35
using namespace std;
36

Ronan's avatar
Ronan committed
37 38
static void _linphone_chat_room_constructor (LinphoneChatRoom *cr);
static void _linphone_chat_room_destructor (LinphoneChatRoom *cr);
39

40
L_DECLARE_C_OBJECT_IMPL_WITH_XTORS(
41
	ChatRoom,
42
	_linphone_chat_room_constructor, _linphone_chat_room_destructor,
43
	LinphoneChatRoomCbs *cbs;
44 45 46
	LinphoneAddress *peerAddressCache;
)

Ronan's avatar
Ronan committed
47
static void _linphone_chat_room_constructor (LinphoneChatRoom *cr) {
48 49
	cr->cbs = linphone_chat_room_cbs_new();
}
50

Ronan's avatar
Ronan committed
51
static void _linphone_chat_room_destructor (LinphoneChatRoom *cr) {
52 53
	linphone_chat_room_cbs_unref(cr->cbs);
	cr->cbs = nullptr;
54 55 56 57 58 59
	if (cr->peerAddressCache) {
		linphone_address_unref(cr->peerAddressCache);
		cr->peerAddressCache = nullptr;
	}
}

Ronan's avatar
Ronan committed
60 61 62
// =============================================================================
// Public functions.
// =============================================================================
63

Ronan's avatar
Ronan committed
64
void linphone_chat_room_release (LinphoneChatRoom *cr) {
65 66 67
	GET_CPP_PRIVATE_PTR(cr)->release();
}

Ronan's avatar
Ronan committed
68
void linphone_chat_room_remove_transient_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
69 70 71
	GET_CPP_PRIVATE_PTR(cr)->removeTransientMessage(msg);
}

Ronan's avatar
Ronan committed
72
void linphone_chat_room_send_message (LinphoneChatRoom *cr, const char *msg) {
73 74 75
	GET_CPP_PTR(cr)->sendMessage(GET_CPP_PTR(cr)->createMessage(msg));
}

Ronan's avatar
Ronan committed
76
bool_t linphone_chat_room_is_remote_composing (const LinphoneChatRoom *cr) {
77 78 79
	return GET_CPP_PTR(cr)->isRemoteComposing();
}

Ronan's avatar
Ronan committed
80
LinphoneCore *linphone_chat_room_get_lc (const LinphoneChatRoom *cr) {
81 82 83
	return linphone_chat_room_get_core(cr);
}

Ronan's avatar
Ronan committed
84
LinphoneCore *linphone_chat_room_get_core (const LinphoneChatRoom *cr) {
85 86 87
	return GET_CPP_PTR(cr)->getCore();
}

Ronan's avatar
Ronan committed
88
const LinphoneAddress *linphone_chat_room_get_peer_address (LinphoneChatRoom *cr) {
89 90 91 92 93 94 95
	if (cr->peerAddressCache) {
		linphone_address_unref(cr->peerAddressCache);
	}
	cr->peerAddressCache = linphone_address_new(GET_CPP_PTR(cr)->getPeerAddress().asString().c_str());
	return cr->peerAddressCache;
}

Ronan's avatar
Ronan committed
96
LinphoneChatMessage *linphone_chat_room_create_message (LinphoneChatRoom *cr, const char *message) {
97 98 99
	return GET_CPP_PTR(cr)->createMessage(message ? message : "");
}

Ronan's avatar
Ronan committed
100 101 102 103 104 105 106 107 108
LinphoneChatMessage *linphone_chat_room_create_message_2 (
	LinphoneChatRoom *cr,
	const char *message,
	const char *external_body_url,
	LinphoneChatMessageState state,
	time_t time,
	bool_t is_read,
	bool_t is_incoming
) {
109 110
	LinphoneChatMessage *msg = linphone_chat_room_create_message(cr, message);
	LinphoneCore *lc = linphone_chat_room_get_core(cr);
111 112 113
	linphone_chat_message_set_external_body_url(msg, external_body_url ? ms_strdup(external_body_url) : NULL);
	linphone_chat_message_set_time(msg, time);
	linphone_chat_message_set_is_secured(msg, FALSE);
114 115
	linphone_chat_message_set_state(msg, state);
	if (is_incoming) {
116 117 118
		linphone_chat_message_set_incoming(msg);
		linphone_chat_message_set_from_address(msg, linphone_chat_room_get_peer_address(cr));
		linphone_chat_message_set_to_address(msg, linphone_address_new(linphone_core_get_identity(lc)));
119
	} else {
120 121 122
		linphone_chat_message_set_outgoing(msg);
		linphone_chat_message_set_to_address(msg, linphone_chat_room_get_peer_address(cr));
		linphone_chat_message_set_from_address(msg, linphone_address_new(linphone_core_get_identity(lc)));
123 124 125 126
	}
	return msg;
}

Ronan's avatar
Ronan committed
127 128 129 130 131 132
void linphone_chat_room_send_message2 (
	LinphoneChatRoom *cr,
	LinphoneChatMessage *msg,
	LinphoneChatMessageStateChangedCb status_cb,
	void *ud
) {
133 134
	linphone_chat_message_set_message_state_changed_cb(msg, status_cb);
	linphone_chat_message_set_message_state_changed_cb_user_data(msg, ud);
135 136 137
	GET_CPP_PTR(cr)->sendMessage(msg);
}

Ronan's avatar
Ronan committed
138
void linphone_chat_room_send_chat_message_2 (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
139 140 141 142
	linphone_chat_message_ref(msg);
	GET_CPP_PTR(cr)->sendMessage(msg);
}

Ronan's avatar
Ronan committed
143
void linphone_chat_room_send_chat_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
144 145 146
	GET_CPP_PTR(cr)->sendMessage(msg);
}

Ronan's avatar
Ronan committed
147
uint32_t linphone_chat_room_get_char (const LinphoneChatRoom *cr) {
148 149 150 151 152
	if (linphone_core_realtime_text_enabled(linphone_chat_room_get_core(cr)))
		return static_cast<const LinphonePrivate::RealTimeTextChatRoom *>(GET_CPP_PTR(cr).get())->getChar();
	return 0;
}

Ronan's avatar
Ronan committed
153
void linphone_chat_room_compose (LinphoneChatRoom *cr) {
154 155 156
	GET_CPP_PTR(cr)->compose();
}

Ronan's avatar
Ronan committed
157
LinphoneCall *linphone_chat_room_get_call (const LinphoneChatRoom *cr) {
158 159 160 161 162
	if (linphone_core_realtime_text_enabled(linphone_chat_room_get_core(cr)))
		return static_cast<const LinphonePrivate::RealTimeTextChatRoom *>(GET_CPP_PTR(cr).get())->getCall();
	return nullptr;
}

Ronan's avatar
Ronan committed
163
void linphone_chat_room_set_call (LinphoneChatRoom *cr, LinphoneCall *call) {
164 165 166 167
	if (linphone_core_realtime_text_enabled(linphone_chat_room_get_core(cr)))
		static_cast<LinphonePrivate::RealTimeTextChatRoomPrivate *>(GET_CPP_PRIVATE_PTR(cr))->setCall(call);
}

Ronan's avatar
Ronan committed
168
bctbx_list_t *linphone_chat_room_get_transient_messages (const LinphoneChatRoom *cr) {
169 170 171
	return L_GET_C_LIST_FROM_CPP_LIST(GET_CPP_PRIVATE_PTR(cr)->getTransientMessages(), LinphoneChatMessage);
}

Ronan's avatar
Ronan committed
172
void linphone_chat_room_mark_as_read (LinphoneChatRoom *cr) {
173 174 175
	GET_CPP_PTR(cr)->markAsRead();
}

Ronan's avatar
Ronan committed
176
int linphone_chat_room_get_unread_messages_count (LinphoneChatRoom *cr) {
177 178 179
	return GET_CPP_PTR(cr)->getUnreadMessagesCount();
}

Ronan's avatar
Ronan committed
180
int linphone_chat_room_get_history_size (LinphoneChatRoom *cr) {
181 182 183
	return GET_CPP_PTR(cr)->getHistorySize();
}

Ronan's avatar
Ronan committed
184
void linphone_chat_room_delete_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
185 186 187
	GET_CPP_PTR(cr)->deleteMessage(msg);
}

Ronan's avatar
Ronan committed
188
void linphone_chat_room_delete_history (LinphoneChatRoom *cr) {
189 190 191
	GET_CPP_PTR(cr)->deleteHistory();
}

Ronan's avatar
Ronan committed
192
bctbx_list_t *linphone_chat_room_get_history_range (LinphoneChatRoom *cr, int startm, int endm) {
193 194 195
	return L_GET_C_LIST_FROM_CPP_LIST(GET_CPP_PTR(cr)->getHistoryRange(startm, endm), LinphoneChatMessage);
}

Ronan's avatar
Ronan committed
196
bctbx_list_t *linphone_chat_room_get_history (LinphoneChatRoom *cr, int nb_message) {
197 198 199
	return L_GET_C_LIST_FROM_CPP_LIST(GET_CPP_PTR(cr)->getHistory(nb_message), LinphoneChatMessage);
}

Ronan's avatar
Ronan committed
200
LinphoneChatMessage *linphone_chat_room_find_message (LinphoneChatRoom *cr, const char *message_id) {
201 202 203
	return GET_CPP_PTR(cr)->findMessage(message_id);
}

Ronan's avatar
Ronan committed
204
LinphoneChatRoomCbs *linphone_chat_room_get_callbacks (const LinphoneChatRoom *cr) {
205 206 207
	return cr->cbs;
}

208 209 210 211
LinphoneChatRoomState linphone_chat_room_get_state (const LinphoneChatRoom *cr) {
	return (LinphoneChatRoomState)GET_CPP_PTR(cr)->getState();
}

Ronan's avatar
Ronan committed
212
LinphoneParticipant *linphone_chat_room_add_participant (LinphoneChatRoom *cr, const LinphoneAddress *addr) {
213
	return L_GET_C_BACK_PTR(GET_CPP_PTR(cr)->addParticipant(
214
			*L_GET_CPP_PTR_FROM_C_OBJECT(addr), nullptr, false),
Ronan's avatar
Ronan committed
215
		Participant);
216 217 218 219 220 221 222 223 224 225
}

void linphone_chat_room_add_participants (LinphoneChatRoom *cr, const bctbx_list_t *addresses) {
	GET_CPP_PTR(cr)->addParticipants(L_GET_CPP_LIST_OF_CPP_OBJ_FROM_C_LIST_OF_STRUCT_PTR(addresses, Address, Address), nullptr, false);
}

bool_t linphone_chat_room_can_handle_participants (const LinphoneChatRoom *cr) {
	return GET_CPP_PTR(cr)->canHandleParticipants();
}

Ronan's avatar
Ronan committed
226
const char *linphone_chat_room_get_id (const LinphoneChatRoom *cr) {
227 228 229 230 231 232 233 234
	string id = GET_CPP_PTR(cr)->getId();
	return id.empty() ? nullptr : id.c_str();
}

int linphone_chat_room_get_nb_participants (const LinphoneChatRoom *cr) {
	return GET_CPP_PTR(cr)->getNbParticipants();
}

Ronan's avatar
Ronan committed
235
bctbx_list_t *linphone_chat_room_get_participants (const LinphoneChatRoom *cr) {
Ronan's avatar
Ronan committed
236
	return L_GET_C_LIST_OF_STRUCT_PTR_FROM_CPP_LIST_OF_CPP_OBJ(GET_CPP_PTR(cr)->getParticipants(), Participant, Participant);
237 238 239
}

void linphone_chat_room_remove_participant (LinphoneChatRoom *cr, LinphoneParticipant *participant) {
240
	GET_CPP_PTR(cr)->removeParticipant(L_GET_CPP_PTR_FROM_C_OBJECT(participant));
241 242 243 244 245 246
}

void linphone_chat_room_remove_participants (LinphoneChatRoom *cr, const bctbx_list_t *participants) {
	GET_CPP_PTR(cr)->removeParticipants(L_GET_CPP_LIST_OF_CPP_OBJ_FROM_C_LIST_OF_STRUCT_PTR(participants, Participant, Participant));
}

Ronan's avatar
Ronan committed
247 248 249
// =============================================================================
// Reference and user data handling functions.
// =============================================================================
250

Ronan's avatar
Ronan committed
251
LinphoneChatRoom *linphone_chat_room_ref (LinphoneChatRoom *cr) {
252 253 254 255
	belle_sip_object_ref(cr);
	return cr;
}

Ronan's avatar
Ronan committed
256
void linphone_chat_room_unref (LinphoneChatRoom *cr) {
257 258 259
	belle_sip_object_unref(cr);
}

Ronan's avatar
Ronan committed
260
void *linphone_chat_room_get_user_data (const LinphoneChatRoom *cr) {
261
	return L_GET_USER_DATA_FROM_C_OBJECT(cr, ChatRoom);
262 263
}

Ronan's avatar
Ronan committed
264
void linphone_chat_room_set_user_data (LinphoneChatRoom *cr, void *ud) {
265
	L_SET_USER_DATA_FROM_C_OBJECT(cr, ud, ChatRoom);
266 267
}

Ronan's avatar
Ronan committed
268 269 270
// =============================================================================
// Constructor and destructor functions.
// =============================================================================
271

Ronan's avatar
Ronan committed
272
LinphoneChatRoom *linphone_chat_room_new (LinphoneCore *core, const LinphoneAddress *addr) {
Ronan's avatar
Ronan committed
273
	LinphoneChatRoom *cr = _linphone_ChatRoom_init();
274
	if (linphone_core_realtime_text_enabled(core))
275
		L_SET_CPP_PTR_FROM_C_OBJECT(cr, std::make_shared<LinphonePrivate::RealTimeTextChatRoom>(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr)));
276
	else
277
		L_SET_CPP_PTR_FROM_C_OBJECT(cr, std::make_shared<LinphonePrivate::BasicChatRoom>(core, *L_GET_CPP_PTR_FROM_C_OBJECT(addr)));
278
	linphone_core_notify_chat_room_instantiated(core, cr);
279 280
	L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
	L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Created);
281 282 283
	return cr;
}

Ronan's avatar
Ronan committed
284
LinphoneChatRoom *linphone_client_group_chat_room_new (LinphoneCore *core, const bctbx_list_t *addresses) {
285
	const char *factoryUri = linphone_core_get_chat_conference_factory_uri(core);
286 287 288
	if (!factoryUri)
		return nullptr;
	LinphoneAddress *factoryAddr = linphone_address_new(factoryUri);
289
	LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(core, factoryAddr);
290 291 292
	linphone_address_unref(factoryAddr);
	std::string from;
	if (proxy)
293
		from = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_proxy_config_get_identity_address(proxy))->asString();
294
	if (from.empty())
295
		from = linphone_core_get_primary_contact(core);
296
	LinphonePrivate::Address me(from);
297
	std::list<LinphonePrivate::Address> l = L_GET_CPP_LIST_OF_CPP_OBJ_FROM_C_LIST_OF_STRUCT_PTR(addresses, Address, Address);
Ronan's avatar
Ronan committed
298
	LinphoneChatRoom *cr = _linphone_ChatRoom_init();
299
	L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::ClientGroupChatRoom>(core, me, l));
300
	linphone_core_notify_chat_room_instantiated(core, cr);
301 302
	L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
	L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::CreationPending);
303 304 305 306
	return cr;
}

/* DEPRECATED */
Ronan's avatar
Ronan committed
307
void linphone_chat_room_destroy (LinphoneChatRoom *cr) {
308 309
	linphone_chat_room_unref(cr);
}