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