Coverage Report

Created: 2025-10-08 19:34

/work/toxcore/Messenger.h
Line
Count
Source
1
/* SPDX-License-Identifier: GPL-3.0-or-later
2
 * Copyright © 2016-2025 The TokTok team.
3
 * Copyright © 2013 Tox project.
4
 */
5
6
/**
7
 * An implementation of a simple text chat only messenger on the tox network
8
 * core.
9
 */
10
#ifndef C_TOXCORE_TOXCORE_MESSENGER_H
11
#define C_TOXCORE_TOXCORE_MESSENGER_H
12
13
#include "DHT.h"
14
#include "TCP_client.h"
15
#include "TCP_server.h"
16
#include "announce.h"
17
#include "attributes.h"
18
#include "crypto_core.h"
19
#include "forwarding.h"
20
#include "friend_connection.h"
21
#include "friend_requests.h"
22
#include "group_announce.h"
23
#include "group_common.h"
24
#include "logger.h"
25
#include "mem.h"
26
#include "mono_time.h"
27
#include "net_crypto.h"
28
#include "net_profile.h"
29
#include "network.h"
30
#include "onion.h"
31
#include "onion_announce.h"
32
#include "onion_client.h"
33
#include "state.h"
34
35
24.0k
#define MAX_NAME_LENGTH 128
36
/* TODO(irungentoo): this must depend on other variable. */
37
3.66k
#define MAX_STATUSMESSAGE_LENGTH 1007
38
/* Used for TCP relays in Messenger struct (may need to be `% 2 == 0`)*/
39
4.97k
#define NUM_SAVED_TCP_RELAYS 8
40
/* This cannot be bigger than 256 */
41
45.2M
#define MAX_CONCURRENT_FILE_PIPES 256
42
43
505
#define FRIEND_ADDRESS_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
44
45
typedef enum Message_Type {
46
    MESSAGE_NORMAL,
47
    MESSAGE_ACTION,
48
} Message_Type;
49
50
// TODO(Jfreegman, Iphy): Remove this before merge
51
#ifndef MESSENGER_DEFINED
52
#define MESSENGER_DEFINED
53
typedef struct Messenger Messenger;
54
#endif /* MESSENGER_DEFINED */
55
56
// Returns the size of the data
57
typedef uint32_t m_state_size_cb(const Messenger *_Nonnull m);
58
59
// Returns the new pointer to data
60
typedef uint8_t *m_state_save_cb(const Messenger *_Nonnull m, uint8_t *_Nonnull data);
61
62
// Returns if there were any erros during loading
63
typedef State_Load_Status m_state_load_cb(Messenger *_Nonnull m, const uint8_t *_Nonnull data, uint32_t length);
64
65
typedef struct Messenger_State_Plugin {
66
    State_Type type;
67
    m_state_size_cb *_Nullable size;
68
    m_state_save_cb *_Nullable save;
69
    m_state_load_cb *_Nullable load;
70
} Messenger_State_Plugin;
71
72
typedef struct Messenger_Options {
73
    bool ipv6enabled;
74
    bool udp_disabled;
75
    TCP_Proxy_Info proxy_info;
76
    uint16_t port_range[2];
77
    uint16_t tcp_server_port;
78
79
    bool hole_punching_enabled;
80
    bool local_discovery_enabled;
81
    bool dht_announcements_enabled;
82
    bool groups_persistence_enabled;
83
84
    logger_cb *_Nullable log_callback;
85
    void *_Nullable log_context;
86
    void *_Nullable log_user_data;
87
88
    Messenger_State_Plugin *_Nullable state_plugins;
89
    uint8_t state_plugins_length;
90
91
    bool dns_enabled;
92
} Messenger_Options;
93
94
struct Receipts {
95
    uint32_t packet_num;
96
    uint32_t msg_id;
97
    struct Receipts *_Nullable next;
98
};
99
100
/** Status definitions. */
101
typedef enum Friend_Status {
102
    NOFRIEND,
103
    FRIEND_ADDED,
104
    FRIEND_REQUESTED,
105
    FRIEND_CONFIRMED,
106
    FRIEND_ONLINE,
107
} Friend_Status;
108
109
/** @brief Errors for m_addfriend
110
 *
111
 * FAERR - Friend Add Error
112
 */
113
typedef enum Friend_Add_Error {
114
    FAERR_TOOLONG = -1,
115
    FAERR_NOMESSAGE = -2,
116
    FAERR_OWNKEY = -3,
117
    FAERR_ALREADYSENT = -4,
118
    FAERR_BADCHECKSUM = -6,
119
    FAERR_SETNEWNOSPAM = -7,
120
    FAERR_NOMEM = -8,
121
} Friend_Add_Error;
122
123
/** Default start timeout in seconds between friend requests. */
124
187
#define FRIENDREQUEST_TIMEOUT 5
125
126
typedef enum Connection_Status {
127
    CONNECTION_NONE,
128
    CONNECTION_TCP,
129
    CONNECTION_UDP,
130
} Connection_Status;
131
132
/**
133
 * Represents userstatuses someone can have.
134
 */
135
typedef enum Userstatus {
136
    USERSTATUS_NONE,
137
    USERSTATUS_AWAY,
138
    USERSTATUS_BUSY,
139
    USERSTATUS_INVALID,
140
} Userstatus;
141
142
24
#define FILE_ID_LENGTH 32
143
144
struct File_Transfers {
145
    uint64_t size;
146
    uint64_t transferred;
147
    uint8_t status; /* 0 == no transfer, 1 = not accepted, 3 = transferring, 4 = broken, 5 = finished */
148
    uint8_t paused; /* 0: not paused, 1 = paused by us, 2 = paused by other, 3 = paused by both. */
149
    uint32_t last_packet_number; /* number of the last packet sent. */
150
    uint64_t requested; /* total data requested by the request chunk callback */
151
    uint8_t id[FILE_ID_LENGTH];
152
};
153
typedef enum Filestatus {
154
    FILESTATUS_NONE,
155
    FILESTATUS_NOT_ACCEPTED,
156
    FILESTATUS_TRANSFERRING,
157
    // FILESTATUS_BROKEN,
158
    FILESTATUS_FINISHED,
159
} Filestatus;
160
161
typedef enum File_Pause {
162
    FILE_PAUSE_NOT,
163
    FILE_PAUSE_US,
164
    FILE_PAUSE_OTHER,
165
    FILE_PAUSE_BOTH,
166
} File_Pause;
167
168
typedef enum Filecontrol {
169
    FILECONTROL_ACCEPT,
170
    FILECONTROL_PAUSE,
171
    FILECONTROL_KILL,
172
    FILECONTROL_SEEK,
173
} Filecontrol;
174
175
typedef enum Filekind {
176
    FILEKIND_DATA,
177
    FILEKIND_AVATAR,
178
} Filekind;
179
180
typedef void m_self_connection_status_cb(Messenger *_Nonnull m, Onion_Connection_Status connection_status, void *_Nullable user_data);
181
typedef void m_friend_status_cb(Messenger *_Nonnull m, uint32_t friend_number, unsigned int status, void *_Nullable user_data);
182
typedef void m_friend_connection_status_cb(Messenger *_Nonnull m, uint32_t friend_number, unsigned int connection_status,
183
        void *_Nullable user_data);
184
typedef void m_friend_message_cb(Messenger *_Nonnull m, uint32_t friend_number, unsigned int message_type,
185
                                 const uint8_t *_Nonnull message, size_t length, void *_Nullable user_data);
186
typedef void m_file_recv_control_cb(Messenger *_Nonnull m, uint32_t friend_number, uint32_t file_number, unsigned int control,
187
                                    void *_Nullable user_data);
188
typedef void m_friend_request_cb(Messenger *_Nonnull m, const uint8_t *_Nonnull public_key, const uint8_t *_Nonnull message, size_t length,
189
                                 void *_Nullable user_data);
190
typedef void m_friend_name_cb(Messenger *_Nonnull m, uint32_t friend_number, const uint8_t *_Nonnull name, size_t length,
191
                              void *_Nullable user_data);
192
typedef void m_friend_status_message_cb(Messenger *_Nonnull m, uint32_t friend_number, const uint8_t *_Nonnull message, size_t length,
193
                                        void *_Nullable user_data);
194
typedef void m_friend_typing_cb(Messenger *_Nonnull m, uint32_t friend_number, bool is_typing, void *_Nullable user_data);
195
typedef void m_friend_read_receipt_cb(Messenger *_Nonnull m, uint32_t friend_number, uint32_t message_id, void *_Nullable user_data);
196
typedef void m_file_recv_cb(Messenger *_Nonnull m, uint32_t friend_number, uint32_t file_number, uint32_t kind,
197
                            uint64_t file_size, const uint8_t *_Nonnull filename, size_t filename_length, void *_Nullable user_data);
198
typedef void m_file_chunk_request_cb(Messenger *_Nonnull m, uint32_t friend_number, uint32_t file_number, uint64_t position,
199
                                     size_t length, void *_Nullable user_data);
200
typedef void m_file_recv_chunk_cb(Messenger *_Nonnull m, uint32_t friend_number, uint32_t file_number, uint64_t position,
201
                                  const uint8_t *_Nullable data, size_t length, void *_Nullable user_data);
202
typedef void m_friend_lossy_packet_cb(Messenger *_Nonnull m, uint32_t friend_number, uint8_t packet_id, const uint8_t *_Nonnull data,
203
                                      size_t length, void *_Nullable user_data);
204
typedef void m_friend_lossless_packet_cb(Messenger *_Nonnull m, uint32_t friend_number, uint8_t packet_id, const uint8_t *_Nonnull data,
205
        size_t length, void *_Nullable user_data);
206
typedef void m_conference_invite_cb(Messenger *_Nonnull m, uint32_t friend_number, const uint8_t *_Nonnull cookie, uint16_t length,
207
                                    void *_Nullable user_data);
208
typedef void m_group_invite_cb(const Messenger *_Nonnull m, uint32_t friend_number, const uint8_t *_Nonnull invite_data, size_t length,
209
                               const uint8_t *_Nullable group_name, size_t group_name_length, void *_Nullable user_data);
210
211
typedef struct Friend {
212
    uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE];
213
    int friendcon_id;
214
215
    uint64_t friendrequest_lastsent; // Time at which the last friend request was sent.
216
    uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts.
217
    uint8_t status; // 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online.
218
    uint8_t info[MAX_FRIEND_REQUEST_DATA_SIZE]; // the data that is sent during the friend requests we do.
219
    uint8_t name[MAX_NAME_LENGTH];
220
    uint16_t name_length;
221
    bool name_sent; // false if we didn't send our name to this friend, true if we have.
222
    uint8_t statusmessage[MAX_STATUSMESSAGE_LENGTH];
223
    uint16_t statusmessage_length;
224
    bool statusmessage_sent;
225
    Userstatus userstatus;
226
    bool userstatus_sent;
227
    bool user_istyping;
228
    bool user_istyping_sent;
229
    bool is_typing;
230
    uint16_t info_size; // Length of the info.
231
    uint32_t message_id; // a semi-unique id used in read receipts.
232
    uint32_t friendrequest_nospam; // The nospam number used in the friend request.
233
    uint64_t last_seen_time;
234
    Connection_Status last_connection_udp_tcp;
235
    struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES];
236
    uint32_t num_sending_files;
237
    struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES];
238
239
    struct Receipts *_Nullable receipts_start;
240
    struct Receipts *_Nullable receipts_end;
241
} Friend;
242
243
struct Messenger {
244
    Logger *_Nullable log;
245
    Mono_Time *_Nullable mono_time;
246
    const Memory *_Nullable mem;
247
    const Random *_Nullable rng;
248
    const Network *_Nullable ns;
249
250
    Networking_Core *_Nonnull net;
251
    Net_Crypto *_Nonnull net_crypto;
252
    Net_Profile *_Nullable tcp_np;
253
    DHT *_Nonnull dht;
254
255
    Forwarding *_Nullable forwarding;
256
    Announcements *_Nullable announce;
257
258
    Onion *_Nullable onion;
259
    Onion_Announce *_Nullable onion_a;
260
    Onion_Client *_Nullable onion_c;
261
262
    Friend_Connections *_Nullable fr_c;
263
264
    TCP_Server *_Nullable tcp_server;
265
    Friend_Requests *_Nullable fr;
266
    uint8_t name[MAX_NAME_LENGTH];
267
    uint16_t name_length;
268
269
    uint8_t statusmessage[MAX_STATUSMESSAGE_LENGTH];
270
    uint16_t statusmessage_length;
271
272
    Userstatus userstatus;
273
274
    Friend *_Nullable friendlist;
275
    uint32_t numfriends;
276
277
    uint64_t lastdump;
278
    uint8_t is_receiving_file;
279
280
    GC_Session *_Nonnull group_handler;
281
    GC_Announces_List *_Nonnull group_announce;
282
283
    bool has_added_relays; // If the first connection has occurred in do_messenger
284
285
    uint16_t num_loaded_relays;
286
    Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config
287
288
    m_friend_request_cb *_Nullable friend_request;
289
    m_friend_message_cb *_Nullable friend_message;
290
    m_friend_name_cb *_Nullable friend_namechange;
291
    m_friend_status_message_cb *_Nullable friend_statusmessagechange;
292
    m_friend_status_cb *_Nullable friend_userstatuschange;
293
    m_friend_typing_cb *_Nullable friend_typingchange;
294
    m_friend_read_receipt_cb *_Nullable read_receipt;
295
    m_friend_connection_status_cb *_Nullable friend_connectionstatuschange;
296
297
    struct Group_Chats *_Nullable conferences_object;
298
    m_conference_invite_cb *_Nullable conference_invite;
299
300
    m_group_invite_cb *_Nullable group_invite;
301
302
    m_file_recv_cb *_Nullable file_sendrequest;
303
    m_file_recv_control_cb *_Nullable file_filecontrol;
304
    m_file_recv_chunk_cb *_Nullable file_filedata;
305
    m_file_chunk_request_cb *_Nullable file_reqchunk;
306
307
    m_friend_lossy_packet_cb *_Nullable lossy_packethandler;
308
    m_friend_lossless_packet_cb *_Nullable lossless_packethandler;
309
310
    m_self_connection_status_cb *_Nullable core_connection_change;
311
    Onion_Connection_Status last_connection_status;
312
313
    Messenger_Options options;
314
};
315
316
/**
317
 * Determines if the friendnumber passed is valid in the Messenger object.
318
 *
319
 * @param friendnumber The index in the friend list.
320
 */
321
bool friend_is_valid(const Messenger *_Nonnull m, int32_t friendnumber);
322
323
/**
324
 * Format: `[real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]`
325
 *
326
 * @param[out] address FRIEND_ADDRESS_SIZE byte address to give to others.
327
 */
328
void getaddress(const Messenger *_Nonnull m, uint8_t *_Nonnull address);
329
330
/**
331
 * Add a friend.
332
 *
333
 * Set the data that will be sent along with friend request.
334
 *
335
 * @param address is the address of the friend (returned by getaddress of the friend
336
 *   you wish to add) it must be FRIEND_ADDRESS_SIZE bytes.
337
 *   TODO(irungentoo): add checksum.
338
 * @param data is the data.
339
 * @param length is the length.
340
 *
341
 * @return the friend number if success.
342
 * @retval FA_TOOLONG if message length is too long.
343
 * @retval FAERR_NOMESSAGE if no message (message length must be >= 1 byte).
344
 * @retval FAERR_OWNKEY if user's own key.
345
 * @retval FAERR_ALREADYSENT if friend request already sent or already a friend.
346
 * @retval FAERR_BADCHECKSUM if bad checksum in address.
347
 * @retval FAERR_SETNEWNOSPAM if the friend was already there but the nospam was different.
348
 *   (the nospam for that friend was set to the new one).
349
 * @retval FAERR_NOMEM if increasing the friend list size fails.
350
 */
351
int32_t m_addfriend(Messenger *_Nonnull m, const uint8_t *_Nonnull address, const uint8_t *_Nonnull data, uint16_t length);
352
353
/** @brief Add a friend without sending a friendrequest.
354
 * @return the friend number if success.
355
 * @retval -3 if user's own key.
356
 * @retval -4 if friend request already sent or already a friend.
357
 * @retval -6 if bad checksum in address.
358
 * @retval -8 if increasing the friend list size fails.
359
 */
360
int32_t m_addfriend_norequest(Messenger *_Nonnull m, const uint8_t *_Nonnull real_pk);
361
362
/** @brief Initializes the friend connection and onion connection for a groupchat.
363
 *
364
 * @retval true on success.
365
 */
366
bool m_create_group_connection(Messenger *_Nonnull m, GC_Chat *_Nonnull chat);
367
368
/*
369
 * Kills the friend connection for a groupchat.
370
 */
371
void m_kill_group_connection(Messenger *_Nonnull m, const GC_Chat *_Nonnull chat);
372
373
/** @return the friend number associated to that public key.
374
 * @retval -1 if no such friend.
375
 */
376
int32_t getfriend_id(const Messenger *_Nonnull m, const uint8_t *_Nonnull real_pk);
377
378
/** @brief Copies the public key associated to that friend id into real_pk buffer.
379
 *
380
 * Make sure that real_pk is of size CRYPTO_PUBLIC_KEY_SIZE.
381
 *
382
 * @retval 0 if success.
383
 * @retval -1 if failure.
384
 */
385
int get_real_pk(const Messenger *_Nonnull m, int32_t friendnumber, uint8_t *_Nonnull real_pk);
386
387
/** @return friend connection id on success.
388
 * @retval -1 if failure.
389
 */
390
int getfriendcon_id(const Messenger *_Nonnull m, int32_t friendnumber);
391
392
/** @brief Remove a friend.
393
 *
394
 * @retval 0 if success.
395
 * @retval -1 if failure.
396
 */
397
int m_delfriend(Messenger *_Nonnull m, int32_t friendnumber);
398
399
/** @brief Checks friend's connection status.
400
 *
401
 * @retval CONNECTION_UDP (2) if friend is directly connected to us (Online UDP).
402
 * @retval CONNECTION_TCP (1) if friend is connected to us (Online TCP).
403
 * @retval CONNECTION_NONE (0) if friend is not connected to us (Offline).
404
 * @retval -1 on failure.
405
 */
406
int m_get_friend_connectionstatus(const Messenger *_Nonnull m, int32_t friendnumber);
407
408
/**
409
 * Checks if there exists a friend with given friendnumber.
410
 *
411
 * @param friendnumber The index in the friend list.
412
 *
413
 * @retval true if friend exists.
414
 * @retval false if friend doesn't exist.
415
 */
416
bool m_friend_exists(const Messenger *_Nonnull m, int32_t friendnumber);
417
418
/** @brief Send a message of type to an online friend.
419
 *
420
 * @retval -1 if friend not valid.
421
 * @retval -2 if too large.
422
 * @retval -3 if friend not online.
423
 * @retval -4 if send failed (because queue is full).
424
 * @retval -5 if bad type.
425
 * @retval 0 if success.
426
 *
427
 * The value in message_id will be passed to your read_receipt callback when the other receives the message.
428
 */
429
int m_send_message_generic(Messenger *_Nonnull m, int32_t friendnumber, uint8_t type, const uint8_t *_Nonnull message, uint32_t length,
430
                           uint32_t *_Nullable message_id);
431
/** @brief Set the name and name_length of a friend.
432
 *
433
 * name must be a string of maximum MAX_NAME_LENGTH length.
434
 * length must be at least 1 byte.
435
 * length is the length of name with the NULL terminator.
436
 *
437
 * @retval 0 if success.
438
 * @retval -1 if failure.
439
 */
440
int setfriendname(Messenger *_Nonnull m, int32_t friendnumber, const uint8_t *_Nonnull name, uint16_t length);
441
442
/** @brief Set our nickname.
443
 *
444
 * name must be a string of maximum MAX_NAME_LENGTH length.
445
 * length must be at least 1 byte.
446
 * length is the length of name with the NULL terminator.
447
 *
448
 * @retval 0 if success.
449
 * @retval -1 if failure.
450
 */
451
int setname(Messenger *_Nonnull m, const uint8_t *_Nonnull name, uint16_t length);
452
453
/**
454
 * @brief Get your nickname.
455
 *
456
 * m - The messenger context to use.
457
 * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
458
 *
459
 * @return length of the name.
460
 * @retval 0 on error.
461
 */
462
uint16_t getself_name(const Messenger *_Nonnull m, uint8_t *_Nonnull name);
463
464
/** @brief Get name of friendnumber and put it in name.
465
 *
466
 * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
467
 *
468
 * @return length of name if success.
469
 * @retval -1 if failure.
470
 */
471
int getname(const Messenger *_Nonnull m, int32_t friendnumber, uint8_t *_Nonnull name);
472
473
/** @return the length of name, including null on success.
474
 * @retval -1 on failure.
475
 */
476
int m_get_name_size(const Messenger *_Nonnull m, int32_t friendnumber);
477
int m_get_self_name_size(const Messenger *_Nonnull m);
478
479
/** @brief Set our user status.
480
 * You are responsible for freeing status after.
481
 *
482
 * @retval 0 if success.
483
 * @retval -1 if failure.
484
 */
485
int m_set_statusmessage(Messenger *_Nonnull m, const uint8_t *_Nonnull status, uint16_t length);
486
int m_set_userstatus(Messenger *_Nonnull m, uint8_t status);
487
488
/**
489
 * Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH.
490
 *
491
 * @return the length of friendnumber's status message, including null on success.
492
 * @retval -1 on failure.
493
 */
494
int m_get_statusmessage_size(const Messenger *_Nonnull m, int32_t friendnumber);
495
int m_get_self_statusmessage_size(const Messenger *_Nonnull m);
496
497
/** @brief Copy friendnumber's status message into buf, truncating if size is over maxlen.
498
 *
499
 * Get the size you need to allocate from m_get_statusmessage_size.
500
 * The self variant will copy our own status message.
501
 *
502
 * @return the length of the copied data on success
503
 * @retval -1 on failure.
504
 */
505
int m_copy_statusmessage(const Messenger *_Nonnull m, int32_t friendnumber, uint8_t *_Nonnull buf, uint32_t maxlen);
506
int m_copy_self_statusmessage(const Messenger *_Nonnull m, uint8_t *_Nonnull buf);
507
508
/** @brief return one of Userstatus values.
509
 *
510
 * Values unknown to your application should be represented as USERSTATUS_NONE.
511
 * As above, the self variant will return our own Userstatus.
512
 * If friendnumber is invalid, this shall return USERSTATUS_INVALID.
513
 */
514
uint8_t m_get_userstatus(const Messenger *_Nonnull m, int32_t friendnumber);
515
uint8_t m_get_self_userstatus(const Messenger *_Nonnull m);
516
517
/** @brief returns timestamp of last time friendnumber was seen online or 0 if never seen.
518
 * if friendnumber is invalid this function will return UINT64_MAX.
519
 */
520
uint64_t m_get_last_online(const Messenger *_Nonnull m, int32_t friendnumber);
521
522
/** @brief Set our typing status for a friend.
523
 * You are responsible for turning it on or off.
524
 *
525
 * @retval 0 on success.
526
 * @retval -1 on failure.
527
 */
528
int m_set_usertyping(Messenger *_Nonnull m, int32_t friendnumber, bool is_typing);
529
530
/** @brief Get the typing status of a friend.
531
 *
532
 * @retval -1 if friend number is invalid.
533
 * @retval 0 if friend is not typing.
534
 * @retval 1 if friend is typing.
535
 */
536
int m_get_istyping(const Messenger *_Nonnull m, int32_t friendnumber);
537
538
/** Set the function that will be executed when a friend request is received. */
539
void m_callback_friendrequest(Messenger *_Nonnull m, m_friend_request_cb *_Nullable function);
540
/** Set the function that will be executed when a message from a friend is received. */
541
void m_callback_friendmessage(Messenger *_Nonnull m, m_friend_message_cb *_Nonnull function);
542
543
/** @brief Set the callback for name changes.
544
 * You are not responsible for freeing newname.
545
 */
546
void m_callback_namechange(Messenger *_Nonnull m, m_friend_name_cb *_Nonnull function);
547
548
/** @brief Set the callback for status message changes.
549
 *
550
 * You are not responsible for freeing newstatus
551
 */
552
void m_callback_statusmessage(Messenger *_Nonnull m, m_friend_status_message_cb *_Nonnull function);
553
554
/** @brief Set the callback for status type changes. */
555
void m_callback_userstatus(Messenger *_Nonnull m, m_friend_status_cb *_Nonnull function);
556
557
/** @brief Set the callback for typing changes. */
558
void m_callback_typingchange(Messenger *_Nonnull m, m_friend_typing_cb *_Nonnull function);
559
560
/** @brief Set the callback for read receipts.
561
 *
562
 * If you are keeping a record of returns from m_sendmessage,
563
 * receipt might be one of those values, meaning the message
564
 * has been received on the other side.
565
 * Since core doesn't track ids for you, receipt may not correspond to any message.
566
 * In that case, you should discard it.
567
 */
568
void m_callback_read_receipt(Messenger *_Nonnull m, m_friend_read_receipt_cb *_Nonnull function);
569
570
/** @brief Set the callback for connection status changes.
571
 *
572
 * Status:
573
 * - 0: friend went offline after being previously online.
574
 * - 1: friend went online.
575
 *
576
 * Note that this callback is not called when adding friends, thus the
577
 * "after being previously online" part.
578
 * It's assumed that when adding friends, their connection status is offline.
579
 */
580
void m_callback_connectionstatus(Messenger *_Nonnull m, m_friend_connection_status_cb *_Nonnull function);
581
582
/** @brief Set the callback for typing changes. */
583
void m_callback_core_connection(Messenger *_Nonnull m, m_self_connection_status_cb *_Nonnull function);
584
585
/*** CONFERENCES */
586
587
/** @brief Set the callback for conference invites. */
588
void m_callback_conference_invite(Messenger *_Nonnull m, m_conference_invite_cb *_Nullable function);
589
/* Set the callback for group invites.
590
 */
591
void m_callback_group_invite(Messenger *_Nonnull m, m_group_invite_cb *_Nullable function);
592
/** @brief Send a conference invite packet.
593
 *
594
 * return true on success
595
 * return false on failure
596
 */
597
bool send_conference_invite_packet(const Messenger *_Nonnull m, int32_t friendnumber, const uint8_t *_Nonnull data, uint16_t length);
598
599
/* Send a group invite packet.
600
 *
601
 *  WARNING: Return-value semantics are different than for
602
 *  send_conference_invite_packet().
603
 *
604
 *  return true on success
605
 */
606
bool send_group_invite_packet(const Messenger *_Nonnull m, uint32_t friendnumber, const uint8_t *_Nonnull packet, uint16_t length);
607
608
/*** FILE SENDING */
609
610
/** @brief Set the callback for file send requests. */
611
void callback_file_sendrequest(Messenger *_Nonnull m, m_file_recv_cb *_Nonnull function);
612
613
/** @brief Set the callback for file control requests. */
614
void callback_file_control(Messenger *_Nonnull m, m_file_recv_control_cb *_Nonnull function);
615
616
/** @brief Set the callback for file data. */
617
void callback_file_data(Messenger *_Nonnull m, m_file_recv_chunk_cb *_Nonnull function);
618
619
/** @brief Set the callback for file request chunk. */
620
void callback_file_reqchunk(Messenger *_Nonnull m, m_file_chunk_request_cb *_Nonnull function);
621
622
/** @brief Copy the file transfer file id to file_id
623
 *
624
 * @retval 0 on success.
625
 * @retval -1 if friend not valid.
626
 * @retval -2 if filenumber not valid
627
 */
628
int file_get_id(const Messenger *_Nonnull m, int32_t friendnumber, uint32_t filenumber, uint8_t *_Nonnull file_id);
629
630
/** @brief Send a file send request.
631
 *
632
 * Maximum filename length is 255 bytes.
633
 *
634
 * @return file number on success
635
 * @retval -1 if friend not found.
636
 * @retval -2 if filename length invalid.
637
 * @retval -3 if no more file sending slots left.
638
 * @retval -4 if could not send packet (friend offline).
639
 */
640
long int new_filesender(const Messenger *_Nonnull m, int32_t friendnumber, uint32_t file_type, uint64_t filesize, const uint8_t *_Nonnull file_id, const uint8_t *_Nonnull filename,
641
                        uint16_t filename_length);
642
643
/** @brief Send a file control request.
644
 *
645
 * @retval 0 on success
646
 * @retval -1 if friend not valid.
647
 * @retval -2 if friend not online.
648
 * @retval -3 if file number invalid.
649
 * @retval -4 if file control is bad.
650
 * @retval -5 if file already paused.
651
 * @retval -6 if resume file failed because it was only paused by the other.
652
 * @retval -7 if resume file failed because it wasn't paused.
653
 * @retval -8 if packet failed to send.
654
 */
655
int file_control(const Messenger *_Nonnull m, int32_t friendnumber, uint32_t filenumber, unsigned int control);
656
657
/** @brief Send a seek file control request.
658
 *
659
 * @retval 0 on success
660
 * @retval -1 if friend not valid.
661
 * @retval -2 if friend not online.
662
 * @retval -3 if file number invalid.
663
 * @retval -4 if not receiving file.
664
 * @retval -5 if file status wrong.
665
 * @retval -6 if position bad.
666
 * @retval -8 if packet failed to send.
667
 */
668
int file_seek(const Messenger *_Nonnull m, int32_t friendnumber, uint32_t filenumber, uint64_t position);
669
670
/** @brief Send file data.
671
 *
672
 * @retval 0 on success
673
 * @retval -1 if friend not valid.
674
 * @retval -2 if friend not online.
675
 * @retval -3 if filenumber invalid.
676
 * @retval -4 if file transfer not transferring.
677
 * @retval -5 if bad data size.
678
 * @retval -6 if packet queue full.
679
 * @retval -7 if wrong position.
680
 */
681
int send_file_data(const Messenger *_Nonnull m, int32_t friendnumber, uint32_t filenumber, uint64_t position,
682
                   const uint8_t *_Nullable data, uint16_t length);
683
/*** CUSTOM PACKETS */
684
685
/** @brief Set handlers for custom lossy packets. */
686
void custom_lossy_packet_registerhandler(Messenger *_Nonnull m, m_friend_lossy_packet_cb *_Nonnull lossy_packethandler);
687
688
/** @brief High level function to send custom lossy packets.
689
 *
690
 * @retval -1 if friend invalid.
691
 * @retval -2 if length wrong.
692
 * @retval -3 if first byte invalid.
693
 * @retval -4 if friend offline.
694
 * @retval -5 if packet failed to send because of other error.
695
 * @retval 0 on success.
696
 */
697
int m_send_custom_lossy_packet(const Messenger *_Nonnull m, int32_t friendnumber, const uint8_t *_Nonnull data, uint32_t length);
698
699
/** @brief Set handlers for custom lossless packets. */
700
void custom_lossless_packet_registerhandler(Messenger *_Nonnull m, m_friend_lossless_packet_cb *_Nonnull lossless_packethandler);
701
702
/** @brief High level function to send custom lossless packets.
703
 *
704
 * @retval -1 if friend invalid.
705
 * @retval -2 if length wrong.
706
 * @retval -3 if first byte invalid.
707
 * @retval -4 if friend offline.
708
 * @retval -5 if packet failed to send because of other error.
709
 * @retval 0 on success.
710
 */
711
int send_custom_lossless_packet(const Messenger *_Nonnull m, int32_t friendnumber, const uint8_t *_Nonnull data, uint32_t length);
712
713
/*** Messenger constructor/destructor/operations. */
714
715
typedef enum Messenger_Error {
716
    MESSENGER_ERROR_NONE,
717
    MESSENGER_ERROR_PORT,
718
    MESSENGER_ERROR_TCP_SERVER,
719
    MESSENGER_ERROR_OTHER,
720
} Messenger_Error;
721
722
/** @brief Run this at startup.
723
 *
724
 * @return allocated instance of Messenger on success.
725
 * @retval 0 if there are problems.
726
 *
727
 * if error is not NULL it will be set to one of the values in the enum above.
728
 */
729
Messenger *_Nullable new_messenger(Mono_Time *_Nonnull mono_time, const Memory *_Nonnull mem, const Random *_Nonnull rng, const Network *_Nonnull ns, Messenger_Options *_Nonnull options,
730
                                   Messenger_Error *_Nonnull error);
731
732
/** @brief Run this before closing shop.
733
 *
734
 * Free all datastructures.
735
 */
736
void kill_messenger(Messenger *_Nullable m);
737
/** @brief The main loop that needs to be run at least 20 times per second. */
738
void do_messenger(Messenger *_Nonnull m, void *_Nullable userdata);
739
/**
740
 * @brief Return the time in milliseconds before `do_messenger()` should be called again
741
 *   for optimal performance.
742
 *
743
 * @return time (in ms) before the next `do_messenger()` needs to be run on success.
744
 */
745
uint32_t messenger_run_interval(const Messenger *_Nonnull m);
746
747
/* SAVING AND LOADING FUNCTIONS: */
748
749
/** @brief Registers a state plugin for saving, loading, and getting the size of a section of the save.
750
 *
751
 * @retval true on success
752
 * @retval false on error
753
 */
754
bool m_register_state_plugin(Messenger *_Nonnull m, State_Type type, m_state_size_cb *_Nonnull size_callback, m_state_load_cb *_Nonnull load_callback, m_state_save_cb *_Nonnull save_callback);
755
756
/** return size of the messenger data (for saving). */
757
uint32_t messenger_size(const Messenger *_Nonnull m);
758
759
/** Save the messenger in data (must be allocated memory of size at least `Messenger_size()`) */
760
uint8_t *_Nonnull messenger_save(const Messenger *_Nonnull m, uint8_t *_Nonnull data);
761
762
/** @brief Load a state section.
763
 *
764
 * @param data Data to load.
765
 * @param length Length of data.
766
 * @param type Type of section (`STATE_TYPE_*`).
767
 * @param status Result of loading section is stored here if the section is handled.
768
 * @return true iff section handled.
769
 */
770
bool messenger_load_state_section(Messenger *_Nonnull m, const uint8_t *_Nonnull data, uint32_t length, uint16_t type, State_Load_Status *_Nonnull status);
771
772
/** @brief Return the number of friends in the instance m.
773
 *
774
 * You should use this to determine how much memory to allocate
775
 * for copy_friendlist.
776
 */
777
uint32_t count_friendlist(const Messenger *_Nonnull m);
778
779
/** @brief Copy a list of valid friend IDs into the array out_list.
780
 * If out_list is NULL, returns 0.
781
 * Otherwise, returns the number of elements copied.
782
 * If the array was too small, the contents
783
 * of out_list will be truncated to list_size.
784
 */
785
uint32_t copy_friendlist(const Messenger *_Nonnull m, uint32_t *_Nonnull out_list, uint32_t list_size);
786
787
bool m_is_receiving_file(Messenger *_Nonnull m);
788
789
#endif /* C_TOXCORE_TOXCORE_MESSENGER_H */