int Core::createGroup(uint8_t type) { if (type == TOX_CONFERENCE_TYPE_TEXT) { TOX_ERR_CONFERENCE_NEW error; uint32_t groupId = tox_conference_new(tox, &error); switch (error) { case TOX_ERR_CONFERENCE_NEW_OK: emit emptyGroupCreated(groupId); return groupId; case TOX_ERR_CONFERENCE_NEW_INIT: qCritical() << "The conference instance failed to initialize"; return std::numeric_limits<uint32_t>::max(); default: return std::numeric_limits<uint32_t>::max(); } } else if (type == TOX_CONFERENCE_TYPE_AV) { uint32_t groupId = toxav_add_av_groupchat(tox, CoreAV::groupCallCallback, this); emit emptyGroupCreated(groupId); return groupId; } else { qWarning() << "createGroup: Unknown type " << type; return -1; } }
static void conference_double_invite_test(Tox **toxes, State *state) { // Conference callbacks. tox_callback_conference_invite(toxes[0], handle_conference_invite); tox_callback_conference_invite(toxes[1], handle_conference_invite); { // Create new conference, tox0 is the founder. Tox_Err_Conference_New err; state[0].conference = tox_conference_new(toxes[0], &err); state[0].joined = true; ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "attempting to create a new conference returned with an error: %d", err); fprintf(stderr, "Created conference: index=%u\n", state[0].conference); } { // Invite friend. Tox_Err_Conference_Invite err; tox_conference_invite(toxes[0], 0, state[0].conference, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "attempting to invite a friend returned with an error: %d", err); fprintf(stderr, "tox0 invited tox1\n"); } fprintf(stderr, "Waiting for invitation to arrive\n"); do { iterate_all_wait(2, toxes, state, ITERATION_INTERVAL); } while (!state[0].joined || !state[1].joined); fprintf(stderr, "Invitations accepted\n"); // Invite one more time, resulting in friend -1 inviting tox1 (toxes[1]). tox_conference_invite(toxes[0], 0, state[0].conference, nullptr); iterate_all_wait(2, toxes, state, ITERATION_INTERVAL); }
int main(void) { uint32_t conference_number; struct Tox_Options to; Tox *t; TOX_ERR_CONFERENCE_NEW conference_err; TOX_ERR_CONFERENCE_TITLE title_err; tox_options_default(&to); t = tox_new(&to, NULL); tox_callback_conference_title(t, &cbtitlechange); if ((conference_number = tox_conference_new(t, &conference_err)) == UINT32_MAX) { tox_kill(t); fprintf(stderr, "error: could not create new conference, error code %d\n", conference_err); return 2; } tox_iterate(t, NULL); c_sleep(tox_iteration_interval(t)); if (!tox_conference_set_title(t, conference_number, (const uint8_t *)newtitle, strlen(newtitle), &title_err)) { tox_kill(t); fprintf(stderr, "error: could not set conference title, error code %d\n", title_err); return 3; } tox_iterate(t, NULL); c_sleep(tox_iteration_interval(t)); tox_iterate(t, NULL); fprintf(stderr, "error: title was not changed in callback. exiting.\n"); tox_kill(t); return 1; }
static void cmd_group(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH]) { const char *outmsg = NULL; if (argc < 1) { outmsg = "Please specify the group type: audio or text"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } uint8_t type = TOX_CONFERENCE_TYPE_AV ? !strcasecmp(argv[1], "audio") : TOX_CONFERENCE_TYPE_TEXT; char name[TOX_MAX_NAME_LENGTH]; tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL); size_t len = tox_friend_get_name_size(m, friendnum, NULL); name[len] = '\0'; int groupnum = -1; if (type == TOX_CONFERENCE_TYPE_TEXT) { TOX_ERR_CONFERENCE_NEW err; groupnum = tox_conference_new(m, &err); if (err != TOX_ERR_CONFERENCE_NEW_OK) { printf("Group chat creation by %s failed to initialize\n", name); outmsg = "Group chat instance failed to initialize."; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } } else if (type == TOX_CONFERENCE_TYPE_AV) { groupnum = toxav_add_av_groupchat(m, NULL, NULL); if (groupnum == -1) { printf("Group chat creation by %s failed to initialize\n", name); outmsg = "Group chat instance failed to initialize."; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } } const char *password = argc >= 2 ? argv[2] : NULL; if (password && strlen(argv[2]) >= MAX_PASSWORD_SIZE) { printf("Group chat creation by %s failed: Password too long\n", name); outmsg = "Group chat instance failed to initialize: Password too long"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); return; } if (group_add(groupnum, type, password) == -1) { printf("Group chat creation by %s failed\n", name); outmsg = "Group chat creation failed"; tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL); tox_conference_delete(m, groupnum, NULL); return; } const char *pw = password ? " (Password protected)" : ""; printf("Group chat %d created by %s%s\n", groupnum, name, pw); char msg[MAX_COMMAND_LENGTH]; snprintf(msg, sizeof(msg), "Group chat %d created%s", groupnum, pw); tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) msg, strlen(msg), NULL); }
int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); State state1 = {1}; State state2 = {2}; State state3 = {3}; // Create toxes. Tox *tox1 = tox_new_log(nullptr, nullptr, &state1.id); Tox *tox2 = tox_new_log(nullptr, nullptr, &state2.id); Tox *tox3 = tox_new_log(nullptr, nullptr, &state3.id); // tox1 <-> tox2, tox2 <-> tox3 uint8_t key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_public_key(tox2, key); tox_friend_add_norequest(tox1, key, nullptr); // tox1 -> tox2 tox_self_get_public_key(tox1, key); tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox1 tox_self_get_public_key(tox3, key); tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox3 tox_self_get_public_key(tox2, key); tox_friend_add_norequest(tox3, key, nullptr); // tox3 -> tox2 printf("bootstrapping tox2 and tox3 off tox1\n"); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr); // Connection callbacks. tox_callback_self_connection_status(tox1, handle_self_connection_status); tox_callback_self_connection_status(tox2, handle_self_connection_status); tox_callback_self_connection_status(tox3, handle_self_connection_status); tox_callback_friend_connection_status(tox1, handle_friend_connection_status); tox_callback_friend_connection_status(tox2, handle_friend_connection_status); tox_callback_friend_connection_status(tox3, handle_friend_connection_status); // Conference callbacks. tox_callback_conference_invite(tox1, handle_conference_invite); tox_callback_conference_invite(tox2, handle_conference_invite); tox_callback_conference_invite(tox3, handle_conference_invite); tox_callback_conference_connected(tox1, handle_conference_connected); tox_callback_conference_connected(tox2, handle_conference_connected); tox_callback_conference_connected(tox3, handle_conference_connected); tox_callback_conference_message(tox1, handle_conference_message); tox_callback_conference_message(tox2, handle_conference_message); tox_callback_conference_message(tox3, handle_conference_message); tox_callback_conference_peer_list_changed(tox1, handle_conference_peer_list_changed); tox_callback_conference_peer_list_changed(tox2, handle_conference_peer_list_changed); tox_callback_conference_peer_list_changed(tox3, handle_conference_peer_list_changed); // Wait for self connection. fprintf(stderr, "Waiting for toxes to come online\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (!state1.self_online || !state2.self_online || !state3.self_online); fprintf(stderr, "Toxes are online\n"); // Wait for friend connection. fprintf(stderr, "Waiting for friends to connect\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (!state1.friend_online || !state2.friend_online || !state3.friend_online); fprintf(stderr, "Friends are connected\n"); { // Create new conference, tox1 is the founder. Tox_Err_Conference_New err; state1.conference = tox_conference_new(tox1, &err); state1.joined = true; ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "failed to create a conference: err = %d", err); fprintf(stderr, "Created conference: id = %u\n", state1.conference); } { // Invite friend. Tox_Err_Conference_Invite err; tox_conference_invite(tox1, 0, state1.conference, &err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "failed to invite a friend: err = %d", err); state1.invited_next = true; fprintf(stderr, "tox1 invited tox2\n"); } fprintf(stderr, "Waiting for invitation to arrive\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (!state1.joined || !state2.joined || !state3.joined); fprintf(stderr, "Invitations accepted\n"); fprintf(stderr, "Waiting for peers to come online\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (state1.peers == 0 || state2.peers == 0 || state3.peers == 0); fprintf(stderr, "All peers are online\n"); { fprintf(stderr, "tox1 sends a message to the group: \"hello!\"\n"); Tox_Err_Conference_Send_Message err; tox_conference_send_message(tox1, state1.conference, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)"hello!", 7, &err); if (err != TOX_ERR_CONFERENCE_SEND_MESSAGE_OK) { fprintf(stderr, "ERROR: %d\n", err); exit(EXIT_FAILURE); } } fprintf(stderr, "Waiting for messages to arrive\n"); do { tox_iterate(tox1, &state1); tox_iterate(tox2, &state2); tox_iterate(tox3, &state3); c_sleep(100); } while (!state2.received || !state3.received); fprintf(stderr, "Messages received. Test complete.\n"); tox_kill(tox3); tox_kill(tox2); tox_kill(tox1); return 0; }