c-chat-room.cpp 11.7 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/api/c-chat-room.h"
23

24
#include "c-wrapper/c-wrapper.h"
25 26 27 28
#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
29
// =============================================================================
30

31 32
#define GET_CPP_PTR(obj) L_GET_CPP_PTR_FROM_C_STRUCT(obj, ChatRoom)
#define GET_CPP_PRIVATE_PTR(obj) L_GET_PRIVATE_FROM_C_STRUCT(obj, ChatRoom)
33

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

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

Ronan's avatar
Ronan committed
39 40
L_DECLARE_C_STRUCT_IMPL_WITH_XTORS(
	ChatRoom, ChatRoom,
41
	_linphone_chat_room_constructor, _linphone_chat_room_destructor,
42
	LinphoneChatRoomCbs *cbs;
43 44 45
	LinphoneAddress *peerAddressCache;
)

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

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

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

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

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

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

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

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

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

Ronan's avatar
Ronan committed
87
const LinphoneAddress *linphone_chat_room_get_peer_address (LinphoneChatRoom *cr) {
88 89 90 91 92 93 94
	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
95
LinphoneChatMessage *linphone_chat_room_create_message (LinphoneChatRoom *cr, const char *message) {
96 97 98
	return GET_CPP_PTR(cr)->createMessage(message ? message : "");
}

Ronan's avatar
Ronan committed
99 100 101 102 103 104 105 106 107
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
) {
108 109
	LinphoneChatMessage *msg = linphone_chat_room_create_message(cr, message);
	LinphoneCore *lc = linphone_chat_room_get_core(cr);
110 111 112
	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);
113 114
	linphone_chat_message_set_state(msg, state);
	if (is_incoming) {
115 116 117
		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)));
118
	} else {
119 120 121
		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)));
122 123 124 125
	}
	return msg;
}

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

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

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

Ronan's avatar
Ronan committed
146
uint32_t linphone_chat_room_get_char (const LinphoneChatRoom *cr) {
147 148 149 150 151
	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
152
void linphone_chat_room_compose (LinphoneChatRoom *cr) {
153 154 155
	GET_CPP_PTR(cr)->compose();
}

Ronan's avatar
Ronan committed
156
LinphoneCall *linphone_chat_room_get_call (const LinphoneChatRoom *cr) {
157 158 159 160 161
	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
162
void linphone_chat_room_set_call (LinphoneChatRoom *cr, LinphoneCall *call) {
163 164 165 166
	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
167
bctbx_list_t *linphone_chat_room_get_transient_messages (const LinphoneChatRoom *cr) {
168 169 170
	return L_GET_C_LIST_FROM_CPP_LIST(GET_CPP_PRIVATE_PTR(cr)->getTransientMessages(), LinphoneChatMessage);
}

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

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

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

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

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

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

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

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

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

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

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

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
225
const char *linphone_chat_room_get_id (const LinphoneChatRoom *cr) {
226 227 228 229 230 231 232 233
	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
234
bctbx_list_t *linphone_chat_room_get_participants (const LinphoneChatRoom *cr) {
Ronan's avatar
Ronan committed
235
	return L_GET_C_LIST_OF_STRUCT_PTR_FROM_CPP_LIST_OF_CPP_OBJ(GET_CPP_PTR(cr)->getParticipants(), Participant, Participant);
236 237 238
}

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

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
246 247 248
// =============================================================================
// Reference and user data handling functions.
// =============================================================================
249

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

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

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

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

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

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

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

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