diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index e6e8d59f..246ae818 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -31,6 +31,7 @@ #endif #include "../toxcore/DHT.h" +#include "../toxcore/LAN_discovery.h" #include "../toxcore/friend_requests.h" #include "../testing/misc_tools.c" @@ -140,6 +141,9 @@ int main(int argc, char *argv[]) int is_waiting_for_dht_connection = 1; + uint64_t last_LANdiscovery = 0; + LANdiscovery_init(dht); + while (1) { if (is_waiting_for_dht_connection && DHT_isconnected(dht)) { printf("Connected to other bootstrap server successfully.\n"); @@ -147,6 +151,10 @@ int main(int argc, char *argv[]) } do_DHT(dht); + if (last_LANdiscovery + (is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL) < unix_time()) { + send_LANdiscovery(htons(PORT), dht->c); + last_LANdiscovery = unix_time(); + } networking_poll(dht->c->lossless_udp->net); diff --git a/testing/nTox.c b/testing/nTox.c index 1e83f507..70dc5c77 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -348,13 +348,34 @@ void line_eval(Tox *m, char *line) do_refresh(); } else if (inpt_command == 'h') { //help new_lines(help); - } else if (inpt_command == 'i') { //info + } else if (inpt_command == 'x') { //info char idstring[200]; get_id(m, idstring); new_lines(idstring); - } + } else if (inpt_command == 'g') { //create new group chat + char msg[256]; + sprintf(msg, "[g] Created new group chat with number: %u", tox_add_groupchat(m)); + new_lines(msg); + } else if (inpt_command == 'i') { //invite friendnum to groupnum + char *posi[1]; + int friendnumber = strtoul(line + prompt_offset, posi, 0); + int groupnumber = strtoul(*posi + 1, NULL, 0); + char msg[256]; + sprintf(msg, "[g] Invited friend number %u to group number %u, returned: %u (0 means success)", friendnumber, + groupnumber, tox_invite_friend(m, friendnumber, groupnumber)); + new_lines(msg); + } else if (inpt_command == 'z') { //send message to groupnum + char *posi[1]; + int groupnumber = strtoul(line + prompt_offset, posi, 0); - else if (inpt_command == 'q') { //exit + if (**posi != 0) { + char msg[256 + 1024]; + sprintf(msg, "[g] sent message: %s to group num: %u returned: %u (0 means success)", *posi + 1, groupnumber, + tox_group_message_send(m, groupnumber, (uint8_t *)*posi + 1, strlen(*posi + 1) + 1)); + new_lines(msg); + } + + } else if (inpt_command == 'q') { //exit endwin(); exit(EXIT_SUCCESS); } else { @@ -535,6 +556,22 @@ void print_help(void) puts("\t-f\t-\tSpecify a keyfile to read (or write to) from."); } +void print_invite(Tox *m, int friendnumber, uint8_t *group_public_key, void *userdata) +{ + char msg[256]; + sprintf(msg, "[i] recieved group chat invite from: %u, auto accepting and joining. group number: %u", friendnumber, + tox_join_groupchat(m, friendnumber, group_public_key)); + new_lines(msg); +} + +void print_groupmessage(Tox *m, int groupnumber, uint8_t *message, uint16_t length, void *userdata) +{ + char msg[256 + length]; + sprintf(msg, "[g] %u: %s", groupnumber, message); + new_lines(msg); +} + + int main(int argc, char *argv[]) { if (argc < 4) { @@ -579,6 +616,8 @@ int main(int argc, char *argv[]) tox_callback_friendmessage(m, print_message, NULL); tox_callback_namechange(m, print_nickchange, NULL); tox_callback_statusmessage(m, print_statuschange, NULL); + tox_callback_group_invite(m, print_invite, NULL); + tox_callback_group_message(m, print_groupmessage, NULL); initscr(); noecho(); diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h index a0789956..3e9d9de5 100644 --- a/toxcore/LAN_discovery.h +++ b/toxcore/LAN_discovery.h @@ -35,7 +35,7 @@ #include #endif -/* standard interval in seconds between LAN discovery packet sending. */ +/* Interval in seconds between LAN discovery packet sending. */ #define LAN_DISCOVERY_INTERVAL 60 /* Send a LAN discovery pcaket to the broadcast address with port port. */ diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index d228fcc2..8d0b149f 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -674,6 +674,40 @@ static int group_num(Messenger *m, uint8_t *group_public_key) return -1; } +/* Set the callback for group invites. + * + * Function(Messenger *m, int friendnumber, uint8_t *group_public_key, void *userdata) + */ +void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, void *), void *userdata) +{ + m->group_invite = function; + m->group_invite_userdata = userdata; +} + +/* Set the callback for group messages. + * + * Function(Messenger *m, int groupnumber, uint8_t * message, uint16_t length, void *userdata) + */ +void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *), + void *userdata) +{ + m->group_message = function; + m->group_message_userdata = userdata; +} +static void group_message_function(Group_Chat *chat, int peer_number, uint8_t *message, uint16_t length, void *userdata) +{ + Messenger *m = userdata; + uint32_t i; + + for (i = 0; i < m->numchats; ++i) { //TODO: remove this + if (m->chats[i] == chat) + break; + } + + if (m->group_message) + (*m->group_message)(m, i, message, length, m->group_invite_userdata); +} + /* Creates a new groupchat and puts it in the chats array. * * return group number on success. @@ -690,6 +724,7 @@ int add_groupchat(Messenger *m) if (newchat == NULL) return -1; + callback_groupmessage(newchat, &group_message_function, m); m->chats[i] = newchat; return i; } @@ -706,6 +741,8 @@ int add_groupchat(Messenger *m) if (temp[m->numchats] == NULL) return -1; + m->chats = temp; + callback_groupmessage(temp[m->numchats], &group_message_function, m); ++m->numchats; return (m->numchats - 1); } @@ -715,7 +752,7 @@ int add_groupchat(Messenger *m) * return 0 on success. * return -1 if failure. */ -static int del_groupchat(Messenger *m, int groupnumber) +int del_groupchat(Messenger *m, int groupnumber) { if ((unsigned int)groupnumber >= m->numchats) return -1; @@ -749,9 +786,42 @@ static int del_groupchat(Messenger *m, int groupnumber) return 0; } +/* return 1 if that friend was invited to the group + * return 0 if the friend was not or error. + */ +static uint8_t group_invited(Messenger *m, int friendnumber, int groupnumber) +{ + //TODO: this function; + return 1; +} + +/* invite friendnumber to groupnumber + * return 0 on success + * return -1 on failure + */ +int invite_friend(Messenger *m, int friendnumber, int groupnumber) +{ + if (friend_not_valid(m, friendnumber) || (unsigned int)groupnumber >= m->numchats) + return -1; + + if (m->chats == NULL) + return -1; + + if (m->friendlist[friendnumber].status == NOFRIEND || m->chats[groupnumber] == NULL) + return -1; + + //TODO: store invited friends. + if (write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_GROUPCHAT, m->chats[groupnumber]->self_public_key, + crypto_box_PUBLICKEYBYTES) == 0) + return -1; + + return 0; +} + + /* Join a group (you need to have been invited first.) * - * returns 0 on success + * returns group number on success * returns -1 on failure. */ int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_key) @@ -771,12 +841,34 @@ int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_ if (write_cryptpacket_id(m, friendnumber, PACKET_ID_JOIN_GROUPCHAT, data, sizeof(data))) { chat_bootstrap_nonlazy(m->chats[groupnum], get_friend_ipport(m, friendnumber), friend_group_public_key); //TODO: check if ip returned is zero? - return 0; + return groupnum; } return -1; } +/* send a group message + * return 0 on success + * return -1 on failure + */ + +int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length) +{ + if ((unsigned int)groupnumber >= m->numchats) + return -1; + + if (m->chats == NULL) + return -1; + + if (m->chats[groupnumber] == NULL) + return -1; + + if (group_sendmessage(m->chats[groupnumber], message, length) > 0) + return 0; + + return -1; +} + static int handle_group(void *object, IP_Port source, uint8_t *packet, uint32_t length) { Messenger *m = object; @@ -810,9 +902,6 @@ static void do_allgroupchats(Messenger *m) /*********************************/ -/* Interval in seconds between LAN discovery packet sending. */ -#define LAN_DISCOVERY_INTERVAL 60 - /* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */ static void LANdiscovery(Messenger *m) { @@ -1065,6 +1154,29 @@ void doFriends(Messenger *m) break; } + + case PACKET_ID_INVITE_GROUPCHAT: { + if (data_length != crypto_box_PUBLICKEYBYTES) + break; + + if (m->group_invite) + (*m->group_invite)(m, i, data, m->group_invite_userdata); + } + + case PACKET_ID_JOIN_GROUPCHAT: { + if (data_length != crypto_box_PUBLICKEYBYTES * 2) + break; + + int groupnum = group_num(m, data); + + if (groupnum == -1) + break; + + if (!group_invited(m, i, groupnum)) + break; + + group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES); + } } } else { if (is_cryptoconnected(m->net_crypto, diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index b7032bbd..bfcc69df 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -157,7 +157,10 @@ typedef struct Messenger { void *friend_statuschange_userdata; void (*friend_connectionstatuschange)(struct Messenger *m, int, uint8_t, void *); void *friend_connectionstatuschange_userdata; - + void (*group_invite)(struct Messenger *m, int, uint8_t *, void *); + void *group_invite_userdata; + void (*group_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *); + void *group_message_userdata; } Messenger; @@ -369,6 +372,57 @@ void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, u */ void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void *), void *userdata); +/**********GROUP CHATS************/ + +/* Set the callback for group invites. + * + * Function(Messenger *m, int friendnumber, uint8_t *group_public_key, void *userdata) + */ +void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, void *), void *userdata); + +/* Set the callback for group messages. + * + * Function(Messenger *m, int groupnumber, uint8_t * message, uint16_t length, void *userdata) + */ +void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *), + void *userdata); + +/* Creates a new groupchat and puts it in the chats array. + * + * return group number on success. + * return -1 on failure. + */ +int add_groupchat(Messenger *m); + +/* Delete a groupchat from the chats array. + * + * return 0 on success. + * return -1 if failure. + */ +int del_groupchat(Messenger *m, int groupnumber); + +/* invite friendnumber to groupnumber + * return 0 on success + * return -1 on failure + */ +int invite_friend(Messenger *m, int friendnumber, int groupnumber); + +/* Join a group (you need to have been invited first.) + * + * returns group number on success + * returns -1 on failure. + */ +int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_key); + +/* send a group message + * return 0 on success + * return -1 on failure + */ + +int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length); + +/*********************************/ + /* Run this at startup. * return allocated instance of Messenger on success. * return 0 if there are problems. diff --git a/toxcore/group_chats.h b/toxcore/group_chats.h index 535b46db..78a5488c 100644 --- a/toxcore/group_chats.h +++ b/toxcore/group_chats.h @@ -77,6 +77,7 @@ void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat, /* * Send a message to the group. * + * returns the number of peers it has sent it to. */ uint32_t group_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length); diff --git a/toxcore/tox.c b/toxcore/tox.c index 3eb80d22..68b1e6e9 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -366,6 +366,81 @@ void tox_callback_connectionstatus(void *tox, void (*function)(Messenger *tox, i m_callback_connectionstatus(m, function, userdata); } +/**********GROUP CHAT FUNCTIONS: WARNING WILL BREAK A LOT************/ + +/* Set the callback for group invites. + * + * Function(Tox *tox, int friendnumber, uint8_t *group_public_key, void *userdata) + */ +void tox_callback_group_invite(void *tox, void (*function)(Messenger *tox, int, uint8_t *, void *), void *userdata) +{ + Messenger *m = tox; + m_callback_group_invite(m, function, userdata); +} +/* Set the callback for group messages. + * + * Function(Tox *tox, int groupnumber, uint8_t * message, uint16_t length, void *userdata) + */ +void tox_callback_group_message(void *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *), + void *userdata) +{ + Messenger *m = tox; + m_callback_group_message(m, function, userdata); +} +/* Creates a new groupchat and puts it in the chats array. + * + * return group number on success. + * return -1 on failure. + */ +int tox_add_groupchat(void *tox) +{ + Messenger *m = tox; + return add_groupchat(m); +} +/* Delete a groupchat from the chats array. + * + * return 0 on success. + * return -1 if failure. + */ +int tox_del_groupchat(void *tox, int groupnumber) +{ + Messenger *m = tox; + return del_groupchat(m, groupnumber); +} +/* invite friendnumber to groupnumber + * return 0 on success + * return -1 on failure + */ +int tox_invite_friend(void *tox, int friendnumber, int groupnumber) +{ + Messenger *m = tox; + return invite_friend(m, friendnumber, groupnumber); +} +/* Join a group (you need to have been invited first.) + * + * returns group number on success + * returns -1 on failure. + */ +int tox_join_groupchat(void *tox, int friendnumber, uint8_t *friend_group_public_key) +{ + Messenger *m = tox; + return join_groupchat(m, friendnumber, friend_group_public_key); +} + +/* send a group message + * return 0 on success + * return -1 on failure + */ +int tox_group_message_send(void *tox, int groupnumber, uint8_t *message, uint32_t length) +{ + Messenger *m = tox; + return group_message_send(m, groupnumber, message, length); +} + + + +/******************END OF GROUP CHAT FUNCTIONS************************/ + /* Use these functions to bootstrap the client. * Sends a get nodes request to the given node with ip port and public_key. */ diff --git a/toxcore/tox.h b/toxcore/tox.h index 4c597250..c52a644f 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -342,6 +342,59 @@ void tox_callback_read_receipt(Tox *tox, void (*function)(Tox *tox, int, uint32_ */ void tox_callback_connectionstatus(Tox *tox, void (*function)(Tox *tox, int, uint8_t, void *), void *userdata); +/**********GROUP CHAT FUNCTIONS: WARNING WILL BREAK A LOT************/ + +/* Set the callback for group invites. + * + * Function(Tox *tox, int friendnumber, uint8_t *group_public_key, void *userdata) + */ +void tox_callback_group_invite(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, void *), void *userdata); + +/* Set the callback for group messages. + * + * Function(Tox *tox, int groupnumber, uint8_t * message, uint16_t length, void *userdata) + */ +void tox_callback_group_message(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, uint16_t, void *), + void *userdata); + +/* Creates a new groupchat and puts it in the chats array. + * + * return group number on success. + * return -1 on failure. + */ +int tox_add_groupchat(Tox *tox); + +/* Delete a groupchat from the chats array. + * + * return 0 on success. + * return -1 if failure. + */ +int tox_del_groupchat(Tox *tox, int groupnumber); + +/* invite friendnumber to groupnumber + * return 0 on success + * return -1 on failure + */ +int tox_invite_friend(Tox *tox, int friendnumber, int groupnumber); + +/* Join a group (you need to have been invited first.) + * + * returns group number on success + * returns -1 on failure. + */ +int tox_join_groupchat(Tox *tox, int friendnumber, uint8_t *friend_group_public_key); + + +/* send a group message + * return 0 on success + * return -1 on failure + */ +int tox_group_message_send(Tox *tox, int groupnumber, uint8_t *message, uint32_t length); + + + +/******************END OF GROUP CHAT FUNCTIONS************************/ + /* * Use these two functions to bootstrap the client. */