summaryrefslogtreecommitdiff
path: root/toxcore/Messenger.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r--toxcore/Messenger.c158
1 files changed, 153 insertions, 5 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index c1301767..692d3d0e 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -43,6 +43,71 @@ static uint8_t friend_not_valid(Messenger *m, int friendnumber)
43 return (unsigned int)friendnumber >= m->numfriends; 43 return (unsigned int)friendnumber >= m->numfriends;
44} 44}
45 45
46static int add_online_friend(Messenger *m, int friendnumber)
47{
48 if (friend_not_valid(m, friendnumber))
49 return -1;
50
51 IP_Port temp_ip_port = get_friend_ipport(m, friendnumber);
52
53 if (temp_ip_port.port == 0)
54 return -1;
55
56 uint32_t i;
57
58 for (i = 0; i < m->numonline_friends; ++i) {
59 if (m->online_friendlist[i].friend_num == (uint32_t)friendnumber)
60 return 0;
61 }
62
63 Online_Friend *temp;
64 temp = realloc(m->online_friendlist, sizeof(Online_Friend) * (m->numonline_friends + 1));
65
66 if (temp == NULL)
67 return -1;
68
69 m->online_friendlist = temp;
70 m->online_friendlist[m->numonline_friends].friend_num = friendnumber;
71 m->online_friendlist[m->numonline_friends].ip_port = temp_ip_port;
72 ++m->numonline_friends;
73 return 0;
74}
75
76
77static int remove_online_friend(Messenger *m, int friendnumber)
78{
79 uint32_t i;
80 Online_Friend *temp;
81
82 for (i = 0; i < m->numonline_friends; ++i) {
83 /* Equal */
84 if (m->online_friendlist[i].friend_num == (uint32_t)friendnumber) {
85 --m->numonline_friends;
86
87 if (m->numonline_friends != i) {
88 memcpy( &m->online_friendlist[i],
89 &m->online_friendlist[m->numonline_friends],
90 sizeof(Online_Friend) );
91 }
92
93 if (m->numonline_friends == 0) {
94 free(m->online_friendlist);
95 m->online_friendlist = NULL;
96 return 0;
97 }
98
99 temp = realloc(m->online_friendlist, sizeof(Online_Friend) * (m->numonline_friends));
100
101 if (temp == NULL)
102 return -1;
103
104 m->online_friendlist = temp;
105 return 0;
106 }
107 }
108
109 return -1;
110}
46/* Set the size of the friend list to numfriends. 111/* Set the size of the friend list to numfriends.
47 * 112 *
48 * return -1 if realloc fails. 113 * return -1 if realloc fails.
@@ -273,6 +338,9 @@ int m_delfriend(Messenger *m, int friendnumber)
273 if (friend_not_valid(m, friendnumber)) 338 if (friend_not_valid(m, friendnumber))
274 return -1; 339 return -1;
275 340
341 if (m->friendlist[friendnumber].status == FRIEND_ONLINE)
342 remove_online_friend(m, friendnumber);
343
276 onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum); 344 onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum);
277 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); 345 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
278 free(m->friendlist[friendnumber].statusmessage); 346 free(m->friendlist[friendnumber].statusmessage);
@@ -650,12 +718,17 @@ void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, in
650 m->friend_connectionstatuschange = function; 718 m->friend_connectionstatuschange = function;
651 m->friend_connectionstatuschange_userdata = userdata; 719 m->friend_connectionstatuschange_userdata = userdata;
652} 720}
721
722void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void *),
723 void *userdata)
724{
725 m->friend_connectionstatuschange_internal = function;
726 m->friend_connectionstatuschange_internal_userdata = userdata;
727}
728
653static void break_files(Messenger *m, int friendnumber); 729static void break_files(Messenger *m, int friendnumber);
654static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_t status) 730static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_t status)
655{ 731{
656 if (!m->friend_connectionstatuschange)
657 return;
658
659 if (status == NOFRIEND) 732 if (status == NOFRIEND)
660 return; 733 return;
661 734
@@ -665,10 +738,19 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_
665 onion_set_friend_online(m->onion_c, m->friendlist[friendnumber].onion_friendnum, is_online); 738 onion_set_friend_online(m->onion_c, m->friendlist[friendnumber].onion_friendnum, is_online);
666 739
667 if (is_online != was_online) { 740 if (is_online != was_online) {
668 if (was_online) 741 if (was_online) {
669 break_files(m, friendnumber); 742 break_files(m, friendnumber);
743 remove_online_friend(m, friendnumber);
744 } else {
745 add_online_friend(m, friendnumber);
746 }
747
748 if (m->friend_connectionstatuschange)
749 m->friend_connectionstatuschange(m, friendnumber, is_online, m->friend_connectionstatuschange_userdata);
670 750
671 m->friend_connectionstatuschange(m, friendnumber, is_online, m->friend_connectionstatuschange_userdata); 751 if (m->friend_connectionstatuschange_internal)
752 m->friend_connectionstatuschange_internal(m, friendnumber, is_online,
753 m->friend_connectionstatuschange_internal_userdata);
672 } 754 }
673} 755}
674 756
@@ -814,6 +896,8 @@ static void group_message_function(Group_Chat *chat, int peer_number, uint8_t *m
814 if (i == -1) 896 if (i == -1)
815 return; 897 return;
816 898
899 message[length - 1] = 0; /* Force NULL terminator */
900
817 if (m->group_message) 901 if (m->group_message)
818 (*m->group_message)(m, i, peer_number, message, length, m->group_message_userdata); 902 (*m->group_message)(m, i, peer_number, message, length, m->group_message_userdata);
819} 903}
@@ -826,6 +910,8 @@ static void group_action_function(Group_Chat *chat, int peer_number, uint8_t *ac
826 if (i == -1) 910 if (i == -1)
827 return; 911 return;
828 912
913 action[length - 1] = 0; /* Force NULL terminator */
914
829 if (m->group_action) 915 if (m->group_action)
830 (*m->group_action)(m, i, peer_number, action, length, m->group_action_userdata); 916 (*m->group_action)(m, i, peer_number, action, length, m->group_action_userdata);
831} 917}
@@ -1489,6 +1575,60 @@ int m_msi_packet(Messenger *m, int friendnumber, uint8_t *data, uint16_t length)
1489 return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length); 1575 return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length);
1490} 1576}
1491 1577
1578static int friendnum_from_ip_port(Messenger *m, IP_Port ip_port)
1579{
1580 uint32_t i;
1581
1582 for (i = 0; i < m->numonline_friends; ++i) {
1583 if (ipport_equal(&m->online_friendlist[i].ip_port, &ip_port))
1584 return m->online_friendlist[i].friend_num;
1585 }
1586
1587 return -1;
1588}
1589
1590static int handle_custom_user_packet(void *object, IP_Port source, uint8_t *packet, uint32_t length)
1591{
1592 Messenger *m = object;
1593 int friend_num = friendnum_from_ip_port(m, source);
1594
1595 if (friend_num == -1)
1596 return 1;
1597
1598 if (m->friendlist[friend_num].packethandlers[packet[0] % TOTAL_USERPACKETS].function)
1599 return m->friendlist[friend_num].packethandlers[packet[0] % TOTAL_USERPACKETS].function(
1600 m->friendlist[friend_num].packethandlers[packet[0] % TOTAL_USERPACKETS].object, source, packet, length);
1601
1602 return 1;
1603}
1604
1605
1606int custom_user_packet_registerhandler(Messenger *m, int friendnumber, uint8_t byte, packet_handler_callback cb,
1607 void *object)
1608{
1609 if (friend_not_valid(m, friendnumber))
1610 return -1;
1611
1612 if (byte < NET_PACKET_CUSTOM_RANGE_START || byte >= NET_PACKET_CUSTOM_RANGE_END)
1613 return -1;
1614
1615 m->friendlist[friendnumber].packethandlers[byte % TOTAL_USERPACKETS].function = cb;
1616 m->friendlist[friendnumber].packethandlers[byte % TOTAL_USERPACKETS].object = object;
1617 networking_registerhandler(m->net, byte, handle_custom_user_packet, m);
1618 return 0;
1619}
1620
1621int send_custom_user_packet(Messenger *m, int friendnumber, uint8_t *data, uint32_t length)
1622{
1623 IP_Port ip_port = get_friend_ipport(m, friendnumber);
1624
1625 if (ip_port.port == 0)
1626 return -1;
1627
1628 return sendpacket(m->net, ip_port, data, length);
1629}
1630
1631
1492/* Function to filter out some friend requests*/ 1632/* Function to filter out some friend requests*/
1493static int friend_already_added(uint8_t *client_id, void *data) 1633static int friend_already_added(uint8_t *client_id, void *data)
1494{ 1634{
@@ -1841,6 +1981,8 @@ void do_friends(Messenger *m)
1841 m->friendlist[i].file_receiving[filenumber].size = filesize; 1981 m->friendlist[i].file_receiving[filenumber].size = filesize;
1842 m->friendlist[i].file_receiving[filenumber].transferred = 0; 1982 m->friendlist[i].file_receiving[filenumber].transferred = 0;
1843 1983
1984 data[data_length - 1] = 0; /* Force NULL terminate file name. */
1985
1844 if (m->file_sendrequest) 1986 if (m->file_sendrequest)
1845 (*m->file_sendrequest)(m, i, filenumber, filesize, data + 1 + sizeof(uint64_t), data_length - 1 - sizeof(uint64_t), 1987 (*m->file_sendrequest)(m, i, filenumber, filesize, data + 1 + sizeof(uint64_t), data_length - 1 - sizeof(uint64_t),
1846 m->file_sendrequest_userdata); 1988 m->file_sendrequest_userdata);
@@ -2360,6 +2502,12 @@ uint32_t count_friendlist(Messenger *m)
2360 return ret; 2502 return ret;
2361} 2503}
2362 2504
2505/* Return the number of online friends in the instance m. */
2506uint32_t get_num_online_friends(Messenger *m)
2507{
2508 return m->numonline_friends;
2509}
2510
2363/* Copy a list of valid friend IDs into the array out_list. 2511/* Copy a list of valid friend IDs into the array out_list.
2364 * If out_list is NULL, returns 0. 2512 * If out_list is NULL, returns 0.
2365 * Otherwise, returns the number of elements copied. 2513 * Otherwise, returns the number of elements copied.