summaryrefslogtreecommitdiff
path: root/toxcore/group_chats.h
blob: 8d5f5e50ff2417eb53d0e1210b07566fd767c6dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/* group_chats.h
 *
 * An implementation of massive text only group chats.
 *
 *
 *  Copyright (C) 2013 Tox project All Rights Reserved.
 *
 *  This file is part of Tox.
 *
 *  Tox is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Tox is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Tox.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef GROUP_CHATS_H
#define GROUP_CHATS_H

#include "net_crypto.h"

#define MAX_NICK_BYTES 128

typedef struct {
    uint8_t     client_id[crypto_box_PUBLICKEYBYTES];
    uint64_t    pingid;
    uint64_t    last_pinged;
    IP_Port     ping_via;

    uint64_t    last_recv;
    uint64_t    last_recv_msgping;
    uint32_t    last_message_number;

    uint8_t     nick[MAX_NICK_BYTES];
    uint16_t    nick_len;
} Group_Peer;

typedef struct {
    uint8_t     client_id[crypto_box_PUBLICKEYBYTES];
    IP_Port     ip_port;
    uint64_t    last_recv;
} Group_Close;

#define GROUP_CLOSE_CONNECTIONS 6

typedef struct Group_Chat {
    Networking_Core *net;
    uint8_t     self_public_key[crypto_box_PUBLICKEYBYTES];
    uint8_t     self_secret_key[crypto_box_SECRETKEYBYTES];

    Group_Peer *group;
    Group_Close  close[GROUP_CLOSE_CONNECTIONS];
    uint32_t numpeers;

    uint32_t message_number;
    void (*group_message)(struct Group_Chat *m, int, uint8_t *, uint16_t, void *);
    void *group_message_userdata;
    void (*group_action)(struct Group_Chat *m, int, uint8_t *, uint16_t, void *);
    void *group_action_userdata;
    void (*peer_namelistchange)(struct Group_Chat *m, int peer, uint8_t change, void *);
    void *group_namelistchange_userdata;

    uint64_t last_sent_ping;

    uint8_t        nick[MAX_NICK_BYTES];
    uint16_t       nick_len;
    uint64_t       last_sent_nick;

    struct Assoc  *assoc;
} Group_Chat;

#define GROUP_CHAT_PING 0
#define GROUP_CHAT_NEW_PEER 16
#define GROUP_CHAT_QUIT 24
#define GROUP_CHAT_PEER_NICK 48
#define GROUP_CHAT_CHAT_MESSAGE 64
#define GROUP_CHAT_ACTION 63

/* Copy the name of peernum to name.
 * name must be at least MAX_NICK_BYTES long.
 *
 * return length of name if success
 * return -1 if failure
 */
int group_peername(Group_Chat *chat, int peernum, uint8_t *name);

/*
 * Set callback function for chat messages.
 *
 * format of function is: function(Group_Chat *chat, peer number, message, message length, userdata)
 */
void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat, int, uint8_t *, uint16_t, void *),
                           void *userdata);

/*
 * Set callback function for actions.
 *
 * format of function is: function(Group_Chat *chat, peer number, action, action length, userdata)
 */
void callback_groupaction(Group_Chat *chat, void (*function)(Group_Chat *chat, int, uint8_t *, uint16_t, void *),
                          void *userdata);

/*
 * Set callback function for peer name list changes.
 *
 * It gets called every time the name list changes(new peer/name, deleted peer)
 *
 * format of function is: function(Group_Chat *chat, userdata)
 */
typedef enum {
    CHAT_CHANGE_PEER_ADD,
    CHAT_CHANGE_PEER_DEL,
    CHAT_CHANGE_PEER_NAME,
} CHAT_CHANGE;

void callback_namelistchange(Group_Chat *chat, void (*function)(Group_Chat *chat, int peer, uint8_t change, void *),
                             void *userdata);

/*
 * 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);

/*
 * Send an action to the group.
 *
 * returns the number of peers it has sent it to.
 */
uint32_t group_sendaction(Group_Chat *chat, uint8_t *action, uint32_t length);

/*
 * Set our nick for this group.
 *
 * returns -1 on failure, 0 on success.
 */
int set_nick(Group_Chat *chat, uint8_t *nick, uint16_t nick_len);

/*
 * Tell everyone about a new peer (a person we are inviting for example.)
 *
 */
uint32_t group_newpeer(Group_Chat *chat, uint8_t *client_id);


/* Create a new group chat.
 *
 * Returns a new group chat instance if success.
 *
 * Returns a NULL pointer if fail.
 */
Group_Chat *new_groupchat(Networking_Core *net);


/* Return the number of peers in the group chat.
 */
uint32_t group_numpeers(Group_Chat *chat);

/* List all the peers in the group chat.
 *
 * Copies the names of the peers to the name[length][MAX_NICK_BYTES] array.
 *
 * returns the number of peers.
 */
uint32_t group_client_names(Group_Chat *chat, uint8_t names[][MAX_NICK_BYTES], uint16_t length);

/* Kill a group chat
 *
 * Frees the memory and everything.
 */
void kill_groupchat(Group_Chat *chat);

/*
 * This is the main loop.
 */
void do_groupchat(Group_Chat *chat);

/* if we receive a group chat packet we call this function so it can be handled.
    return 0 if packet is handled correctly.
    return 1 if it didn't handle the packet or if the packet was shit. */
int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, uint32_t length);


void chat_bootstrap(Group_Chat *chat, IP_Port ip_port, uint8_t *client_id);
void chat_bootstrap_nonlazy(Group_Chat *chat, IP_Port ip_port, uint8_t *client_id);


#endif