/* Creates a new groupchat and puts it in the chats array. * * return group number on success. * return -1 on failure. */ int add_groupchat(Group_Chats *g_c) { int groupnumber = create_group_chat(g_c); if (groupnumber == -1) return -1; Group_c *g = &g_c->chats[groupnumber]; g->status = GROUPCHAT_STATUS_CONNECTED; new_symmetric_key(g->identifier); g->peer_number = 0; /* Founder is peer 0. */ memcpy(g->real_pk, g_c->m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES); addpeer(g_c, groupnumber, g->real_pk, g_c->m->dht->self_public_key, 0); return groupnumber; }
/* Join a group (you need to have been invited first.) * * returns group number on success * returns -1 on failure. */ int join_groupchat(Group_Chats *g_c, int32_t friendnumber, const uint8_t *data, uint16_t length) { if (length != sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH) return -1; int friendcon_id = getfriendcon_id(g_c->m, friendnumber); if (friendcon_id == -1) return -1; int groupnumber = create_group_chat(g_c); if (groupnumber == -1) return -1; Group_c *g = &g_c->chats[groupnumber]; uint16_t group_num = htons(groupnumber); g->status = GROUPCHAT_STATUS_VALID; g->number_joined = -1; memcpy(g->real_pk, g_c->m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES); uint8_t response[INVITE_RESPONSE_PACKET_SIZE]; response[0] = INVITE_RESPONSE_ID; memcpy(response + 1, &group_num, sizeof(uint16_t)); memcpy(response + 1 + sizeof(uint16_t), data, sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH); if (send_group_invite_packet(g_c->m, friendnumber, response, sizeof(response))) { uint16_t other_groupnum; memcpy(&other_groupnum, data, sizeof(other_groupnum)); other_groupnum = ntohs(other_groupnum); memcpy(g->identifier, data + sizeof(uint16_t), GROUP_IDENTIFIER_LENGTH); int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnumber, 0, 1); if (close_index != -1) { g->close[close_index].group_number = other_groupnum; g->close[close_index].type = GROUPCHAT_CLOSE_ONLINE; g->number_joined = friendcon_id; } send_peer_query(g_c, friendcon_id, other_groupnum); return groupnumber; } else { g->status = GROUPCHAT_STATUS_NONE; return -1; } }