diff options
-rw-r--r-- | testing/nTox.c | 4 | ||||
-rw-r--r-- | toxcore/group.c | 304 | ||||
-rw-r--r-- | toxcore/group.h | 25 | ||||
-rw-r--r-- | toxcore/tox.c | 48 | ||||
-rw-r--r-- | toxcore/tox.h | 16 |
5 files changed, 348 insertions, 49 deletions
diff --git a/testing/nTox.c b/testing/nTox.c index edda43b1..b33b1fd3 100644 --- a/testing/nTox.c +++ b/testing/nTox.c | |||
@@ -1001,11 +1001,11 @@ void print_help(char *prog_name) | |||
1001 | puts(" -f keyfile [Optional] Specify a keyfile to read from and write to."); | 1001 | puts(" -f keyfile [Optional] Specify a keyfile to read from and write to."); |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | void print_invite(Tox *m, int friendnumber, const uint8_t *group_public_key, void *userdata) | 1004 | void print_invite(Tox *m, int friendnumber, const uint8_t *data, uint16_t length, void *userdata) |
1005 | { | 1005 | { |
1006 | char msg[256]; | 1006 | char msg[256]; |
1007 | sprintf(msg, "[i] received group chat invite from: %u, auto accepting and joining. group number: %u", friendnumber, | 1007 | sprintf(msg, "[i] received group chat invite from: %u, auto accepting and joining. group number: %u", friendnumber, |
1008 | tox_join_groupchat(m, friendnumber, group_public_key)); | 1008 | tox_join_groupchat(m, friendnumber, data, length)); |
1009 | new_lines(msg); | 1009 | new_lines(msg); |
1010 | } | 1010 | } |
1011 | 1011 | ||
diff --git a/toxcore/group.c b/toxcore/group.c index d3652e17..602c9124 100644 --- a/toxcore/group.c +++ b/toxcore/group.c | |||
@@ -220,7 +220,7 @@ static int wipe_group_chat(Group_Chats *g_c, int groupnumber) | |||
220 | return 0; | 220 | return 0; |
221 | } | 221 | } |
222 | 222 | ||
223 | static Group_c *get_group_c(Group_Chats *g_c, int groupnumber) | 223 | static Group_c *get_group_c(const Group_Chats *g_c, int groupnumber) |
224 | { | 224 | { |
225 | if (groupnumber_not_valid(g_c, groupnumber)) | 225 | if (groupnumber_not_valid(g_c, groupnumber)) |
226 | return 0; | 226 | return 0; |
@@ -231,7 +231,7 @@ static Group_c *get_group_c(Group_Chats *g_c, int groupnumber) | |||
231 | /* | 231 | /* |
232 | * check if peer with client_id is in peer array. | 232 | * check if peer with client_id is in peer array. |
233 | * | 233 | * |
234 | * return peer number if peer is in chat. | 234 | * return peer index if peer is in chat. |
235 | * return -1 if peer is not in chat. | 235 | * return -1 if peer is not in chat. |
236 | * | 236 | * |
237 | * TODO: make this more efficient. | 237 | * TODO: make this more efficient. |
@@ -268,17 +268,37 @@ static int get_group_num(const Group_Chats *g_c, const uint8_t *identifier) | |||
268 | } | 268 | } |
269 | 269 | ||
270 | /* | 270 | /* |
271 | * check if peer with peer_number is in peer array. | ||
272 | * | ||
273 | * return peer number if peer is in chat. | ||
274 | * return -1 if peer is not in chat. | ||
275 | * | ||
276 | * TODO: make this more efficient. | ||
277 | */ | ||
278 | int get_peer_index(Group_c *g, uint16_t peer_number) | ||
279 | { | ||
280 | uint32_t i; | ||
281 | |||
282 | for (i = 0; i < g->numpeers; ++i) | ||
283 | if (g->group[i].peer_number == peer_number) | ||
284 | return i; | ||
285 | |||
286 | return -1; | ||
287 | } | ||
288 | |||
289 | /* | ||
271 | * Add a peer to the group chat. | 290 | * Add a peer to the group chat. |
272 | * | 291 | * |
273 | * return peernum if success or peer already in chat. | 292 | * return peer_index if success or peer already in chat. |
274 | * return -1 if error. | 293 | * return -1 if error. |
275 | */ | 294 | */ |
276 | static int addpeer(Group_c *chat, const uint8_t *client_id) | 295 | static int addpeer(Group_c *chat, const uint8_t *client_id, uint16_t peer_number) |
277 | { | 296 | { |
278 | int peernum = peer_in_chat(chat, client_id); | 297 | //TODO |
298 | //int peer_index = peer_in_chat(chat, client_id); | ||
279 | 299 | ||
280 | if (peernum != -1) | 300 | //if (peer_index != -1) |
281 | return peernum; | 301 | // return peer_index; |
282 | 302 | ||
283 | Group_Peer *temp; | 303 | Group_Peer *temp; |
284 | temp = realloc(chat->group, sizeof(Group_Peer) * (chat->numpeers + 1)); | 304 | temp = realloc(chat->group, sizeof(Group_Peer) * (chat->numpeers + 1)); |
@@ -290,6 +310,8 @@ static int addpeer(Group_c *chat, const uint8_t *client_id) | |||
290 | chat->group = temp; | 310 | chat->group = temp; |
291 | 311 | ||
292 | id_copy(chat->group[chat->numpeers].client_id, client_id); | 312 | id_copy(chat->group[chat->numpeers].client_id, client_id); |
313 | chat->group[chat->numpeers].peer_number = peer_number; | ||
314 | |||
293 | chat->group[chat->numpeers].last_recv = unix_time(); | 315 | chat->group[chat->numpeers].last_recv = unix_time(); |
294 | chat->group[chat->numpeers].last_recv_msgping = unix_time(); | 316 | chat->group[chat->numpeers].last_recv_msgping = unix_time(); |
295 | ++chat->numpeers; | 317 | ++chat->numpeers; |
@@ -300,6 +322,39 @@ static int addpeer(Group_c *chat, const uint8_t *client_id) | |||
300 | return (chat->numpeers - 1); | 322 | return (chat->numpeers - 1); |
301 | } | 323 | } |
302 | 324 | ||
325 | /* Add friend to group chat. | ||
326 | * | ||
327 | * return 0 on success | ||
328 | * return -1 on failure. | ||
329 | */ | ||
330 | static int add_friend_to_groupchat(Group_Chats *g_c, int32_t friendnumber, int groupnumber, uint16_t other_groupnum) | ||
331 | { | ||
332 | if (!m_friend_exists(g_c->m, friendnumber)) | ||
333 | return -1; | ||
334 | |||
335 | Group_c *g = get_group_c(g_c, groupnumber); | ||
336 | |||
337 | if (!g) | ||
338 | return -1; | ||
339 | |||
340 | uint16_t i; | ||
341 | |||
342 | for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { | ||
343 | if (g->close[i].type != GROUPCHAT_CLOSE_NONE) | ||
344 | continue; | ||
345 | |||
346 | break; | ||
347 | } | ||
348 | |||
349 | if (i == MAX_GROUP_CONNECTIONS) | ||
350 | return -1; | ||
351 | |||
352 | g->close[i].type = GROUPCHAT_CLOSE_FRIEND; | ||
353 | g->close[i].number = friendnumber; | ||
354 | g->close[i].group_number = other_groupnum; | ||
355 | |||
356 | return 0; | ||
357 | } | ||
303 | 358 | ||
304 | /* Creates a new groupchat and puts it in the chats array. | 359 | /* Creates a new groupchat and puts it in the chats array. |
305 | * | 360 | * |
@@ -310,13 +365,14 @@ int add_groupchat(Group_Chats *g_c) | |||
310 | { | 365 | { |
311 | int groupnumber = create_group_chat(g_c); | 366 | int groupnumber = create_group_chat(g_c); |
312 | 367 | ||
313 | Group_c *g = get_group_c(g_c, groupnumber); | 368 | if (groupnumber == -1) |
314 | |||
315 | if (!g) | ||
316 | return -1; | 369 | return -1; |
317 | 370 | ||
371 | Group_c *g = &g_c->chats[groupnumber]; | ||
372 | |||
318 | g->status = GROUPCHAT_STATUS_VALID; | 373 | g->status = GROUPCHAT_STATUS_VALID; |
319 | new_symmetric_key(g->identifier); | 374 | new_symmetric_key(g->identifier); |
375 | g->peer_number = 0; /* Founder is peer 0. */ | ||
320 | return groupnumber; | 376 | return groupnumber; |
321 | } | 377 | } |
322 | 378 | ||
@@ -356,18 +412,18 @@ int invite_friend(Group_Chats *g_c, int32_t friendnumber, int groupnumber) | |||
356 | * returns group number on success | 412 | * returns group number on success |
357 | * returns -1 on failure. | 413 | * returns -1 on failure. |
358 | */ | 414 | */ |
359 | int join_groupchat(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length) | 415 | int join_groupchat(Group_Chats *g_c, int32_t friendnumber, const uint8_t *data, uint16_t length) |
360 | { | 416 | { |
361 | if (length != sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH) | 417 | if (length != sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH) |
362 | return -1; | 418 | return -1; |
363 | 419 | ||
364 | int groupnumber = create_group_chat(g_c); | 420 | int groupnumber = create_group_chat(g_c); |
365 | 421 | ||
366 | Group_c *g = get_group_c(g_c, groupnumber); | 422 | if (groupnumber == -1) |
367 | |||
368 | if (!g) | ||
369 | return -1; | 423 | return -1; |
370 | 424 | ||
425 | Group_c *g = &g_c->chats[groupnumber]; | ||
426 | |||
371 | uint16_t group_num = htons(groupnumber); | 427 | uint16_t group_num = htons(groupnumber); |
372 | g->status = GROUPCHAT_STATUS_VALID; | 428 | g->status = GROUPCHAT_STATUS_VALID; |
373 | uint8_t response[INVITE_RESPONSE_PACKET_SIZE]; | 429 | uint8_t response[INVITE_RESPONSE_PACKET_SIZE]; |
@@ -379,7 +435,9 @@ int join_groupchat(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16 | |||
379 | uint16_t other_groupnum; | 435 | uint16_t other_groupnum; |
380 | memcpy(&other_groupnum, data, sizeof(other_groupnum)); | 436 | memcpy(&other_groupnum, data, sizeof(other_groupnum)); |
381 | other_groupnum = htons(other_groupnum); | 437 | other_groupnum = htons(other_groupnum); |
382 | //TODO add_friend_to_groupchat(g_c, friendnumber, groupnumber, other_groupnum); | 438 | memcpy(g->identifier, data + sizeof(uint16_t), GROUP_IDENTIFIER_LENGTH); |
439 | add_friend_to_groupchat(g_c, friendnumber, groupnumber, other_groupnum); | ||
440 | g->peer_number = rand(); /* TODO */ | ||
383 | return groupnumber; | 441 | return groupnumber; |
384 | } else { | 442 | } else { |
385 | return -1; | 443 | return -1; |
@@ -428,10 +486,16 @@ static void handle_friend_invite_packet(Messenger *m, int32_t friendnumber, cons | |||
428 | int groupnumber = get_group_num(g_c, data + 1 + sizeof(uint16_t)); | 486 | int groupnumber = get_group_num(g_c, data + 1 + sizeof(uint16_t)); |
429 | 487 | ||
430 | if (groupnumber == -1) { | 488 | if (groupnumber == -1) { |
431 | g_c->invite_callback(m, friendnumber, invite_data, invite_length, g_c->invite_callback_userdata); | 489 | if (g_c->invite_callback) |
490 | g_c->invite_callback(m, friendnumber, invite_data, invite_length, g_c->invite_callback_userdata); | ||
491 | |||
432 | return; | 492 | return; |
433 | } else { | 493 | } else { |
434 | //TODO | 494 | //TODO |
495 | uint16_t other_groupnum; | ||
496 | memcpy(&other_groupnum, data + 1, sizeof(uint16_t)); | ||
497 | other_groupnum = ntohs(other_groupnum); | ||
498 | add_friend_to_groupchat(g_c, friendnumber, groupnumber, other_groupnum); | ||
435 | } | 499 | } |
436 | 500 | ||
437 | break; | 501 | break; |
@@ -441,13 +505,22 @@ static void handle_friend_invite_packet(Messenger *m, int32_t friendnumber, cons | |||
441 | if (length != INVITE_RESPONSE_PACKET_SIZE) | 505 | if (length != INVITE_RESPONSE_PACKET_SIZE) |
442 | return; | 506 | return; |
443 | 507 | ||
444 | int groupnumber = get_group_num(g_c, data + 1 + sizeof(uint16_t)); | 508 | uint16_t other_groupnum, groupnum; |
509 | memcpy(&groupnum, data + 1 + sizeof(uint16_t), sizeof(uint16_t)); | ||
510 | groupnum = ntohs(groupnum); | ||
445 | 511 | ||
446 | if (groupnumber == -1) { | 512 | Group_c *g = get_group_c(g_c, groupnum); |
513 | |||
514 | if (!g) | ||
515 | return; | ||
516 | |||
517 | if (memcmp(data + 1 + sizeof(uint16_t) * 2, g->identifier, GROUP_IDENTIFIER_LENGTH) != 0) | ||
447 | return; | 518 | return; |
448 | } else { | 519 | |
449 | //TODO add_friend_to_groupchat(g_c, friendnumber, groupnumber, other_groupnum); | 520 | memcpy(&other_groupnum, data + 1, sizeof(uint16_t)); |
450 | } | 521 | other_groupnum = ntohs(other_groupnum); |
522 | |||
523 | add_friend_to_groupchat(g_c, friendnumber, groupnum, other_groupnum); | ||
451 | 524 | ||
452 | break; | 525 | break; |
453 | } | 526 | } |
@@ -457,9 +530,197 @@ static void handle_friend_invite_packet(Messenger *m, int32_t friendnumber, cons | |||
457 | } | 530 | } |
458 | } | 531 | } |
459 | 532 | ||
533 | /* Find index of friend in the close list; | ||
534 | * | ||
535 | * returns index on success | ||
536 | * returns -1 on failure. | ||
537 | */ | ||
538 | static int friend_in_close(Group_c *g, int32_t friendnumber) | ||
539 | { | ||
540 | int i; | ||
541 | |||
542 | for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { | ||
543 | if (g->close[i].type != GROUPCHAT_CLOSE_FRIEND) | ||
544 | continue; | ||
545 | |||
546 | if (g->close[i].number != (uint32_t)friendnumber) | ||
547 | continue; | ||
548 | |||
549 | break; | ||
550 | } | ||
551 | |||
552 | if (i == MAX_GROUP_CONNECTIONS) | ||
553 | return -1; | ||
554 | |||
555 | return i; | ||
556 | } | ||
557 | |||
558 | #define MIN_MESSAGE_PACKET_LEN (sizeof(uint16_t) * 2 + sizeof(uint32_t) + 1) | ||
559 | |||
560 | /* Send message to all close except receiver (if receiver isn't -1) | ||
561 | * NOTE: this function appends the group chat number to the data passed to it. | ||
562 | * | ||
563 | * return number of messages sent. | ||
564 | */ | ||
565 | static unsigned int send_message_all_close(const Group_Chats *g_c, int groupnumber, const uint8_t *data, | ||
566 | uint16_t length, int receiver) | ||
567 | { | ||
568 | |||
569 | Group_c *g = get_group_c(g_c, groupnumber); | ||
570 | |||
571 | if (!g) | ||
572 | return 0; | ||
573 | |||
574 | uint16_t i, sent = 0; | ||
575 | |||
576 | for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { | ||
577 | if (g->close[i].type == GROUPCHAT_CLOSE_NONE) | ||
578 | continue; | ||
579 | |||
580 | if ((int)i == receiver) | ||
581 | continue; | ||
582 | |||
583 | uint16_t other_groupnum = htons(g->close[i].group_number); | ||
584 | uint8_t packet[sizeof(uint16_t) + length]; | ||
585 | memcpy(packet, &other_groupnum, sizeof(uint16_t)); | ||
586 | memcpy(packet + sizeof(uint16_t), data, length); | ||
587 | |||
588 | if (send_group_message_packet(g_c->m, g->close[i].number, packet, sizeof(packet))) | ||
589 | ++sent; | ||
590 | } | ||
591 | |||
592 | return sent; | ||
593 | } | ||
594 | |||
595 | /* Send data of len with message_id to groupnumber. | ||
596 | * | ||
597 | * return number of peers it was sent to on success. | ||
598 | * return 0 on failure. | ||
599 | */ | ||
600 | static unsigned int send_message_group(const Group_Chats *g_c, int groupnumber, uint8_t message_id, const uint8_t *data, | ||
601 | uint16_t len) | ||
602 | { | ||
603 | Group_c *g = get_group_c(g_c, groupnumber); | ||
604 | |||
605 | if (!g) | ||
606 | return 0; | ||
607 | |||
608 | uint8_t packet[sizeof(uint16_t) + sizeof(uint32_t) + 1 + len]; | ||
609 | uint16_t peer_num = htons(g->peer_number); | ||
610 | memcpy(packet, &peer_num, sizeof(peer_num)); | ||
611 | |||
612 | ++g->message_number; | ||
613 | |||
614 | if (!g->message_number) | ||
615 | ++g->message_number; | ||
616 | |||
617 | uint32_t message_num = htonl(g->message_number); | ||
618 | memcpy(packet + sizeof(uint16_t), &message_num, sizeof(message_num)); | ||
619 | |||
620 | packet[sizeof(uint16_t) + sizeof(uint32_t)] = message_id; | ||
621 | |||
622 | if (len) | ||
623 | memcpy(packet + sizeof(uint16_t) + sizeof(uint32_t) + 1, data, len); | ||
624 | |||
625 | return send_message_all_close(g_c, groupnumber, packet, sizeof(packet), -1); | ||
626 | } | ||
627 | |||
628 | /* send a group message | ||
629 | * return 0 on success | ||
630 | * return -1 on failure | ||
631 | */ | ||
632 | int group_message_send(const Group_Chats *g_c, int groupnumber, const uint8_t *message, uint16_t length) | ||
633 | { | ||
634 | if (send_message_group(g_c, groupnumber, PACKET_ID_MESSAGE, message, length)) { | ||
635 | return 0; | ||
636 | } else { | ||
637 | return -1; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | static void handle_message_packet_group(Group_Chats *g_c, int groupnumber, const uint8_t *data, uint16_t length, | ||
642 | int close_index) | ||
643 | { | ||
644 | if (length < MIN_MESSAGE_PACKET_LEN) | ||
645 | return; | ||
646 | |||
647 | Group_c *g = get_group_c(g_c, groupnumber); | ||
648 | |||
649 | if (!g) | ||
650 | return; | ||
651 | |||
652 | uint16_t peer_number; | ||
653 | memcpy(&peer_number, data + sizeof(uint16_t), sizeof(uint16_t)); | ||
654 | peer_number = ntohs(peer_number); | ||
655 | |||
656 | int index = get_peer_index(g, peer_number); | ||
657 | |||
658 | //TODO remove | ||
659 | if (index == -1) { | ||
660 | uint8_t empty_key[crypto_box_PUBLICKEYBYTES]; | ||
661 | index = addpeer(g, empty_key, peer_number); | ||
662 | } | ||
663 | |||
664 | if (index == -1) | ||
665 | return; | ||
666 | |||
667 | uint32_t message_number; | ||
668 | memcpy(&message_number, data + sizeof(uint16_t) * 2, sizeof(message_number)); | ||
669 | message_number = ntohl(message_number); | ||
670 | |||
671 | if (g->group[index].last_message_number == 0) { | ||
672 | g->group[index].last_message_number = message_number; | ||
673 | } else if (message_number - g->group[index].last_message_number > 64 || | ||
674 | message_number == g->group[index].last_message_number) { | ||
675 | return; | ||
676 | } | ||
677 | |||
678 | g->group[index].last_message_number = message_number; | ||
679 | |||
680 | uint8_t message_id = data[sizeof(uint16_t) * 2 + sizeof(message_number)]; | ||
681 | const uint8_t *msg_data = data + sizeof(uint16_t) * 2 + sizeof(message_number) + 1; | ||
682 | uint16_t msg_data_len = length - (sizeof(uint16_t) * 2 + sizeof(message_number) + 1); | ||
683 | |||
684 | switch (message_id) { | ||
685 | case PACKET_ID_MESSAGE: { | ||
686 | if (msg_data_len == 0) | ||
687 | return; | ||
688 | |||
689 | //TODO | ||
690 | if (g_c->message_callback) | ||
691 | g_c->message_callback(g_c->m, groupnumber, index, msg_data, msg_data_len, g_c->message_callback_userdata); | ||
692 | |||
693 | break; | ||
694 | } | ||
695 | |||
696 | default: | ||
697 | return; | ||
698 | } | ||
699 | |||
700 | send_message_all_close(g_c, groupnumber, data + sizeof(uint16_t), length - sizeof(uint16_t), close_index); | ||
701 | } | ||
702 | |||
460 | static void handle_friend_message_packet(Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length) | 703 | static void handle_friend_message_packet(Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length) |
461 | { | 704 | { |
705 | Group_Chats *g_c = m->group_chat_object; | ||
706 | |||
707 | if (length < MIN_MESSAGE_PACKET_LEN) | ||
708 | return; | ||
709 | |||
710 | uint16_t groupnumber; | ||
711 | memcpy(&groupnumber, data, sizeof(uint16_t)); | ||
712 | groupnumber = ntohs(groupnumber); | ||
713 | Group_c *g = get_group_c(g_c, groupnumber); | ||
714 | |||
715 | if (!g) | ||
716 | return; | ||
717 | |||
718 | int index = friend_in_close(g, friendnumber); | ||
719 | |||
720 | if (index == -1) | ||
721 | return; | ||
462 | 722 | ||
723 | handle_message_packet_group(g_c, groupnumber, data, length, index); | ||
463 | } | 724 | } |
464 | 725 | ||
465 | /* Create new groupchat instance. */ | 726 | /* Create new groupchat instance. */ |
@@ -476,6 +737,7 @@ Group_Chats *new_groupchats(Messenger *m) | |||
476 | temp->m = m; | 737 | temp->m = m; |
477 | m->group_chat_object = temp; | 738 | m->group_chat_object = temp; |
478 | m_callback_group_invite(m, &handle_friend_invite_packet); | 739 | m_callback_group_invite(m, &handle_friend_invite_packet); |
740 | m_callback_group_message(m, &handle_friend_message_packet); | ||
479 | 741 | ||
480 | return temp; | 742 | return temp; |
481 | } | 743 | } |
diff --git a/toxcore/group.h b/toxcore/group.h index 544fbdb7..51152843 100644 --- a/toxcore/group.h +++ b/toxcore/group.h | |||
@@ -41,7 +41,6 @@ typedef struct { | |||
41 | uint8_t client_id[crypto_box_PUBLICKEYBYTES]; | 41 | uint8_t client_id[crypto_box_PUBLICKEYBYTES]; |
42 | uint64_t pingid; | 42 | uint64_t pingid; |
43 | uint64_t last_pinged; | 43 | uint64_t last_pinged; |
44 | IP_Port ping_via; | ||
45 | 44 | ||
46 | uint64_t last_recv; | 45 | uint64_t last_recv; |
47 | uint64_t last_recv_msgping; | 46 | uint64_t last_recv_msgping; |
@@ -52,12 +51,20 @@ typedef struct { | |||
52 | 51 | ||
53 | uint8_t deleted; | 52 | uint8_t deleted; |
54 | uint64_t deleted_time; | 53 | uint64_t deleted_time; |
55 | } Group_Peer; | ||
56 | 54 | ||
55 | uint16_t peer_number; | ||
56 | } Group_Peer; | ||
57 | 57 | ||
58 | #define MAX_GROUP_CONNECTIONS 4 | 58 | #define DESIRED_CLOSE_CONNECTIONS 3 |
59 | #define MAX_GROUP_CONNECTIONS 16 | ||
59 | #define GROUP_IDENTIFIER_LENGTH crypto_box_KEYBYTES /* So we can use new_symmetric_key(...) to fill it */ | 60 | #define GROUP_IDENTIFIER_LENGTH crypto_box_KEYBYTES /* So we can use new_symmetric_key(...) to fill it */ |
60 | 61 | ||
62 | enum { | ||
63 | GROUPCHAT_CLOSE_NONE, | ||
64 | GROUPCHAT_CLOSE_FRIEND, | ||
65 | GROUPCHAT_CLOSE_GROUPCON | ||
66 | }; | ||
67 | |||
61 | typedef struct { | 68 | typedef struct { |
62 | uint8_t status; | 69 | uint8_t status; |
63 | 70 | ||
@@ -65,11 +72,15 @@ typedef struct { | |||
65 | uint32_t numpeers; | 72 | uint32_t numpeers; |
66 | 73 | ||
67 | struct { | 74 | struct { |
68 | uint8_t type; | 75 | uint8_t type; /* GROUPCHAT_CLOSE_* */ |
69 | uint32_t number; | 76 | uint32_t number; |
77 | uint16_t group_number; | ||
70 | } close[MAX_GROUP_CONNECTIONS]; | 78 | } close[MAX_GROUP_CONNECTIONS]; |
71 | 79 | ||
72 | uint8_t identifier[GROUP_IDENTIFIER_LENGTH]; | 80 | uint8_t identifier[GROUP_IDENTIFIER_LENGTH]; |
81 | |||
82 | uint32_t message_number; | ||
83 | uint16_t peer_number; | ||
73 | } Group_c; | 84 | } Group_c; |
74 | 85 | ||
75 | typedef struct { | 86 | typedef struct { |
@@ -155,19 +166,19 @@ int invite_friend(Group_Chats *g_c, int32_t friendnumber, int groupnumber); | |||
155 | * returns group number on success | 166 | * returns group number on success |
156 | * returns -1 on failure. | 167 | * returns -1 on failure. |
157 | */ | 168 | */ |
158 | int join_groupchat(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length); | 169 | int join_groupchat(Group_Chats *g_c, int32_t friendnumber, const uint8_t *data, uint16_t length); |
159 | 170 | ||
160 | /* send a group message | 171 | /* send a group message |
161 | * return 0 on success | 172 | * return 0 on success |
162 | * return -1 on failure | 173 | * return -1 on failure |
163 | */ | 174 | */ |
164 | int group_message_send(const Group_Chats *g_c, int groupnumber, const uint8_t *message, uint32_t length); | 175 | int group_message_send(const Group_Chats *g_c, int groupnumber, const uint8_t *message, uint16_t length); |
165 | 176 | ||
166 | /* send a group action | 177 | /* send a group action |
167 | * return 0 on success | 178 | * return 0 on success |
168 | * return -1 on failure | 179 | * return -1 on failure |
169 | */ | 180 | */ |
170 | int group_action_send(const Group_Chats *g_c, int groupnumber, const uint8_t *action, uint32_t length); | 181 | int group_action_send(const Group_Chats *g_c, int groupnumber, const uint8_t *action, uint16_t length); |
171 | 182 | ||
172 | /* Return the number of peers in the group chat on success. | 183 | /* Return the number of peers in the group chat on success. |
173 | * return -1 on failure | 184 | * return -1 on failure |
diff --git a/toxcore/tox.c b/toxcore/tox.c index 39a63fd9..789ef3c9 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #include "Messenger.h" | 28 | #include "Messenger.h" |
29 | #include "group.h" | ||
29 | #include "logger.h" | 30 | #include "logger.h" |
30 | 31 | ||
31 | #define __TOX_DEFINED__ | 32 | #define __TOX_DEFINED__ |
@@ -544,13 +545,15 @@ int tox_send_lossless_packet(const Tox *tox, int32_t friendnumber, const uint8_t | |||
544 | 545 | ||
545 | /* Set the callback for group invites. | 546 | /* Set the callback for group invites. |
546 | * | 547 | * |
547 | * Function(Tox *tox, int32_t friendnumber, uint8_t *group_public_key, void *userdata) | 548 | * Function(Tox *tox, int32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) |
549 | * | ||
550 | * data of length is what needs to be passed to join_groupchat(). | ||
548 | */ | 551 | */ |
549 | void tox_callback_group_invite(Tox *tox, void (*function)(Messenger *tox, int32_t, const uint8_t *, void *), | 552 | void tox_callback_group_invite(Tox *tox, void (*function)(Messenger *tox, int32_t, const uint8_t *, uint16_t, void *), |
550 | void *userdata) | 553 | void *userdata) |
551 | { | 554 | { |
552 | Messenger *m = tox; | 555 | Messenger *m = tox; |
553 | //m_callback_group_invite(m, function, userdata); | 556 | g_callback_group_invite(m->group_chat_object, function, userdata); |
554 | } | 557 | } |
555 | 558 | ||
556 | /* Set the callback for group messages. | 559 | /* Set the callback for group messages. |
@@ -561,7 +564,7 @@ void tox_callback_group_message(Tox *tox, void (*function)(Messenger *tox, int, | |||
561 | void *userdata) | 564 | void *userdata) |
562 | { | 565 | { |
563 | Messenger *m = tox; | 566 | Messenger *m = tox; |
564 | //m_callback_group_message(m, function, userdata); | 567 | g_callback_group_message(m->group_chat_object, function, userdata); |
565 | } | 568 | } |
566 | 569 | ||
567 | /* Set the callback for group actions. | 570 | /* Set the callback for group actions. |
@@ -594,8 +597,9 @@ void tox_callback_group_namelist_change(Tox *tox, void (*function)(Tox *tox, int | |||
594 | int tox_add_groupchat(Tox *tox) | 597 | int tox_add_groupchat(Tox *tox) |
595 | { | 598 | { |
596 | Messenger *m = tox; | 599 | Messenger *m = tox; |
597 | //return add_groupchat(m); | 600 | return add_groupchat(m->group_chat_object); |
598 | } | 601 | } |
602 | |||
599 | /* Delete a groupchat from the chats array. | 603 | /* Delete a groupchat from the chats array. |
600 | * | 604 | * |
601 | * return 0 on success. | 605 | * return 0 on success. |
@@ -605,6 +609,7 @@ int tox_del_groupchat(Tox *tox, int groupnumber) | |||
605 | { | 609 | { |
606 | Messenger *m = tox; | 610 | Messenger *m = tox; |
607 | //return del_groupchat(m, groupnumber); | 611 | //return del_groupchat(m, groupnumber); |
612 | return -1; | ||
608 | } | 613 | } |
609 | 614 | ||
610 | /* Copy the name of peernumber who is in groupnumber to name. | 615 | /* Copy the name of peernumber who is in groupnumber to name. |
@@ -617,7 +622,9 @@ int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t | |||
617 | { | 622 | { |
618 | const Messenger *m = tox; | 623 | const Messenger *m = tox; |
619 | //return m_group_peername(m, groupnumber, peernumber, name); | 624 | //return m_group_peername(m, groupnumber, peernumber, name); |
625 | return -1; | ||
620 | } | 626 | } |
627 | |||
621 | /* invite friendnumber to groupnumber | 628 | /* invite friendnumber to groupnumber |
622 | * return 0 on success | 629 | * return 0 on success |
623 | * return -1 on failure | 630 | * return -1 on failure |
@@ -625,37 +632,40 @@ int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t | |||
625 | int tox_invite_friend(Tox *tox, int32_t friendnumber, int groupnumber) | 632 | int tox_invite_friend(Tox *tox, int32_t friendnumber, int groupnumber) |
626 | { | 633 | { |
627 | Messenger *m = tox; | 634 | Messenger *m = tox; |
628 | //return invite_friend(m, friendnumber, groupnumber); | 635 | return invite_friend(m->group_chat_object, friendnumber, groupnumber); |
629 | } | 636 | } |
630 | /* Join a group (you need to have been invited first.) | 637 | |
638 | /* Join a group (you need to have been invited first.) using data of length obtained | ||
639 | * in the group invite callback. | ||
631 | * | 640 | * |
632 | * returns group number on success | 641 | * returns group number on success |
633 | * returns -1 on failure. | 642 | * returns -1 on failure. |
634 | */ | 643 | */ |
635 | int tox_join_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *friend_group_public_key) | 644 | int tox_join_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length) |
636 | { | 645 | { |
637 | Messenger *m = tox; | 646 | Messenger *m = tox; |
638 | //return join_groupchat(m, friendnumber, friend_group_public_key); | 647 | return join_groupchat(m->group_chat_object, friendnumber, data, length); |
639 | } | 648 | } |
640 | 649 | ||
641 | /* send a group message | 650 | /* send a group message |
642 | * return 0 on success | 651 | * return 0 on success |
643 | * return -1 on failure | 652 | * return -1 on failure |
644 | */ | 653 | */ |
645 | int tox_group_message_send(Tox *tox, int groupnumber, const uint8_t *message, uint32_t length) | 654 | int tox_group_message_send(Tox *tox, int groupnumber, const uint8_t *message, uint16_t length) |
646 | { | 655 | { |
647 | Messenger *m = tox; | 656 | Messenger *m = tox; |
648 | //return group_message_send(m, groupnumber, message, length); | 657 | return group_message_send(m->group_chat_object, groupnumber, message, length); |
649 | } | 658 | } |
650 | 659 | ||
651 | /* send a group action | 660 | /* send a group action |
652 | * return 0 on success | 661 | * return 0 on success |
653 | * return -1 on failure | 662 | * return -1 on failure |
654 | */ | 663 | */ |
655 | int tox_group_action_send(Tox *tox, int groupnumber, const uint8_t *action, uint32_t length) | 664 | int tox_group_action_send(Tox *tox, int groupnumber, const uint8_t *action, uint16_t length) |
656 | { | 665 | { |
657 | Messenger *m = tox; | 666 | Messenger *m = tox; |
658 | //return group_action_send(m, groupnumber, action, length); | 667 | //return group_action_send(m, groupnumber, action, length); |
668 | return -1; | ||
659 | } | 669 | } |
660 | 670 | ||
661 | /* Return the number of peers in the group chat on success. | 671 | /* Return the number of peers in the group chat on success. |
@@ -665,6 +675,7 @@ int tox_group_number_peers(const Tox *tox, int groupnumber) | |||
665 | { | 675 | { |
666 | const Messenger *m = tox; | 676 | const Messenger *m = tox; |
667 | //return group_number_peers(m, groupnumber); | 677 | //return group_number_peers(m, groupnumber); |
678 | return -1; | ||
668 | } | 679 | } |
669 | 680 | ||
670 | /* List all the peers in the group chat. | 681 | /* List all the peers in the group chat. |
@@ -682,6 +693,7 @@ int tox_group_get_names(const Tox *tox, int groupnumber, uint8_t names[][TOX_MAX | |||
682 | { | 693 | { |
683 | const Messenger *m = tox; | 694 | const Messenger *m = tox; |
684 | //return group_names(m, groupnumber, names, lengths, length); | 695 | //return group_names(m, groupnumber, names, lengths, length); |
696 | return -1; | ||
685 | } | 697 | } |
686 | 698 | ||
687 | /* Return the number of chats in the instance m. | 699 | /* Return the number of chats in the instance m. |
@@ -691,6 +703,7 @@ uint32_t tox_count_chatlist(const Tox *tox) | |||
691 | { | 703 | { |
692 | const Messenger *m = tox; | 704 | const Messenger *m = tox; |
693 | //return count_chatlist(m); | 705 | //return count_chatlist(m); |
706 | return 0; | ||
694 | } | 707 | } |
695 | 708 | ||
696 | /* Copy a list of valid chat IDs into the array out_list. | 709 | /* Copy a list of valid chat IDs into the array out_list. |
@@ -702,6 +715,7 @@ uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size) | |||
702 | { | 715 | { |
703 | const Messenger *m = tox; | 716 | const Messenger *m = tox; |
704 | //return copy_chatlist(m, out_list, list_size); | 717 | //return copy_chatlist(m, out_list, list_size); |
718 | return 0; | ||
705 | } | 719 | } |
706 | 720 | ||
707 | 721 | ||
@@ -947,7 +961,14 @@ Tox *tox_new(Tox_Options *options) | |||
947 | } | 961 | } |
948 | } | 962 | } |
949 | 963 | ||
950 | return new_messenger(&m_options); | 964 | Messenger *m = new_messenger(&m_options); |
965 | |||
966 | if (!new_groupchats(m)) { | ||
967 | kill_messenger(m); | ||
968 | return NULL; | ||
969 | } | ||
970 | |||
971 | return m; | ||
951 | } | 972 | } |
952 | 973 | ||
953 | /* Run this before closing shop. | 974 | /* Run this before closing shop. |
@@ -956,6 +977,7 @@ Tox *tox_new(Tox_Options *options) | |||
956 | void tox_kill(Tox *tox) | 977 | void tox_kill(Tox *tox) |
957 | { | 978 | { |
958 | Messenger *m = tox; | 979 | Messenger *m = tox; |
980 | kill_groupchats(m->group_chat_object); | ||
959 | kill_messenger(m); | 981 | kill_messenger(m); |
960 | } | 982 | } |
961 | 983 | ||
diff --git a/toxcore/tox.h b/toxcore/tox.h index 61cfdf70..a271bc60 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -419,9 +419,12 @@ int tox_send_lossless_packet(const Tox *tox, int32_t friendnumber, const uint8_t | |||
419 | 419 | ||
420 | /* Set the callback for group invites. | 420 | /* Set the callback for group invites. |
421 | * | 421 | * |
422 | * Function(Tox *tox, int friendnumber, uint8_t *group_public_key, void *userdata) | 422 | * Function(Tox *tox, int32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) |
423 | * | ||
424 | * data of length is what needs to be passed to join_groupchat(). | ||
423 | */ | 425 | */ |
424 | void tox_callback_group_invite(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, void *), void *userdata); | 426 | void tox_callback_group_invite(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *), |
427 | void *userdata); | ||
425 | 428 | ||
426 | /* Set the callback for group messages. | 429 | /* Set the callback for group messages. |
427 | * | 430 | * |
@@ -479,24 +482,25 @@ int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t | |||
479 | */ | 482 | */ |
480 | int tox_invite_friend(Tox *tox, int32_t friendnumber, int groupnumber); | 483 | int tox_invite_friend(Tox *tox, int32_t friendnumber, int groupnumber); |
481 | 484 | ||
482 | /* Join a group (you need to have been invited first.) | 485 | /* Join a group (you need to have been invited first.) using data of length obtained |
486 | * in the group invite callback. | ||
483 | * | 487 | * |
484 | * returns group number on success | 488 | * returns group number on success |
485 | * returns -1 on failure. | 489 | * returns -1 on failure. |
486 | */ | 490 | */ |
487 | int tox_join_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *friend_group_public_key); | 491 | int tox_join_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length); |
488 | 492 | ||
489 | /* send a group message | 493 | /* send a group message |
490 | * return 0 on success | 494 | * return 0 on success |
491 | * return -1 on failure | 495 | * return -1 on failure |
492 | */ | 496 | */ |
493 | int tox_group_message_send(Tox *tox, int groupnumber, const uint8_t *message, uint32_t length); | 497 | int tox_group_message_send(Tox *tox, int groupnumber, const uint8_t *message, uint16_t length); |
494 | 498 | ||
495 | /* send a group action | 499 | /* send a group action |
496 | * return 0 on success | 500 | * return 0 on success |
497 | * return -1 on failure | 501 | * return -1 on failure |
498 | */ | 502 | */ |
499 | int tox_group_action_send(Tox *tox, int groupnumber, const uint8_t *action, uint32_t length); | 503 | int tox_group_action_send(Tox *tox, int groupnumber, const uint8_t *action, uint16_t length); |
500 | 504 | ||
501 | /* Return the number of peers in the group chat on success. | 505 | /* Return the number of peers in the group chat on success. |
502 | * return -1 on failure | 506 | * return -1 on failure |