Coverage Report

Created: 2026-10-24 08:16

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