summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL.md245
-rw-r--r--README.md20
-rw-r--r--auto_tests/TCP_test.c6
-rw-r--r--auto_tests/tox_test.c10
-rw-r--r--auto_tests/toxav_basic_test.c51
-rw-r--r--auto_tests/toxav_many_test.c36
-rw-r--r--docs/TODO4
-rw-r--r--other/bootstrap_daemon/tox_bootstrap_daemon.c62
-rw-r--r--other/fun/cracker.c2
-rw-r--r--other/fun/sign.c1
-rw-r--r--other/fun/strkey.c137
-rw-r--r--testing/Messenger_test.c2
-rw-r--r--testing/dns3_test.c72
-rw-r--r--testing/nTox.c43
-rw-r--r--testing/tox_sync.c6
-rw-r--r--toxav/Makefile.inc8
-rw-r--r--toxav/codec.c (renamed from toxav/media.c)141
-rw-r--r--toxav/codec.h (renamed from toxav/media.h)28
-rw-r--r--toxav/event.c382
-rw-r--r--toxav/event.h49
-rw-r--r--toxav/msi.c719
-rw-r--r--toxav/msi.h13
-rw-r--r--toxav/rtp.c389
-rw-r--r--toxav/rtp.h38
-rw-r--r--toxav/toxav.c562
-rw-r--r--toxav/toxav.h82
-rw-r--r--toxcore/DHT.c4
-rw-r--r--toxcore/DHT.h2
-rw-r--r--toxcore/Messenger.c224
-rw-r--r--toxcore/Messenger.h148
-rw-r--r--toxcore/TCP_client.c53
-rw-r--r--toxcore/TCP_client.h29
-rw-r--r--toxcore/TCP_server.c35
-rw-r--r--toxcore/TCP_server.h6
-rw-r--r--toxcore/assoc.c4
-rw-r--r--toxcore/group_chats.c10
-rw-r--r--toxcore/list.c96
-rw-r--r--toxcore/list.h21
-rw-r--r--toxcore/net_crypto.c172
-rw-r--r--toxcore/net_crypto.h40
-rw-r--r--toxcore/network.c8
-rw-r--r--toxcore/onion.c38
-rw-r--r--toxcore/onion.h18
-rw-r--r--toxcore/onion_announce.c112
-rw-r--r--toxcore/onion_announce.h45
-rw-r--r--toxcore/onion_client.c89
-rw-r--r--toxcore/onion_client.h8
-rw-r--r--toxcore/ping_array.c2
-rw-r--r--toxcore/tox.c184
-rw-r--r--toxcore/tox.h118
-rw-r--r--toxdns/toxdns.c8
51 files changed, 2476 insertions, 2106 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 78c3d688..41aa5afd 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1,18 +1,22 @@
1#Install Instructions 1#Install Instructions
2 2
3- [Installation](#installation) 3- [Installation](#installation)
4 - [Unix like](#unix) 4 - [Unix like](#unix)
5 - [OS X](#osx) 5 - [OS X](#osx)
6 - [Homebrew](#homebrew) 6 - [Homebrew](#homebrew)
7 - [Non-Homebrew](#non-homebrew) 7 - [Non-Homebrew](#non-homebrew)
8 - [Windows](#windows) 8 - [Windows](#windows)
9 9 - [Cross-Compile](#windows-cross-compile)
10 - [Setting up a VM](#windows-cross-compile-vm)
11 - [Setting up the environment](#windows-cross-compile-environment)
12 - [Compiling](#windows-cross-compile-compiling)
13 - [Native](#windows-native)
10- [Additional](#additional) 14- [Additional](#additional)
11 - [Advanced configure options] (#aconf) 15 - [Advanced configure options](#aconf)
12 - [A/V support](#av) 16 - [A/V support](#av)
13 - [libtoxav] (#libtoxav) 17 - [libtoxav](#libtoxav)
14 - [Bootstrap daemon] (#bootstrapd) 18 - [Bootstrap daemon](#bootstrapd)
15 - [nTox] (#ntox) 19 - [nTox](#ntox)
16 20
17<a name="installation" /> 21<a name="installation" />
18##Installation 22##Installation
@@ -45,17 +49,18 @@ pkg install autoconf automake gcc-47
45On FreeBSD 10+: 49On FreeBSD 10+:
46 50
47```tcsh 51```tcsh
48pkg install automake autoconf 52pkg install net-im/tox
49``` 53```
54Note, if you install from ports select NaCl for performance, and sodium if you want it to be portable.
50 55
51You should get and install [libsodium](https://github.com/jedisct1/libsodium): 56You should get and install [libsodium](https://github.com/jedisct1/libsodium):
52```bash 57```bash
53git clone git://github.com/jedisct1/libsodium.git 58git clone git://github.com/jedisct1/libsodium.git
54cd libsodium 59cd libsodium
55git checkout tags/0.4.2 60git checkout tags/0.5.0
56./autogen.sh 61./autogen.sh
57./configure && make check 62./configure && make check
58sudo checkinstall --install --pkgname libsodium --pkgversion 0.4.2 --nodoc 63sudo checkinstall --install --pkgname libsodium --pkgversion 0.5.0 --nodoc
59sudo ldconfig 64sudo ldconfig
60cd .. 65cd ..
61``` 66```
@@ -67,7 +72,7 @@ this will install the libs to /usr/local/lib and the headers to /usr/local/inclu
67```bash 72```bash
68git clone git://github.com/jedisct1/libsodium.git 73git clone git://github.com/jedisct1/libsodium.git
69cd libsodium 74cd libsodium
70git checkout tags/0.4.2 75git checkout tags/0.5.0
71./autogen.sh 76./autogen.sh
72./configure 77./configure
73make check 78make check
@@ -145,6 +150,14 @@ Grab the following packages:
145 * https://gnu.org/software/automake/ 150 * https://gnu.org/software/automake/
146 * https://github.com/jedisct1/libsodium 151 * https://github.com/jedisct1/libsodium
147 * http://check.sourceforge.net/ 152 * http://check.sourceforge.net/
153 * http://yasm.tortall.net/Download.html
154 * https://code.google.com/p/webm/downloads/list
155 * http://www.opus-codec.org/downloads/
156 * http://www.freedesktop.org/wiki/Software/pkg-config/
157
158You must install yasm before installing libvpx, otherwise libvpx will fail to make correctly.
159
160pkg-config is important for enabling a/v support in tox core, failure to install pkg-config will prevent tox core form finding the required libopus/libvpx libraries. (pkg-config may not configure properly, if you get an error about GLIB, run configure with the following parameter, --with-internal-glib).
148 161
149Uncompress and install them all. Make sure to follow the README as the instructions change, but they all follow the same pattern below: 162Uncompress and install them all. Make sure to follow the README as the instructions change, but they all follow the same pattern below:
150 163
@@ -154,9 +167,8 @@ make
154sudo make install 167sudo make install
155``` 168```
156 169
157In your local TOX repository: 170Compiling and installing Tox Core
158 171
159Then generate makefile, build and install tox:
160```bash 172```bash
161cd ProjectTox-Core 173cd ProjectTox-Core
162autoreconf -i 174autoreconf -i
@@ -165,36 +177,210 @@ make
165make install 177make install
166``` 178```
167 179
168Do not install them from macports (or any dependencies for that matter) as they get shoved in the wrong directory 180If after running ./configure you get an error about core being unable to find libsodium (and you have installed it) run the following in place of ./configure;
169(or the wrong version gets installed) and make your life more annoying. 181
182./configure --with-libsodium-headers=/usr/local/include/ --with-libsodium-libs=/usr/local/lib
183
184Ensure you set the locations correctly depending on where you installed libsodium on your computer.
185
186If there is a problem with opus (for A/V) and you don't get a libtoxav, then try to set the pkg-config environment variable beforehand:
170 187
171Another thing: you may want to install is the latest gcc. This caused me a few problems as XCode from 4.3 188```
172no longer includes gcc and instead uses LLVM-GCC, a nice install guide can be found at 189export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
173http://caiustheory.com/install-gcc-421-apple-build-56663-with-xcode-42 190```
174 191
175<a name="windows" /> 192<a name="windows" />
176###Windows: 193###Windows:
177 194
195<a name="windows-cross-compile" />
196
197####Cross-compile
198
199It's a bit challenging to build Tox and all of its dependencies nativly on Windows, so we will show an easier, less error and headache prone method of building it -- cross-compiling.
200
201<a name="windows-cross-compile-vm" />
202#####Setting up a VM
203
204We will assume that you don't have any VM running Linux around and will guide you from the ground up.
205
206First, you would need to get a virtual machine and a Linux distribution image file.
207
208For a virtual machine we will use VirtualBox. You can get it [here](https://www.virtualbox.org/wiki/Downloads).
209
210For a Linux distribution we will use Lubuntu 14.04 32-bit, which you can get [here](https://help.ubuntu.com/community/Lubuntu/GetLubuntu).
211
212After you have those downloaded, install the VirtualBox and create a VM in it. The default of 512mb of RAM and 8gb of dynamically-allocated virtual hard drive would be enough.
213
214When you have created the VM, go into its **Settings** -> **System** -> **Processor** and add some cores, if you have any additional available, for faster builds.
215
216Then, go to **Settings** -> **Storage**, click on **Empty** under **Controller: IDE**, click on the little disc icon on the right side of the window, click on **Choose a virtual CD/DVD disk file** and select the downloaded Lubuntu image file.
217
218Start the VM and follow the installation instructions.
219
220After Lubuntu is installed and you have booted into it, in VirtualBox menu on top of the window select **Devices** -> **Insert Guest Additions CD image...**.
221
222Open terminal from **Lubuntu's menu** -> **Accessories**.
223
224Execute:
225```bash
226sudo apt-get update
227sudo apt-get install build-essential -y
228cd /media/*/*/
229sudo ./VBoxLinuxAdditions.run
230```
231
232After that, create a folder called `toxbuild` somewhere on your Windows system. The go to **Devices** -> **Shared Folders Settings...** in the VirtualBox menu, add the `toxbuild` folder there and set **Auto-mount** and **Make Permanent** options.
233
234Execute:
235```bash
236sudo adduser `whoami` vboxsf
237```
238Note the use of a [grave accent](http://en.wikipedia.org/wiki/Grave_accent) instead of an apostrophe.
239
240Then just reboot the system with:
241```bash
242sudo reboot
243```
244
245After the system is booted, go to **Devices** -> **Shared Clipboard** and select **Bidirectional**. Now you will be able to copy-paste text between the host and the guest systems.
246
247Now that the virtual machine is all set up, let's move to getting build dependencies and setting up environment variables.
248
249<a name="windows-cross-compile-environment" />
250#####Setting up the environment
251
252First we will install all tools that we would need for building:
253```bash
254sudo apt-get install build-essential libtool autotools-dev automake checkinstall check git yasm pkg-config mingw-w64 -y
255```
256
257Then we will define a few variables, **depending on which you will build either 32-bit or 64-bit Tox**.
258
259For 32-bit Tox build, do:
260```bash
261WINDOWS_TOOLCHAIN=i686-w64-mingw32
262LIB_VPX_TARGET=x86-win32-gcc
263```
264
265For 64-bit Tox build, do:
266```bash
267WINDOWS_TOOLCHAIN=x86_64-w64-mingw32
268LIB_VPX_TARGET=x86_64-win64-gcc
269```
270
271This is the only difference between 32-bit and 64-bit build procedures.
272
273For speeding up the build process do:
274```
275MAKEFLAGS=j$(nproc)
276export MAKEFLAGS
277```
278
279And let's make a folder where we will be building everything at
280```bash
281cd ~
282mkdir prefix
283cd prefix
284PREFIX_DIR=$(pwd)
285cd ..
286mkdir build
287cd build
288```
289
290<a name="windows-cross-compile-compiling" />
291#####Compiling
292
293Now we will build libraries needed for audio/video: VPX and Opus.
294
295VPX:
296```bash
297git clone http://git.chromium.org/webm/libvpx.git
298cd libvpx
299git checkout tags/v1.3.0
300CROSS="$WINDOWS_TOOLCHAIN"- ./configure --target="$LIB_VPX_TARGET" --prefix="$PREFIX_DIR" --disable-examples --disable-unit-tests --disable-shared --enable-static
301make
302make install
303cd ..
304```
305
306Opus:
307```bash
308wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz
309tar -xf opus-1.1.tar.gz
310cd opus-1.1
311./configure --host="$WINDOWS_TOOLCHAIN" --prefix="$PREFIX_DIR" --disable-extra-programs --disable-doc --disable-shared --enable-static
312make
313make install
314cd ..
315```
316
317Now we will build sodium crypto library:
318```bash
319git clone https://github.com/jedisct1/libsodium/
320cd libsodium
321git checkout tags/0.4.5
322./autogen.sh
323./configure --host="$WINDOWS_TOOLCHAIN" --prefix="$PREFIX_DIR" --disable-shared --enable-static
324make
325make install
326cd ..
327```
328
329And finally we will build Tox:
330```bash
331git clone https://github.com/irungentoo/toxcore
332cd toxcore
333./autogen.sh
334./configure --host="$WINDOWS_TOOLCHAIN" --prefix="$PREFIX_DIR" --disable-ntox --disable-tests --disable-testing --with-dependency-search="$PREFIX_DIR" --disable-shared --enable-static
335make
336make install
337cd ..
338```
339
340Then we make Tox shared library:
341```bash
342cd "$PREFIX_DIR"
343mkdir tmp
344cd tmp
345$WINDOWS_TOOLCHAIN-ar x ../lib/libtoxcore.a
346$WINDOWS_TOOLCHAIN-ar x ../lib/libtoxav.a
347$WINDOWS_TOOLCHAIN-ar x ../lib/libtoxdns.a
348$WINDOWS_TOOLCHAIN-gcc -Wl,--export-all-symbols -Wl,--out-implib=libtox.dll.a -shared -o libtox.dll *.o ../lib/*.a /usr/$WINDOWS_TOOLCHAIN/lib/libwinpthread.a -lws2_32 -static-libgcc
349```
350
351And we will copy it over to the `toxbuild` directory:
352```bash
353mkdir -p /media/sf_toxbuild/release/lib
354mv libtox.dll* /media/sf_toxbuild/release/lib
355mkdir -p /media/sf_toxbuild/release/include
356mv ../include/tox /media/sf_toxbuild/release/include
357```
358
359That's it. Now you should have `release/lib/libtox.dll` and `release/include/tox/<headers>` in your `toxbuild` directory on the Windows system.
360
361<a name="windows-native" />
362####Native
363
364Note that the Native instructions are incomplete, in a sense that they miss instructions needed for adding audio/video support to Tox. You also might stumble upon some unknown MinGW+msys issues while trying to build it.
365
178You should install: 366You should install:
179 - [MinGW](http://sourceforge.net/projects/mingw/) 367 - [MinGW](http://sourceforge.net/projects/mingw/)
180 368
181When installing MinGW, make sure to select the MSYS option in the installer. 369When installing MinGW, make sure to select the MSYS option in the installer.
182MinGW will install an "MinGW shell" (you should get a shortcut for it), make 370MinGW will install an "MinGW shell" (you should get a shortcut for it), make sure to perform all operations (i.e., generating/running configure script, compiling, etc.) from the MinGW shell.
183sure to perform all operations (i.e., generating/running configure script, compiling, etc.) from the MinGW shell.
184 371
185First download the source tarball from https://download.libsodium.org/libsodium/releases/ and build it. 372First download the source tarball from https://download.libsodium.org/libsodium/releases/ and build it.
186Assuming that you got the libsodium-0.4.2.tar.gz release: 373Assuming that you got the libsodium-0.5.0.tar.gz release:
187```cmd 374```cmd
188tar -zxvf libsodium-0.4.2.tar.gz 375tar -zxvf libsodium-0.5.0.tar.gz
189cd libsodium-0.4.2 376cd libsodium-0.5.0
190./configure 377./configure
191make 378make
192make install 379make install
193cd .. 380cd ..
194``` 381```
195 382
196You can also use a precompiled win32 binary of libsodium, however you will have 383You can also use a precompiled win32 binary of libsodium, however you will have to place the files in places where they can be found, i.e., dll's go to /bin headers to /include and libraries to /lib directories in your MinGW shell.
197to place the files in places where they can be found, i.e., dll's go to /bin headers to /include and libraries to /lib directories in your MinGW shell.
198 384
199Next, install ProjectTox-Core library, should either clone this repo by using git, or just download a [zip of current Master branch](https://github.com/irungentoo/ProjectTox-Core/archive/master.zip) and extract it somewhere. 385Next, install ProjectTox-Core library, should either clone this repo by using git, or just download a [zip of current Master branch](https://github.com/irungentoo/ProjectTox-Core/archive/master.zip) and extract it somewhere.
200 386
@@ -334,4 +520,3 @@ Install on ubuntu:
334```bash 520```bash
335sudo apt-get install ncurses-dev 521sudo apt-get install ncurses-dev
336``` 522```
337
diff --git a/README.md b/README.md
index 853a747d..ff3a6bba 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,21 @@
1![Project Tox](https://raw.github.com/irungentoo/ProjectTox-Core/master/other/tox.png "Project Tox") 1![Project Tox](https://raw.github.com/irungentoo/toxcore/master/other/tox.png "Project Tox")
2*** 2***
3 3
4With the rise of governmental monitoring programs, Tox, a FOSS initiative, aims to be an easy to use, all-in-one communication platform that ensures their users full privacy and secure message delivery.<br /> <br /> 4With the rise of governmental monitoring programs, Tox, a FOSS initiative, aims to be an easy to use, all-in-one communication platform that ensures their users full privacy and secure message delivery.<br /> <br />
5 5
6[**Website**](https://tox.im) **|** [**Wiki**](http://wiki.tox.im/) **|** [**Blog**](https://blog.libtoxcore.so/) **|** [**FAQ**](http://wiki.tox.im/FAQ) **|** [**Binaries**](http://download.tox.im/) **|** [**Clients**](http://wiki.tox.im/Client) **|** [**Compiling**](http://wiki.tox.im/Installing) **|** [**API**](http://api.libtoxcore.so/) **|** [**Qt-GUI**](https://github.com/nurupo/ProjectTox-Qt-GUI) **|** **IRC:** #tox@freenode 6[**Website**](https://tox.im) **|** [**Download**](https://wiki.tox.im/Binaries) **|** [**Wiki**](https://wiki.tox.im/) **|** [**Blog**](https://blog.libtoxcore.so/) **|** [**FAQ**](http://wiki.tox.im/FAQ) **|** [**Binaries**](https://wiki.tox.im/Binaries) **|** [**Clients**](https://wiki.tox.im/Client) **|** [**Compiling**](https://wiki.tox.im/Installing) **|** [**API**](https://libtoxcore.so/) **|** **IRC:** #tox@freenode
7 7
8 8
9## The Complex Stuff: 9## The Complex Stuff:
10### UDP vs. TCP 10### UDP vs. TCP
11Tox must use UDP simply because [hole punching](http://en.wikipedia.org/wiki/UDP_hole_punching) with TCP is not as reliable. 11Tox must use UDP simply because [hole punching](https://en.wikipedia.org/wiki/UDP_hole_punching) with TCP is not as reliable.
12However, Tox does use [TCP relays](https://github.com/irungentoo/ProjectTox-Core/blob/master/docs/TCP_Network.txt) as a fallback if it encounters a firewall that prevents UDP hole punching. 12However, Tox does use [TCP relays](https://github.com/irungentoo/ProjectTox-Core/blob/master/docs/TCP_Network.txt) as a fallback if it encounters a firewall that prevents UDP hole punching.
13 13
14### Connecting & Communicating 14### Connecting & Communicating
15Every peer is represented as a [byte string][String] (the public key [Tox ID] of the peer). By using torrent-style DHT, peers can find the IP of other peers by using their Tox ID. Once the IP is obtained, peers can initiate a [secure](https://github.com/irungentoo/ProjectTox-Core/wiki/Crypto) connection with each other. Once the connection is made, peers can exchange messages, send files, start video chats, etc. using encrypted communications. 15Every peer is represented as a [byte string][String] (the public key [Tox ID] of the peer). By using torrent-style DHT, peers can find the IP of other peers by using their Tox ID. Once the IP is obtained, peers can initiate a [secure](https://github.com/irungentoo/toxcore/wiki/Crypto) connection with each other. Once the connection is made, peers can exchange messages, send files, start video chats, etc. using encrypted communications.
16 16
17 17
18**Current build status:** [![Build Status](https://travis-ci.org/irungentoo/ProjectTox-Core.png?branch=master)](https://travis-ci.org/irungentoo/ProjectTox-Core) 18**Current build status:** [![Build Status](https://travis-ci.org/irungentoo/toxcore.png?branch=master)](https://travis-ci.org/irungentoo/toxcore)
19 19
20 20
21## Q&A: 21## Q&A:
@@ -33,10 +33,10 @@ The goal of this project is to create a configuration-free P2P Skype replacement
33 33
34## Documentation: 34## Documentation:
35 35
36- [Installation](/INSTALL.md) 36- [Compiling](/INSTALL.md)
37- [DHT Protocol](http://wiki.tox.im/index.php/DHT)<br /> 37- [DHT Protocol](https://wiki.tox.im/index.php/DHT)<br />
38- [Lossless UDP Protocol](http://wiki.tox.im/index.php/Lossless_UDP)<br /> 38- [Lossless UDP Protocol](https://wiki.tox.im/index.php/Lossless_UDP)<br />
39- [Crypto](http://wiki.tox.im/index.php/Crypto)<br /> 39- [Crypto](https://wiki.tox.im/index.php/Crypto)<br />
40- [Ideas](http://wiki.tox.im/index.php/Ideas) 40- [Ideas](https://wiki.tox.im/index.php/Ideas)
41 41
42[String]: https://en.wikipedia.org/wiki/String_(computer_science) 42[String]: https://en.wikipedia.org/wiki/String_(computer_science)
diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c
index ca5afd9a..8e75fae0 100644
--- a/auto_tests/TCP_test.c
+++ b/auto_tests/TCP_test.c
@@ -294,7 +294,7 @@ END_TEST
294static int response_callback_good; 294static int response_callback_good;
295static uint8_t response_callback_connection_id; 295static uint8_t response_callback_connection_id;
296static uint8_t response_callback_public_key[crypto_box_PUBLICKEYBYTES]; 296static uint8_t response_callback_public_key[crypto_box_PUBLICKEYBYTES];
297static int response_callback(void *object, uint8_t connection_id, uint8_t *public_key) 297static int response_callback(void *object, uint8_t connection_id, const uint8_t *public_key)
298{ 298{
299 if (set_tcp_connection_number(object - 2, connection_id, 7) != 0) 299 if (set_tcp_connection_number(object - 2, connection_id, 7) != 0)
300 return 1; 300 return 1;
@@ -321,7 +321,7 @@ static int status_callback(void *object, uint32_t number, uint8_t connection_id,
321 return 0; 321 return 0;
322} 322}
323static int data_callback_good; 323static int data_callback_good;
324static int data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length) 324static int data_callback(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length)
325{ 325{
326 if (object != (void *)3) 326 if (object != (void *)3)
327 return 1; 327 return 1;
@@ -342,7 +342,7 @@ static int data_callback(void *object, uint32_t number, uint8_t connection_id, u
342 342
343static int oob_data_callback_good; 343static int oob_data_callback_good;
344static uint8_t oob_pubkey[crypto_box_PUBLICKEYBYTES]; 344static uint8_t oob_pubkey[crypto_box_PUBLICKEYBYTES];
345static int oob_data_callback(void *object, uint8_t *public_key, uint8_t *data, uint16_t length) 345static int oob_data_callback(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length)
346{ 346{
347 if (object != (void *)4) 347 if (object != (void *)4)
348 return 1; 348 return 1;
diff --git a/auto_tests/tox_test.c b/auto_tests/tox_test.c
index f8da8560..1a3c5868 100644
--- a/auto_tests/tox_test.c
+++ b/auto_tests/tox_test.c
@@ -30,7 +30,7 @@ void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *dat
30} 30}
31uint32_t messages_received; 31uint32_t messages_received;
32 32
33void print_message(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) 33void print_message(Tox *m, int friendnumber, const uint8_t *string, uint16_t length, void *userdata)
34{ 34{
35 if (*((uint32_t *)userdata) != 974536) 35 if (*((uint32_t *)userdata) != 974536)
36 return; 36 return;
@@ -44,7 +44,7 @@ void print_message(Tox *m, int friendnumber, uint8_t *string, uint16_t length, v
44 44
45uint32_t name_changes; 45uint32_t name_changes;
46 46
47void print_nickchange(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) 47void print_nickchange(Tox *m, int friendnumber, const uint8_t *string, uint16_t length, void *userdata)
48{ 48{
49 if (*((uint32_t *)userdata) != 974536) 49 if (*((uint32_t *)userdata) != 974536)
50 return; 50 return;
@@ -69,7 +69,7 @@ void print_typingchange(Tox *m, int friendnumber, uint8_t typing, void *userdata
69uint8_t filenum; 69uint8_t filenum;
70uint32_t file_accepted; 70uint32_t file_accepted;
71uint64_t file_size; 71uint64_t file_size;
72void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, 72void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, const uint8_t *filename,
73 uint16_t filename_length, void *userdata) 73 uint16_t filename_length, void *userdata)
74{ 74{
75 if (*((uint32_t *)userdata) != 974536) 75 if (*((uint32_t *)userdata) != 974536)
@@ -85,7 +85,7 @@ void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t
85uint32_t file_sent; 85uint32_t file_sent;
86uint32_t sendf_ok; 86uint32_t sendf_ok;
87void file_print_control(Tox *m, int friendnumber, uint8_t send_recieve, uint8_t filenumber, uint8_t control_type, 87void file_print_control(Tox *m, int friendnumber, uint8_t send_recieve, uint8_t filenumber, uint8_t control_type,
88 uint8_t *data, uint16_t length, void *userdata) 88 const uint8_t *data, uint16_t length, void *userdata)
89{ 89{
90 if (*((uint32_t *)userdata) != 974536) 90 if (*((uint32_t *)userdata) != 974536)
91 return; 91 return;
@@ -100,7 +100,7 @@ void file_print_control(Tox *m, int friendnumber, uint8_t send_recieve, uint8_t
100 100
101uint64_t size_recv; 101uint64_t size_recv;
102uint8_t num; 102uint8_t num;
103void write_file(Tox *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) 103void write_file(Tox *m, int friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length, void *userdata)
104{ 104{
105 if (*((uint32_t *)userdata) != 974536) 105 if (*((uint32_t *)userdata) != 974536)
106 return; 106 return;
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c
index ce3185de..bf130ecb 100644
--- a/auto_tests/toxav_basic_test.c
+++ b/auto_tests/toxav_basic_test.c
@@ -138,6 +138,15 @@ void callback_requ_timeout ( int32_t call_index, void *_arg )
138{ 138{
139 ck_assert_msg(0, "No answer!"); 139 ck_assert_msg(0, "No answer!");
140} 140}
141
142static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int length)
143{
144}
145
146static void callback_video(ToxAv *av, int32_t call_index, vpx_image_t *img)
147{
148}
149
141/*************************************************************************************************/ 150/*************************************************************************************************/
142 151
143/* Alice calls bob and the call starts. 152/* Alice calls bob and the call starts.
@@ -199,7 +208,7 @@ START_TEST(test_AV_flows)
199 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time); 208 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time);
200 209
201 muhcaps = av_DefaultSettings; 210 muhcaps = av_DefaultSettings;
202 muhcaps.video_height = muhcaps.video_width = 128; 211 muhcaps.max_video_height = muhcaps.max_video_width = 128;
203 212
204 Status status_control = { 213 Status status_control = {
205 {none, toxav_new(Alice, 1), NULL, -1}, 214 {none, toxav_new(Alice, 1), NULL, -1},
@@ -222,6 +231,10 @@ START_TEST(test_AV_flows)
222 toxav_register_callstate_callback(callback_recv_error, av_OnError, &status_control); 231 toxav_register_callstate_callback(callback_recv_error, av_OnError, &status_control);
223 toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control); 232 toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control);
224 233
234 toxav_register_audio_recv_callback(status_control.Alice.av, callback_audio);
235 toxav_register_video_recv_callback(status_control.Alice.av, callback_video);
236 toxav_register_audio_recv_callback(status_control.Bob.av, callback_audio);
237 toxav_register_video_recv_callback(status_control.Bob.av, callback_video);
225 238
226 const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000); 239 const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000);
227 int16_t sample_payload[frame_size]; 240 int16_t sample_payload[frame_size];
@@ -267,21 +280,22 @@ START_TEST(test_AV_flows)
267 toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); 280 toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size);
268 281
269 /* Both receive */ 282 /* Both receive */
270 int16_t storage[frame_size]; 283 /*int16_t storage[frame_size];
271 int recved; 284 int recved;
272 285
273 /* Payload from Bob */ 286 /* Payload from Bob */
274 recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage); 287
288 /*recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage);
275 289
276 if ( recved ) { 290 if ( recved ) {
277 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/ 291 //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");
278 } 292 }
279 293
280 recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage); 294 recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage);
281 295
282 if ( recved ) { 296 if ( recved ) {
283 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/ 297 //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");
284 } 298 }*/
285 299
286 if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ 300 if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
287 step++; /* This terminates the loop */ 301 step++; /* This terminates the loop */
@@ -317,6 +331,7 @@ START_TEST(test_AV_flows)
317 } 331 }
318 332
319 toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); 333 toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size);
334
320// toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image); 335// toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image);
321 336
322 /* Both receive */ 337 /* Both receive */
@@ -325,11 +340,11 @@ START_TEST(test_AV_flows)
325 int recved; 340 int recved;
326 341
327 /* Payload from Bob */ 342 /* Payload from Bob */
328 recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage); 343 /*recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage);
329 344
330 if ( recved ) { 345 if ( recved ) {
331 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/ 346 //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");
332 } 347 }*/
333 348
334 /* Video payload */ 349 /* Video payload */
335// toxav_recv_video(status_control.Alice.av, status_control.Alice.call_index, &video_storage); 350// toxav_recv_video(status_control.Alice.av, status_control.Alice.call_index, &video_storage);
@@ -345,11 +360,11 @@ START_TEST(test_AV_flows)
345 360
346 361
347 /* Payload from Alice */ 362 /* Payload from Alice */
348 recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage); 363 /*recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage);
349 364
350 if ( recved ) { 365 if ( recved ) {
351 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/ 366 //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");
352 } 367 }*/
353 368
354 if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ 369 if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
355 step++; /* This terminates the loop */ 370 step++; /* This terminates the loop */
@@ -396,11 +411,11 @@ START_TEST(test_AV_flows)
396 int recved; 411 int recved;
397 412
398 /* Payload from Bob */ 413 /* Payload from Bob */
399 recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage); 414 /*recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage);
400 415
401 if ( recved ) { 416 if ( recved ) {
402 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/ 417 //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");
403 } 418 }*/
404 419
405 /* Video payload */ 420 /* Video payload */
406// toxav_recv_video(status_control.Alice.av, status_control.Alice.call_index, &video_storage); 421// toxav_recv_video(status_control.Alice.av, status_control.Alice.call_index, &video_storage);
@@ -416,11 +431,11 @@ START_TEST(test_AV_flows)
416 431
417 432
418 /* Payload from Alice */ 433 /* Payload from Alice */
419 recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage); 434 /*recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage);
420 435
421 if ( recved ) { 436 if ( recved ) {
422 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/ 437 ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");
423 } 438 }*/
424 439
425 /* Video payload */ 440 /* Video payload */
426// toxav_recv_video(status_control.Bob.av, status_control.Bob.call_index, &video_storage); 441// toxav_recv_video(status_control.Bob.av, status_control.Bob.call_index, &video_storage);
diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c
index 2a931cb0..3195d1ed 100644
--- a/auto_tests/toxav_many_test.c
+++ b/auto_tests/toxav_many_test.c
@@ -24,6 +24,7 @@
24#define c_sleep(x) usleep(1000*x) 24#define c_sleep(x) usleep(1000*x)
25#endif 25#endif
26 26
27pthread_mutex_t muhmutex;
27 28
28typedef enum _CallStatus { 29typedef enum _CallStatus {
29 none, 30 none,
@@ -124,6 +125,14 @@ void callback_requ_timeout ( int32_t call_index, void *_arg )
124{ 125{
125 ck_assert_msg(0, "No answer!"); 126 ck_assert_msg(0, "No answer!");
126} 127}
128
129static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int length)
130{
131}
132
133static void callback_video(ToxAv *av, int32_t call_index, vpx_image_t *img)
134{
135}
127/*************************************************************************************************/ 136/*************************************************************************************************/
128 137
129 138
@@ -142,6 +151,11 @@ void *in_thread_call (void *arg)
142 151
143 uint8_t prepared_payload[RTP_PAYLOAD_SIZE]; 152 uint8_t prepared_payload[RTP_PAYLOAD_SIZE];
144 153
154 toxav_register_audio_recv_callback(this_call->Caller.av, callback_audio);
155 toxav_register_video_recv_callback(this_call->Caller.av, callback_video);
156 toxav_register_audio_recv_callback(this_call->Callee.av, callback_audio);
157 toxav_register_video_recv_callback(this_call->Callee.av, callback_video);
158
145 159
146 /* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */ 160 /* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */
147 while (running) { 161 while (running) {
@@ -192,26 +206,28 @@ void *in_thread_call (void *arg)
192 int recved; 206 int recved;
193 207
194 /* Payload from CALLER */ 208 /* Payload from CALLER */
195 recved = toxav_recv_audio(this_call->Callee.av, 0, frame_size, storage); 209 /*recved = toxav_recv_audio(this_call->Callee.av, 0, frame_size, storage);
196 210
197 if ( recved ) { 211 if ( recved ) {
198 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLER is invalid");*/ 212 //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLER is invalid");
199 } 213 }*/
200 214
201 /* Payload from CALLEE */ 215 /* Payload from CALLEE */
202 recved = toxav_recv_audio(this_call->Caller.av, call_idx, frame_size, storage); 216 /*recved = toxav_recv_audio(this_call->Caller.av, call_idx, frame_size, storage);
203 217
204 if ( recved ) { 218 if ( recved ) {
205 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLEE is invalid");*/ 219 //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLEE is invalid");
206 } 220 }*/
207 221
208 c_sleep(20); 222 c_sleep(20);
209 } 223 }
210 224
211 step++; /* This terminates the loop */ 225 step++; /* This terminates the loop */
212 226
227 pthread_mutex_lock(&muhmutex);
213 toxav_kill_transmission(this_call->Callee.av, 0); 228 toxav_kill_transmission(this_call->Callee.av, 0);
214 toxav_kill_transmission(this_call->Caller.av, call_idx); 229 toxav_kill_transmission(this_call->Caller.av, call_idx);
230 pthread_mutex_unlock(&muhmutex);
215 231
216 /* Call over CALLER hangs up */ 232 /* Call over CALLER hangs up */
217 toxav_hangup(this_call->Caller.av, call_idx); 233 toxav_hangup(this_call->Caller.av, call_idx);
@@ -335,6 +351,8 @@ START_TEST(test_AV_three_calls)
335 toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control); 351 toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control);
336 352
337 353
354 pthread_mutex_init(&muhmutex, NULL);
355
338 356
339 for ( i = 0; i < 3; i++ ) 357 for ( i = 0; i < 3; i++ )
340 pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]); 358 pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]);
@@ -350,11 +368,15 @@ START_TEST(test_AV_three_calls)
350 status_control.calls[1].Callee.status != Ended && status_control.calls[1].Caller.status != Ended && 368 status_control.calls[1].Callee.status != Ended && status_control.calls[1].Caller.status != Ended &&
351 status_control.calls[2].Callee.status != Ended && status_control.calls[2].Caller.status != Ended 369 status_control.calls[2].Callee.status != Ended && status_control.calls[2].Caller.status != Ended
352 ) { 370 ) {
371 pthread_mutex_lock(&muhmutex);
372
353 tox_do(bootstrap_node); 373 tox_do(bootstrap_node);
354 tox_do(caller); 374 tox_do(caller);
355 tox_do(callees[0]); 375 tox_do(callees[0]);
356 tox_do(callees[1]); 376 tox_do(callees[1]);
357 tox_do(callees[2]); 377 tox_do(callees[2]);
378
379 pthread_mutex_unlock(&muhmutex);
358 c_sleep(20); 380 c_sleep(20);
359 } 381 }
360 382
@@ -403,4 +425,4 @@ int main(int argc, char *argv[])
403// test_AV_three_calls(); 425// test_AV_three_calls();
404// 426//
405// return 0; 427// return 0;
406} \ No newline at end of file 428}
diff --git a/docs/TODO b/docs/TODO
index fc50d566..966a1b5f 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -24,8 +24,8 @@ Lossless UDP:
24 [DONE] Call initiation 24 [DONE] Call initiation
25 [DONE] Encryption 25 [DONE] Encryption
26 [IN PROGRESS] Auditing. 26 [IN PROGRESS] Auditing.
27 [NOT STARTED] Video packet splitting. 27 [NEEDS TESTING] Video packet splitting.
28 [NOT STARTED] Prevent audio skew. 28 [IN PROGRESS] Prevent audio skew (seems to be easily solvable client side.)
29 [IN PROGRESS] Group chats. 29 [IN PROGRESS] Group chats.
30 30
31Friend_requests.c: 31Friend_requests.c:
diff --git a/other/bootstrap_daemon/tox_bootstrap_daemon.c b/other/bootstrap_daemon/tox_bootstrap_daemon.c
index ceb4fded..5f8f9f76 100644
--- a/other/bootstrap_daemon/tox_bootstrap_daemon.c
+++ b/other/bootstrap_daemon/tox_bootstrap_daemon.c
@@ -91,6 +91,7 @@ int manage_keys(DHT *dht, char *keys_file_path)
91 size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file); 91 size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
92 92
93 if (read_size != KEYS_SIZE) { 93 if (read_size != KEYS_SIZE) {
94 fclose(keys_file);
94 return 0; 95 return 0;
95 } 96 }
96 97
@@ -106,6 +107,7 @@ int manage_keys(DHT *dht, char *keys_file_path)
106 size_t write_size = fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file); 107 size_t write_size = fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
107 108
108 if (write_size != KEYS_SIZE) { 109 if (write_size != KEYS_SIZE) {
110 fclose(keys_file);
109 return 0; 111 return 0;
110 } 112 }
111 } 113 }
@@ -147,8 +149,11 @@ void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_ports, int
147 for (i = 0; i < DEFAULT_TCP_RELAY_PORTS_COUNT; i ++) { 149 for (i = 0; i < DEFAULT_TCP_RELAY_PORTS_COUNT; i ++) {
148 150
149 (*tcp_relay_ports)[*tcp_relay_port_count] = default_ports[i]; 151 (*tcp_relay_ports)[*tcp_relay_port_count] = default_ports[i];
150 if ((*tcp_relay_ports)[*tcp_relay_port_count] < MIN_ALLOWED_PORT || (*tcp_relay_ports)[*tcp_relay_port_count] > MAX_ALLOWED_PORT) { 152
151 syslog(LOG_WARNING, "Port #%d: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i, (*tcp_relay_ports)[*tcp_relay_port_count], MIN_ALLOWED_PORT, MAX_ALLOWED_PORT); 153 if ((*tcp_relay_ports)[*tcp_relay_port_count] < MIN_ALLOWED_PORT
154 || (*tcp_relay_ports)[*tcp_relay_port_count] > MAX_ALLOWED_PORT) {
155 syslog(LOG_WARNING, "Port #%d: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i,
156 (*tcp_relay_ports)[*tcp_relay_port_count], MIN_ALLOWED_PORT, MAX_ALLOWED_PORT);
152 continue; 157 continue;
153 } 158 }
154 159
@@ -162,11 +167,13 @@ void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_ports, int
162 } 167 }
163 168
164 if (config_setting_is_array(ports_array) == CONFIG_FALSE) { 169 if (config_setting_is_array(ports_array) == CONFIG_FALSE) {
165 syslog(LOG_WARNING, "'%s' setting should be an array. Array syntax: 'setting = [value1, value2, ...]'.\n", NAME_TCP_RELAY_PORTS); 170 syslog(LOG_WARNING, "'%s' setting should be an array. Array syntax: 'setting = [value1, value2, ...]'.\n",
171 NAME_TCP_RELAY_PORTS);
166 return; 172 return;
167 } 173 }
168 174
169 int config_port_count = config_setting_length(ports_array); 175 int config_port_count = config_setting_length(ports_array);
176
170 if (config_port_count == 0) { 177 if (config_port_count == 0) {
171 syslog(LOG_WARNING, "'%s' is empty.\n", NAME_TCP_RELAY_PORTS); 178 syslog(LOG_WARNING, "'%s' is empty.\n", NAME_TCP_RELAY_PORTS);
172 return; 179 return;
@@ -174,12 +181,10 @@ void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_ports, int
174 181
175 *tcp_relay_ports = malloc(config_port_count * sizeof(uint16_t)); 182 *tcp_relay_ports = malloc(config_port_count * sizeof(uint16_t));
176 183
177 config_setting_t *elem;
178 int i; 184 int i;
179 185
180 for (i = 0; i < config_port_count; i ++) { 186 for (i = 0; i < config_port_count; i ++) {
181 187 config_setting_t *elem = config_setting_get_elem(ports_array, i);
182 elem = config_setting_get_elem(ports_array, i);
183 188
184 if (elem == NULL) { 189 if (elem == NULL) {
185 // it's NULL if `ports_array` is not an array (we have that check ealier) or if `i` is out of range, which should not be 190 // it's NULL if `ports_array` is not an array (we have that check ealier) or if `i` is out of range, which should not be
@@ -193,8 +198,11 @@ void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_ports, int
193 } 198 }
194 199
195 (*tcp_relay_ports)[*tcp_relay_port_count] = config_setting_get_int(elem); 200 (*tcp_relay_ports)[*tcp_relay_port_count] = config_setting_get_int(elem);
196 if ((*tcp_relay_ports)[*tcp_relay_port_count] < MIN_ALLOWED_PORT || (*tcp_relay_ports)[*tcp_relay_port_count] > MAX_ALLOWED_PORT) { 201
197 syslog(LOG_WARNING, "Port #%d: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i, (*tcp_relay_ports)[*tcp_relay_port_count], MIN_ALLOWED_PORT, MAX_ALLOWED_PORT); 202 if ((*tcp_relay_ports)[*tcp_relay_port_count] < MIN_ALLOWED_PORT
203 || (*tcp_relay_ports)[*tcp_relay_port_count] > MAX_ALLOWED_PORT) {
204 syslog(LOG_WARNING, "Port #%d: Invalid port: %u, should be in [%d, %d]. Skipping.\n", i,
205 (*tcp_relay_ports)[*tcp_relay_port_count], MIN_ALLOWED_PORT, MAX_ALLOWED_PORT);
198 continue; 206 continue;
199 } 207 }
200 208
@@ -315,6 +323,7 @@ int get_general_config(char *cfg_file_path, char **pid_file_path, char **keys_fi
315 syslog(LOG_WARNING, "Using default '%s': %s\n", NAME_MOTD, DEFAULT_MOTD); 323 syslog(LOG_WARNING, "Using default '%s': %s\n", NAME_MOTD, DEFAULT_MOTD);
316 tmp_motd = DEFAULT_MOTD; 324 tmp_motd = DEFAULT_MOTD;
317 } 325 }
326
318 size_t tmp_motd_length = strlen(tmp_motd) + 1; 327 size_t tmp_motd_length = strlen(tmp_motd) + 1;
319 size_t motd_length = tmp_motd_length > MAX_MOTD_LENGTH ? MAX_MOTD_LENGTH : tmp_motd_length; 328 size_t motd_length = tmp_motd_length > MAX_MOTD_LENGTH ? MAX_MOTD_LENGTH : tmp_motd_length;
320 *motd = malloc(motd_length); 329 *motd = malloc(motd_length);
@@ -332,6 +341,7 @@ int get_general_config(char *cfg_file_path, char **pid_file_path, char **keys_fi
332 syslog(LOG_DEBUG, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false"); 341 syslog(LOG_DEBUG, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false");
333 342
334 syslog(LOG_DEBUG, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay ? "true" : "false"); 343 syslog(LOG_DEBUG, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay ? "true" : "false");
344
335 // show info about tcp ports only if tcp relay is enabled 345 // show info about tcp ports only if tcp relay is enabled
336 if (*enable_tcp_relay) { 346 if (*enable_tcp_relay) {
337 if (*tcp_relay_port_count == 0) { 347 if (*tcp_relay_port_count == 0) {
@@ -339,6 +349,7 @@ int get_general_config(char *cfg_file_path, char **pid_file_path, char **keys_fi
339 } else { 349 } else {
340 syslog(LOG_DEBUG, "Read %d TCP ports:\n", *tcp_relay_port_count); 350 syslog(LOG_DEBUG, "Read %d TCP ports:\n", *tcp_relay_port_count);
341 int i; 351 int i;
352
342 for (i = 0; i < *tcp_relay_port_count; i ++) { 353 for (i = 0; i < *tcp_relay_port_count; i ++) {
343 syslog(LOG_DEBUG, "Port #%d: %u\n", i, (*tcp_relay_ports)[i]); 354 syslog(LOG_DEBUG, "Port #%d: %u\n", i, (*tcp_relay_ports)[i]);
344 } 355 }
@@ -346,6 +357,7 @@ int get_general_config(char *cfg_file_path, char **pid_file_path, char **keys_fi
346 } 357 }
347 358
348 syslog(LOG_DEBUG, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd ? "true" : "false"); 359 syslog(LOG_DEBUG, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd ? "true" : "false");
360
349 if (*enable_motd) { 361 if (*enable_motd) {
350 syslog(LOG_DEBUG, "'%s': %s\n", NAME_MOTD, *motd); 362 syslog(LOG_DEBUG, "'%s': %s\n", NAME_MOTD, *motd);
351 } 363 }
@@ -424,14 +436,15 @@ int bootstrap_from_config(char *cfg_file_path, DHT *dht, int enable_ipv6)
424 } 436 }
425 437
426 // Process settings 438 // Process settings
427 if (strlen(bs_public_key) != crypto_box_PUBLICKEYBYTES*2) { 439 if (strlen(bs_public_key) != crypto_box_PUBLICKEYBYTES * 2) {
428 syslog(LOG_WARNING, "Bootstrap node #%d: Invalid '%s': %s. Skipping the node.\n", i, NAME_PUBLIC_KEY, 440 syslog(LOG_WARNING, "Bootstrap node #%d: Invalid '%s': %s. Skipping the node.\n", i, NAME_PUBLIC_KEY,
429 bs_public_key); 441 bs_public_key);
430 goto next; 442 goto next;
431 } 443 }
432 444
433 if (bs_port < MIN_ALLOWED_PORT || bs_port > MAX_ALLOWED_PORT) { 445 if (bs_port < MIN_ALLOWED_PORT || bs_port > MAX_ALLOWED_PORT) {
434 syslog(LOG_WARNING, "Bootstrap node #%d: Invalid '%s': %d, should be in [%d, %d]. Skipping the node.\n", i, NAME_PORT, bs_port, MIN_ALLOWED_PORT, MAX_ALLOWED_PORT); 446 syslog(LOG_WARNING, "Bootstrap node #%d: Invalid '%s': %d, should be in [%d, %d]. Skipping the node.\n", i, NAME_PORT,
447 bs_port, MIN_ALLOWED_PORT, MAX_ALLOWED_PORT);
435 goto next; 448 goto next;
436 } 449 }
437 450
@@ -464,7 +477,7 @@ next:
464 477
465void print_public_key(uint8_t *public_key) 478void print_public_key(uint8_t *public_key)
466{ 479{
467 char buffer[2*crypto_box_PUBLICKEYBYTES + 1]; 480 char buffer[2 * crypto_box_PUBLICKEYBYTES + 1];
468 int index = 0; 481 int index = 0;
469 482
470 int i; 483 int i;
@@ -500,7 +513,8 @@ int main(int argc, char *argv[])
500 int enable_motd; 513 int enable_motd;
501 char *motd; 514 char *motd;
502 515
503 if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &port, &enable_ipv6, &enable_lan_discovery, &enable_tcp_relay, &tcp_relay_ports, &tcp_relay_port_count, &enable_motd, &motd)) { 516 if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &port, &enable_ipv6, &enable_lan_discovery,
517 &enable_tcp_relay, &tcp_relay_ports, &tcp_relay_port_count, &enable_motd, &motd)) {
504 syslog(LOG_DEBUG, "General config read successfully\n"); 518 syslog(LOG_DEBUG, "General config read successfully\n");
505 } else { 519 } else {
506 syslog(LOG_ERR, "Couldn't read config file: %s. Exiting.\n", cfg_file_path); 520 syslog(LOG_ERR, "Couldn't read config file: %s. Exiting.\n", cfg_file_path);
@@ -513,8 +527,11 @@ int main(int argc, char *argv[])
513 } 527 }
514 528
515 // Check if the PID file exists 529 // Check if the PID file exists
516 if (fopen(pid_file_path, "r")) { 530 FILE *pid_file;
531
532 if (pid_file = fopen(pid_file_path, "r")) {
517 syslog(LOG_ERR, "Another instance of the daemon is already running, PID file %s exists.\n", pid_file_path); 533 syslog(LOG_ERR, "Another instance of the daemon is already running, PID file %s exists.\n", pid_file_path);
534 fclose(pid_file);
518 } 535 }
519 536
520 IP ip; 537 IP ip;
@@ -536,12 +553,13 @@ int main(int argc, char *argv[])
536 } 553 }
537 554
538 if (enable_motd) { 555 if (enable_motd) {
539 if (bootstrap_set_callbacks(dht->net, DAEMON_VERSION_NUMBER, (uint8_t*)motd, strlen(motd) + 1) == 0) { 556 if (bootstrap_set_callbacks(dht->net, DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) {
540 syslog(LOG_DEBUG, "Set MOTD successfully.\n"); 557 syslog(LOG_DEBUG, "Set MOTD successfully.\n");
541 } else { 558 } else {
542 syslog(LOG_ERR, "Couldn't set MOTD: %s. Exiting.\n", motd); 559 syslog(LOG_ERR, "Couldn't set MOTD: %s. Exiting.\n", motd);
543 return 1; 560 return 1;
544 } 561 }
562
545 free(motd); 563 free(motd);
546 } 564 }
547 565
@@ -560,7 +578,8 @@ int main(int argc, char *argv[])
560 return 1; 578 return 1;
561 } 579 }
562 580
563 tcp_server = new_TCP_server(enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht->self_public_key, dht->self_secret_key, onion); 581 tcp_server = new_TCP_server(enable_ipv6, tcp_relay_port_count, tcp_relay_ports, dht->self_public_key,
582 dht->self_secret_key, onion);
564 583
565 // tcp_relay_port_count != 0 at this point 584 // tcp_relay_port_count != 0 at this point
566 free(tcp_relay_ports); 585 free(tcp_relay_ports);
@@ -596,17 +615,18 @@ int main(int argc, char *argv[])
596 // Fork off from the parent process 615 // Fork off from the parent process
597 pid_t pid = fork(); 616 pid_t pid = fork();
598 617
599 if (pid < 0) {
600 fclose(pidf);
601 syslog(LOG_ERR, "Forking failed. Exiting.\n");
602 return 1;
603 }
604
605 if (pid > 0) { 618 if (pid > 0) {
606 fprintf(pidf, "%d ", pid); 619 fprintf(pidf, "%d ", pid);
607 fclose(pidf); 620 fclose(pidf);
608 syslog(LOG_DEBUG, "Forked successfully: PID: %d.\n", pid); 621 syslog(LOG_DEBUG, "Forked successfully: PID: %d.\n", pid);
609 return 0; 622 return 0;
623 } else {
624 fclose(pidf);
625 }
626
627 if (pid < 0) {
628 syslog(LOG_ERR, "Forking failed. Exiting.\n");
629 return 1;
610 } 630 }
611 631
612 // Change the file mode mask 632 // Change the file mode mask
diff --git a/other/fun/cracker.c b/other/fun/cracker.c
index 7b7000de..843b9359 100644
--- a/other/fun/cracker.c
+++ b/other/fun/cracker.c
@@ -17,7 +17,7 @@
17#include <randombytes.h> 17#include <randombytes.h>
18 18
19/* Sodium include*/ 19/* Sodium include*/
20//#include <libsodium.h> 20//#include <sodium.h>
21 21
22void print_key(uint8_t *client_id) 22void print_key(uint8_t *client_id)
23{ 23{
diff --git a/other/fun/sign.c b/other/fun/sign.c
index eaea9d6a..56a9d1e2 100644
--- a/other/fun/sign.c
+++ b/other/fun/sign.c
@@ -36,6 +36,7 @@ int load_file(char *filename, char **result)
36 36
37 if (size != fread(*result, sizeof(char), size, f)) { 37 if (size != fread(*result, sizeof(char), size, f)) {
38 free(*result); 38 free(*result);
39 fclose(f);
39 return -2; // -2 means file reading fail 40 return -2; // -2 means file reading fail
40 } 41 }
41 42
diff --git a/other/fun/strkey.c b/other/fun/strkey.c
new file mode 100644
index 00000000..7e5a1e1c
--- /dev/null
+++ b/other/fun/strkey.c
@@ -0,0 +1,137 @@
1/* strkey -- String in Public Key
2 *
3 * Generates Tox's key pairs, checking if a certain string is in the public key.
4 *
5 * Requires sodium or nacl library.
6 *
7 * There seem to be some problems with the code working on Windows -- it works
8 * when built in debug mode with MinGW 4.8, but it doesn't work correctly when
9 * built in release.
10 *
11 * Usage: strkey <offset> <string>
12 *
13 * Offset - an integer specifying exact byte offset position of the string you
14 * are looking for within a public key. When offset is negative, the program
15 * just looks for the desired string being somewhere, doesn't matter where, in
16 * the public key.
17 *
18 * String - a hex string that you want to have in your public key. It must have
19 * an even number of letters, since every two hexes map to a single byte of
20 * the public key.
21 *
22 * Examples:
23 * strkey 0 0123
24 * Looks for a public key that begins with "0123".
25 *
26 * strkey 1 0123
27 * Looks for a public key that has "0123" starting at its second byte, i.e. "XX0123...".
28 *
29 * strkey 2 0123
30 * Looks for a public key that has "0123" starting at its third byte, i.e. "XXXX0123...".
31 * (each two hexes represent a single byte of a public key)
32 *
33 * strkey -1 AF57CC
34 * Looks for a public key that contains "AF57CC", regardless of its position.
35 *
36 * To compile with gcc and sodium: gcc strkey.c -o strkey -lsodium
37*/
38
39#include <stdio.h>
40#include <string.h>
41
42#include <sodium.h>
43
44#define PRINT_TRIES_COUNT
45
46void print_key(unsigned char *key)
47{
48 size_t i;
49 for (i = 0; i < crypto_box_PUBLICKEYBYTES; i++) {
50 if (key[i] < 16) {
51 fprintf(stdout, "0");
52 }
53
54 fprintf(stdout, "%hhX", key[i]);
55 }
56}
57
58int main(int argc, char *argv[])
59{
60 unsigned char public_key[crypto_box_PUBLICKEYBYTES]; // null terminator
61 unsigned char secret_key[crypto_box_SECRETKEYBYTES];
62 int offset = 0;
63 size_t len;
64 unsigned char desired_bin[crypto_box_PUBLICKEYBYTES]; // null terminator
65
66 if (argc == 3) {
67 offset = atoi(argv[1]);
68 char *desired_hex = argv[2];
69 len = strlen(desired_hex);
70 if (len % 2 != 0) {
71 fprintf(stderr, "Desired key should have an even number of letters\n");
72 exit(1);
73 }
74 size_t block_length = (offset < 0 ? 0 : offset) + len/2;
75 if (block_length > crypto_box_PUBLICKEYBYTES) {
76 fprintf(stderr, "The given key with the given offset exceed public key's length\n");
77 exit(1);
78 }
79
80 // convert hex to bin
81 char *pos = desired_hex;
82 size_t i;
83 for (i = 0; i < len; pos += 2) {
84 sscanf(pos, "%2hhx", &desired_bin[i]);
85 ++i;
86 }
87 } else {
88 fprintf(stdout, "Usage: executable <byte offset> <desired hex string with even number of letters>\n");
89 exit(1);
90 }
91
92 len /= 2;
93
94#ifdef PRINT_TRIES_COUNT
95 long long unsigned int tries = 0;
96#endif
97
98 if (offset < 0) {
99 int found = 0;
100 do {
101#ifdef PRINT_TRIES_COUNT
102 tries ++;
103#endif
104 crypto_box_keypair(public_key, secret_key);
105 int i;
106 for (i = 0; i <= crypto_box_PUBLICKEYBYTES - len; i ++) {
107 if (memcmp(public_key + i, desired_bin, len) == 0) {
108 found = 1;
109 break;
110 }
111 }
112 } while (!found);
113 } else {
114 unsigned char *p = public_key + offset;
115
116 do {
117#ifdef PRINT_TRIES_COUNT
118 tries ++;
119#endif
120 crypto_box_keypair(public_key, secret_key);
121 } while (memcmp(p, desired_bin, len) != 0);
122 }
123
124 fprintf(stdout, "Public key: ");
125 print_key(public_key);
126 fprintf(stdout, "\n");
127
128 fprintf(stdout, "Private key: ");
129 print_key(secret_key);
130 fprintf(stdout, "\n");
131
132#ifdef PRINT_TRIES_COUNT
133 fprintf(stdout, "Found the key pair on %llu try.\n", tries);
134#endif
135
136 return 0;
137}
diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c
index 7c1d64e7..905bcef4 100644
--- a/testing/Messenger_test.c
+++ b/testing/Messenger_test.c
@@ -56,7 +56,7 @@
56 56
57#endif 57#endif
58 58
59void print_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) 59void print_message(Messenger *m, int friendnumber, const uint8_t *string, uint16_t length, void *userdata)
60{ 60{
61 printf("Message with length %u received from %u: %s \n", length, friendnumber, string); 61 printf("Message with length %u received from %u: %s \n", length, friendnumber, string);
62 m_sendmessage(m, friendnumber, (uint8_t *)"Test1", 6); 62 m_sendmessage(m, friendnumber, (uint8_t *)"Test1", 6);
diff --git a/testing/dns3_test.c b/testing/dns3_test.c
index 69649f50..7052aae7 100644
--- a/testing/dns3_test.c
+++ b/testing/dns3_test.c
@@ -2,8 +2,45 @@
2 2
3#include "../toxdns/toxdns.h" 3#include "../toxdns/toxdns.h"
4#include "../toxcore/tox.h" 4#include "../toxcore/tox.h"
5#include "../toxcore/network.h"
5#include "misc_tools.c" 6#include "misc_tools.c"
6 7
8#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
9
10#define c_sleep(x) Sleep(1*x)
11
12#else
13#define c_sleep(x) usleep(1000*x)
14
15#endif
16
17uint32_t create_packet(uint8_t *packet, uint8_t *string, uint8_t str_len, uint8_t id)
18{
19 memset(packet, 0, str_len + 13 + 16);
20 packet[0] = id;
21 packet[1] = rand();
22 packet[5] = 1;
23 packet[11] = 1;
24 packet[12] = '.';
25 memcpy(packet + 13, string, str_len);
26 uint32_t i, c = 0;
27
28 for (i = str_len + 12; i != 11; --i) {
29 if (packet[i] == '.') {
30 packet[i] = c;
31 c = 0;
32 } else {
33 ++c;
34 }
35 }
36
37 packet[str_len + 13 + 2] = 16;
38 packet[str_len + 13 + 4] = 1;
39 packet[str_len + 13 + 7] = 0x29;
40 packet[str_len + 13 + 8] = 16;
41 packet[str_len + 13 + 12] = 0x80;
42 return str_len + 13 + 16;
43}
7 44
8int main(int argc, char *argv[]) 45int main(int argc, char *argv[])
9{ 46{
@@ -13,6 +50,22 @@ int main(int argc, char *argv[])
13 exit(0); 50 exit(0);
14 } 51 }
15 52
53 IP ip = {0};
54 ip.family = AF_INET;
55 sock_t sock = socket(ip.family, SOCK_DGRAM, IPPROTO_UDP);
56
57 if (!sock_valid(sock))
58 return -1;
59
60 if (!addr_resolve_or_parse_ip(argv[1], &ip, 0))
61 return -1;
62
63 struct sockaddr_in target;
64 size_t addrsize = sizeof(struct sockaddr_in);
65 target.sin_family = AF_INET;
66 target.sin_addr = ip.ip4.in_addr;
67 target.sin_port = htons(53);
68
16 uint8_t string[1024] = {0}; 69 uint8_t string[1024] = {0};
17 void *d = tox_dns3_new(hex_string_to_bin(argv[2])); 70 void *d = tox_dns3_new(hex_string_to_bin(argv[2]));
18 unsigned int i; 71 unsigned int i;
@@ -30,13 +83,24 @@ int main(int argc, char *argv[])
30 string[0] = '_'; 83 string[0] = '_';
31 memcpy(string + len + 1, "._tox.", sizeof("._tox.")); 84 memcpy(string + len + 1, "._tox.", sizeof("._tox."));
32 memcpy((char *)(string + len + 1 + sizeof("._tox.") - 1), argv[1], strlen(argv[1])); 85 memcpy((char *)(string + len + 1 + sizeof("._tox.") - 1), argv[1], strlen(argv[1]));
33 printf("Do a DNS request and find the TXT record for:\n%s\nThen paste the contents of the data contained in the id field here:\n", 86 uint8_t packet[512];
34 string); 87 uint8_t id = rand();
88 uint32_t p_len = create_packet(packet, string, strlen((char *)string), id);
89
90 if (sendto(sock, (char *) packet, p_len, 0, (struct sockaddr *)&target, addrsize) != p_len)
91 return -1;
92
93 uint8_t buffer[512] = {};
94 int r_len = recv(sock, buffer, sizeof(buffer), 0);
95
96 if (r_len < (int)p_len)
97 return -1;
98
99 for (i = r_len - 1; i != 0 && buffer[i] != '='; --i);
35 100
36 scanf("%s", string);
37 uint8_t tox_id[TOX_FRIEND_ADDRESS_SIZE]; 101 uint8_t tox_id[TOX_FRIEND_ADDRESS_SIZE];
38 102
39 if (tox_decrypt_dns3_TXT(d, tox_id, string, strlen((char *)string), request_id) != 0) 103 if (tox_decrypt_dns3_TXT(d, tox_id, buffer + i + 1, r_len - (i + 1), request_id) != 0)
40 return -1; 104 return -1;
41 105
42 printf("The Tox id for username %s is:\n", argv[3]); 106 printf("The Tox id for username %s is:\n", argv[3]);
diff --git a/testing/nTox.c b/testing/nTox.c
index 0145c6ee..971a2571 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -531,11 +531,11 @@ void line_eval(Tox *m, char *line)
531 } 531 }
532 } 532 }
533 } else if (inpt_command == 't') { 533 } else if (inpt_command == 't') {
534 char msg[512];
535 char *posi[1]; 534 char *posi[1];
536 int friendnum = strtoul(line + prompt_offset, posi, 0); 535 int friendnum = strtoul(line + prompt_offset, posi, 0);
537 536
538 if (**posi != 0) { 537 if (**posi != 0) {
538 char msg[512];
539 sprintf(msg, "[t] Sending file %s to friendnum %u filenumber is %i (-1 means failure)", *posi + 1, friendnum, 539 sprintf(msg, "[t] Sending file %s to friendnum %u filenumber is %i (-1 means failure)", *posi + 1, friendnum,
540 add_filesender(m, friendnum, *posi + 1)); 540 add_filesender(m, friendnum, *posi + 1));
541 new_lines(msg); 541 new_lines(msg);
@@ -634,7 +634,7 @@ void line_eval(Tox *m, char *line)
634 * otherwise turns spaces into newlines if possible */ 634 * otherwise turns spaces into newlines if possible */
635void wrap(char output[STRING_LENGTH_WRAPPED], char input[STRING_LENGTH], int line_width) 635void wrap(char output[STRING_LENGTH_WRAPPED], char input[STRING_LENGTH], int line_width)
636{ 636{
637 size_t i, k, m, len = strlen(input); 637 size_t i, len = strlen(input);
638 638
639 if ((line_width < 4) || (len < (size_t)line_width)) { 639 if ((line_width < 4) || (len < (size_t)line_width)) {
640 /* if line_width ridiculously tiny, it's not worth the effort */ 640 /* if line_width ridiculously tiny, it's not worth the effort */
@@ -652,8 +652,8 @@ void wrap(char output[STRING_LENGTH_WRAPPED], char input[STRING_LENGTH], int lin
652 652
653 for (i = line_width; i < len; i += line_width) { 653 for (i = line_width; i < len; i += line_width) {
654 /* look backward for a space to expand/turn into a new line */ 654 /* look backward for a space to expand/turn into a new line */
655 k = i; 655 size_t k = i;
656 m = i - line_width; 656 size_t m = i - line_width;
657 657
658 while (input[k] != ' ' && k > m) { 658 while (input[k] != ' ' && k > m) {
659 k--; 659 k--;
@@ -837,7 +837,6 @@ void do_refresh()
837{ 837{
838 int count = 0; 838 int count = 0;
839 char wrap_output[STRING_LENGTH_WRAPPED]; 839 char wrap_output[STRING_LENGTH_WRAPPED];
840 int L;
841 int i; 840 int i;
842 841
843 for (i = 0; i < HISTORY; i++) { 842 for (i = 0; i < HISTORY; i++) {
@@ -846,7 +845,7 @@ void do_refresh()
846 else 845 else
847 wrap(wrap_output, lines[i], x); 846 wrap(wrap_output, lines[i], x);
848 847
849 L = count_lines(wrap_output); 848 int L = count_lines(wrap_output);
850 count = count + L; 849 count = count + L;
851 850
852 if (count < y) { 851 if (count < y) {
@@ -877,14 +876,16 @@ void print_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint1
877 do_refresh(); 876 do_refresh();
878} 877}
879 878
880void print_message(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) 879void print_message(Tox *m, int friendnumber, const uint8_t *string, uint16_t length, void *userdata)
881{ 880{
882 /* ensure null termination */ 881 /* ensure null termination */
883 string[length - 1] = 0; 882 uint8_t null_string[length + 1];
884 print_formatted_message(m, (char *)string, friendnumber, 0); 883 memcpy(null_string, string, length);
884 null_string[length] = 0;
885 print_formatted_message(m, (char *)null_string, friendnumber, 0);
885} 886}
886 887
887void print_nickchange(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) 888void print_nickchange(Tox *m, int friendnumber, const uint8_t *string, uint16_t length, void *userdata)
888{ 889{
889 char name[TOX_MAX_NAME_LENGTH + 1]; 890 char name[TOX_MAX_NAME_LENGTH + 1];
890 891
@@ -900,7 +901,7 @@ void print_nickchange(Tox *m, int friendnumber, uint8_t *string, uint16_t length
900 } 901 }
901} 902}
902 903
903void print_statuschange(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) 904void print_statuschange(Tox *m, int friendnumber, const uint8_t *string, uint16_t length, void *userdata)
904{ 905{
905 char name[TOX_MAX_NAME_LENGTH + 1]; 906 char name[TOX_MAX_NAME_LENGTH + 1];
906 907
@@ -921,11 +922,10 @@ static char *data_file_name = NULL;
921static int load_data(Tox *m) 922static int load_data(Tox *m)
922{ 923{
923 FILE *data_file = fopen(data_file_name, "r"); 924 FILE *data_file = fopen(data_file_name, "r");
924 size_t size = 0;
925 925
926 if (data_file) { 926 if (data_file) {
927 fseek(data_file, 0, SEEK_END); 927 fseek(data_file, 0, SEEK_END);
928 size = ftell(data_file); 928 size_t size = ftell(data_file);
929 rewind(data_file); 929 rewind(data_file);
930 930
931 uint8_t data[size]; 931 uint8_t data[size];
@@ -1001,7 +1001,7 @@ 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
1004void print_invite(Tox *m, int friendnumber, uint8_t *group_public_key, void *userdata) 1004void print_invite(Tox *m, int friendnumber, const uint8_t *group_public_key, 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,
@@ -1057,7 +1057,8 @@ void print_groupchatpeers(Tox *m, int groupnumber)
1057 new_lines_mark(msg, 1); 1057 new_lines_mark(msg, 1);
1058} 1058}
1059 1059
1060void print_groupmessage(Tox *m, int groupnumber, int peernumber, uint8_t *message, uint16_t length, void *userdata) 1060void print_groupmessage(Tox *m, int groupnumber, int peernumber, const uint8_t *message, uint16_t length,
1061 void *userdata)
1061{ 1062{
1062 char msg[256 + length]; 1063 char msg[256 + length];
1063 uint8_t name[TOX_MAX_NAME_LENGTH] = {0}; 1064 uint8_t name[TOX_MAX_NAME_LENGTH] = {0};
@@ -1118,7 +1119,7 @@ void print_groupnamelistchange(Tox *m, int groupnumber, int peernumber, uint8_t
1118 print_groupchatpeers(m, groupnumber); 1119 print_groupchatpeers(m, groupnumber);
1119 } 1120 }
1120} 1121}
1121void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, 1122void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, const uint8_t *filename,
1122 uint16_t filename_length, void *userdata) 1123 uint16_t filename_length, void *userdata)
1123{ 1124{
1124 char msg[512]; 1125 char msg[512];
@@ -1133,8 +1134,7 @@ void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t
1133} 1134}
1134 1135
1135void file_print_control(Tox *m, int friendnumber, uint8_t send_recieve, uint8_t filenumber, uint8_t control_type, 1136void file_print_control(Tox *m, int friendnumber, uint8_t send_recieve, uint8_t filenumber, uint8_t control_type,
1136 uint8_t *data, 1137 const uint8_t *data, uint16_t length, void *userdata)
1137 uint16_t length, void *userdata)
1138{ 1138{
1139 char msg[512] = {0}; 1139 char msg[512] = {0};
1140 1140
@@ -1148,7 +1148,7 @@ void file_print_control(Tox *m, int friendnumber, uint8_t send_recieve, uint8_t
1148 new_lines(msg); 1148 new_lines(msg);
1149} 1149}
1150 1150
1151void write_file(Tox *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) 1151void write_file(Tox *m, int friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length, void *userdata)
1152{ 1152{
1153 char filename[256]; 1153 char filename[256];
1154 sprintf(filename, "%u.%u.bin", friendnumber, filenumber); 1154 sprintf(filename, "%u.%u.bin", friendnumber, filenumber);
@@ -1215,7 +1215,6 @@ int main(int argc, char *argv[])
1215 exit(1); 1215 exit(1);
1216 1216
1217 int on = 0; 1217 int on = 0;
1218 int c = 0;
1219 char *filename = "data"; 1218 char *filename = "data";
1220 char idstring[200] = {0}; 1219 char idstring[200] = {0};
1221 Tox *m; 1220 Tox *m;
@@ -1282,8 +1281,6 @@ int main(int argc, char *argv[])
1282 1281
1283 time_t timestamp0 = time(NULL); 1282 time_t timestamp0 = time(NULL);
1284 1283
1285 uint8_t pollok = 0;
1286
1287 while (1) { 1284 while (1) {
1288 if (on == 0) { 1285 if (on == 0) {
1289 if (tox_isconnected(m)) { 1286 if (tox_isconnected(m)) {
@@ -1305,7 +1302,7 @@ int main(int argc, char *argv[])
1305 tox_do(m); 1302 tox_do(m);
1306 do_refresh(); 1303 do_refresh();
1307 1304
1308 c = timeout_getch(m); 1305 int c = timeout_getch(m);
1309 1306
1310 if (c == ERR || c == 27) 1307 if (c == ERR || c == 27)
1311 continue; 1308 continue;
diff --git a/testing/tox_sync.c b/testing/tox_sync.c
index 68cad9f4..523f2c56 100644
--- a/testing/tox_sync.c
+++ b/testing/tox_sync.c
@@ -130,7 +130,7 @@ int not_sending()
130 130
131static char path[1024]; 131static char path[1024];
132 132
133void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, 133void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, const uint8_t *filename,
134 uint16_t filename_length, void *userdata) 134 uint16_t filename_length, void *userdata)
135{ 135{
136 char fullpath[1024]; 136 char fullpath[1024];
@@ -169,7 +169,7 @@ void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t
169} 169}
170 170
171void file_print_control(Tox *m, int friendnumber, uint8_t recieve_send, uint8_t filenumber, uint8_t control_type, 171void file_print_control(Tox *m, int friendnumber, uint8_t recieve_send, uint8_t filenumber, uint8_t control_type,
172 uint8_t *data, 172 const uint8_t *data,
173 uint16_t length, void *userdata) 173 uint16_t length, void *userdata)
174{ 174{
175 if (recieve_send == 1 && (control_type == TOX_FILECONTROL_KILL || control_type == TOX_FILECONTROL_FINISHED)) { 175 if (recieve_send == 1 && (control_type == TOX_FILECONTROL_KILL || control_type == TOX_FILECONTROL_FINISHED)) {
@@ -185,7 +185,7 @@ void file_print_control(Tox *m, int friendnumber, uint8_t recieve_send, uint8_t
185 } 185 }
186} 186}
187 187
188void write_file(Tox *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) 188void write_file(Tox *m, int friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length, void *userdata)
189{ 189{
190 if (file_recv[filenumber].file != 0) 190 if (file_recv[filenumber].file != 0)
191 if (fwrite(data, length, 1, file_recv[filenumber].file) != 1) 191 if (fwrite(data, length, 1, file_recv[filenumber].file) != 1)
diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc
index 50e2564c..de8ef8ff 100644
--- a/toxav/Makefile.inc
+++ b/toxav/Makefile.inc
@@ -4,14 +4,12 @@ lib_LTLIBRARIES += libtoxav.la
4libtoxav_la_include_HEADERS = ../toxav/toxav.h 4libtoxav_la_include_HEADERS = ../toxav/toxav.h
5libtoxav_la_includedir = $(includedir)/tox 5libtoxav_la_includedir = $(includedir)/tox
6 6
7libtoxav_la_SOURCES = ../toxav/event.h \ 7libtoxav_la_SOURCES = ../toxav/rtp.h \
8 ../toxav/event.c \
9 ../toxav/rtp.h \
10 ../toxav/rtp.c \ 8 ../toxav/rtp.c \
11 ../toxav/msi.h \ 9 ../toxav/msi.h \
12 ../toxav/msi.c \ 10 ../toxav/msi.c \
13 ../toxav/media.h \ 11 ../toxav/codec.h \
14 ../toxav/media.c \ 12 ../toxav/codec.c \
15 ../toxav/toxav.h \ 13 ../toxav/toxav.h \
16 ../toxav/toxav.c 14 ../toxav/toxav.c
17 15
diff --git a/toxav/media.c b/toxav/codec.c
index 8b50e301..ae24a976 100644
--- a/toxav/media.c
+++ b/toxav/codec.c
@@ -1,4 +1,4 @@
1/** media.c 1/** codec.c
2 * 2 *
3 * Audio and video codec intitialization, encoding/decoding and playback 3 * Audio and video codec intitialization, encoding/decoding and playback
4 * 4 *
@@ -34,7 +34,10 @@
34#include <assert.h> 34#include <assert.h>
35 35
36#include "rtp.h" 36#include "rtp.h"
37#include "media.h" 37#include "codec.h"
38
39const uint16_t min_jbuf_size = 4;
40const uint16_t min_readiness_idx = 2; /* when is buffer ready to dqq */
38 41
39int empty_queue(JitterBuffer *q) 42int empty_queue(JitterBuffer *q)
40{ 43{
@@ -65,7 +68,7 @@ JitterBuffer *create_queue(int capacity)
65 } 68 }
66 69
67 q->size = 0; 70 q->size = 0;
68 q->capacity = capacity; 71 q->capacity = capacity >= min_jbuf_size ? capacity : min_jbuf_size;
69 q->front = 0; 72 q->front = 0;
70 q->rear = -1; 73 q->rear = -1;
71 q->queue_ready = 0; 74 q->queue_ready = 0;
@@ -77,8 +80,12 @@ JitterBuffer *create_queue(int capacity)
77 80
78void terminate_queue(JitterBuffer *q) 81void terminate_queue(JitterBuffer *q)
79{ 82{
83 if (!q) return;
84
80 empty_queue(q); 85 empty_queue(q);
81 free(q->queue); 86 free(q->queue);
87
88 LOGGER_DEBUG("Terminated jitter buffer: %p", q);
82 free(q); 89 free(q);
83} 90}
84 91
@@ -141,24 +148,21 @@ void queue(JitterBuffer *q, RTPMessage *pk)
141 empty_queue(q); 148 empty_queue(q);
142 } 149 }
143 150
144 if (q->size > 8) 151 if (q->size >= min_readiness_idx) q->queue_ready = 1;
145 q->queue_ready = 1;
146 152
147 ++q->size; 153 ++q->size;
148 ++q->rear; 154 ++q->rear;
149 155
150 if (q->rear == q->capacity) 156 if (q->rear == q->capacity) q->rear = 0;
151 q->rear = 0;
152 157
153 q->queue[q->rear] = pk; 158 q->queue[q->rear] = pk;
154 159
155 int a; 160 int a;
156 int b;
157 int j; 161 int j;
158 a = q->rear; 162 a = q->rear;
159 163
160 for (j = 0; j < q->size - 1; ++j) { 164 for (j = 0; j < q->size - 1; ++j) {
161 b = a - 1; 165 int b = a - 1;
162 166
163 if (b < 0) 167 if (b < 0)
164 b += q->capacity; 168 b += q->capacity;
@@ -176,8 +180,7 @@ void queue(JitterBuffer *q, RTPMessage *pk)
176 180
177 a -= 1; 181 a -= 1;
178 182
179 if (a < 0) 183 if (a < 0) a += q->capacity;
180 a += q->capacity;
181 } 184 }
182} 185}
183 186
@@ -207,20 +210,71 @@ int init_audio_decoder(CodecState *cs, uint32_t audio_channels)
207 return 0; 210 return 0;
208} 211}
209 212
213int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_t height)
214{
215 vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc;
216
217 if (cfg.g_w == width && cfg.g_h == height)
218 return 0;
219
220 if (width * height > cs->max_width * cs->max_height)
221 return -1;
222
223 LOGGER_DEBUG("New video resolution: %u %u", width, height);
224 cfg.g_w = width;
225 cfg.g_h = height;
226 int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg);
227
228 if ( rc != VPX_CODEC_OK) {
229 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
230 return -1;
231 }
232
233 return 0;
234}
210 235
211int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t video_bitrate) 236int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate)
237{
238 vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc;
239
240 if (cfg.rc_target_bitrate == video_bitrate)
241 return 0;
242
243 LOGGER_DEBUG("New video bitrate: %u", video_bitrate);
244 cfg.rc_target_bitrate = video_bitrate;
245 int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg);
246
247 if ( rc != VPX_CODEC_OK) {
248 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
249 return -1;
250 }
251
252 return 0;
253}
254
255int init_video_encoder(CodecState *cs, uint16_t max_width, uint16_t max_height, uint32_t video_bitrate)
212{ 256{
213 vpx_codec_enc_cfg_t cfg; 257 vpx_codec_enc_cfg_t cfg;
214 int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0); 258 int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
215 259
216 if (rc) { 260 if (rc != VPX_CODEC_OK) {
217 LOGGER_ERROR("Failed to get config: %s", vpx_codec_err_to_string(rc)); 261 LOGGER_ERROR("Failed to get config: %s", vpx_codec_err_to_string(rc));
218 return -1; 262 return -1;
219 } 263 }
220 264
221 cfg.rc_target_bitrate = video_bitrate; 265 cfg.rc_target_bitrate = video_bitrate;
222 cfg.g_w = width; 266 cfg.g_w = max_width;
223 cfg.g_h = height; 267 cfg.g_h = max_height;
268 cfg.g_pass = VPX_RC_ONE_PASS;
269 cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS;
270 cfg.g_lag_in_frames = 0;
271 cfg.kf_min_dist = 0;
272 cfg.kf_max_dist = 300;
273 cfg.kf_mode = VPX_KF_AUTO;
274
275 cs->max_width = max_width;
276 cs->max_height = max_height;
277 cs->bitrate = video_bitrate;
224 278
225 rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION); 279 rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION);
226 280
@@ -229,6 +283,13 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
229 return -1; 283 return -1;
230 } 284 }
231 285
286 rc = vpx_codec_control(&cs->v_encoder, VP8E_SET_CPUUSED, 7);
287
288 if ( rc != VPX_CODEC_OK) {
289 LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
290 return -1;
291 }
292
232 return 0; 293 return 0;
233} 294}
234 295
@@ -265,8 +326,9 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
265 uint16_t audio_frame_duration, 326 uint16_t audio_frame_duration,
266 uint32_t audio_sample_rate, 327 uint32_t audio_sample_rate,
267 uint32_t audio_channels, 328 uint32_t audio_channels,
268 uint16_t video_width, 329 uint32_t audio_VAD_tolerance_ms,
269 uint16_t video_height, 330 uint16_t max_video_width,
331 uint16_t max_video_height,
270 uint32_t video_bitrate ) 332 uint32_t video_bitrate )
271{ 333{
272 CodecState *retu = calloc(sizeof(CodecState), 1); 334 CodecState *retu = calloc(sizeof(CodecState), 1);
@@ -277,11 +339,12 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
277 retu->audio_sample_rate = audio_sample_rate; 339 retu->audio_sample_rate = audio_sample_rate;
278 340
279 /* Encoders */ 341 /* Encoders */
280 if (!video_width || !video_height) { /* Disable video */ 342 if (!max_video_width || !max_video_height) { /* Disable video */
281 /*video_width = 320; 343 /*video_width = 320;
282 video_height = 240; */ 344 video_height = 240; */
283 } else { 345 } else {
284 retu->capabilities |= ( 0 == init_video_encoder(retu, video_width, video_height, video_bitrate) ) ? v_encoding : 0; 346 retu->capabilities |= ( 0 == init_video_encoder(retu, max_video_width, max_video_height,
347 video_bitrate) ) ? v_encoding : 0;
285 retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0; 348 retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0;
286 } 349 }
287 350
@@ -293,24 +356,56 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
293 return NULL; 356 return NULL;
294 } 357 }
295 358
359
360 retu->EVAD_tolerance = audio_VAD_tolerance_ms > audio_frame_duration ?
361 audio_VAD_tolerance_ms / audio_frame_duration : audio_frame_duration;
362
296 return retu; 363 return retu;
297} 364}
298 365
299void codec_terminate_session ( CodecState *cs ) 366void codec_terminate_session ( CodecState *cs )
300{ 367{
368 if (!cs) return;
369
301 if ( cs->audio_encoder ) 370 if ( cs->audio_encoder )
302 opus_encoder_destroy(cs->audio_encoder); 371 opus_encoder_destroy(cs->audio_encoder);
303 372
304 if ( cs->audio_decoder ) 373 if ( cs->audio_decoder )
305 opus_decoder_destroy(cs->audio_decoder); 374 opus_decoder_destroy(cs->audio_decoder);
306 375
307
308 /* TODO: Terminate video
309 * Do what?
310 */
311 if ( cs->capabilities & v_decoding ) 376 if ( cs->capabilities & v_decoding )
312 vpx_codec_destroy(&cs->v_decoder); 377 vpx_codec_destroy(&cs->v_decoder);
313 378
314 if ( cs->capabilities & v_encoding ) 379 if ( cs->capabilities & v_encoding )
315 vpx_codec_destroy(&cs->v_encoder); 380 vpx_codec_destroy(&cs->v_encoder);
381
382 LOGGER_DEBUG("Terminated codec state: %p", cs);
383 free(cs);
384}
385
386inline float calculate_sum_sq (int16_t *n, uint16_t k)
387{
388 float result = 0;
389 uint16_t i = 0;
390
391 for ( ; i < k; i ++) result += (float) (n[i] * n[i]);
392
393 return result;
394}
395
396int energy_VAD(CodecState *cs, int16_t *PCM, uint16_t frame_size, float energy)
397{
398 float frame_energy = sqrt(calculate_sum_sq(PCM, frame_size)) / frame_size;
399
400 if ( frame_energy > energy) {
401 cs->EVAD_tolerance_cr = cs->EVAD_tolerance; /* Reset counter */
402 return 1;
403 }
404
405 if ( cs->EVAD_tolerance_cr ) {
406 cs->EVAD_tolerance_cr --;
407 return 1;
408 }
409
410 return 0;
316} 411}
diff --git a/toxav/media.h b/toxav/codec.h
index 66798351..a464ec8f 100644
--- a/toxav/media.h
+++ b/toxav/codec.h
@@ -1,4 +1,4 @@
1/** media.h 1/** codec.h
2 * 2 *
3 * Audio and video codec intitialization, encoding/decoding and playback 3 * Audio and video codec intitialization, encoding/decoding and playback
4 * 4 *
@@ -21,8 +21,8 @@
21 * 21 *
22 */ 22 */
23 23
24#ifndef _AVCODEC_H_ 24#ifndef _CODEC_H_
25#define _AVCODEC_H_ 25#define _CODEC_H_
26 26
27#include <stdio.h> 27#include <stdio.h>
28#include <math.h> 28#include <math.h>
@@ -46,6 +46,8 @@ typedef enum _Capabilities {
46 v_decoding = 1 << 3 46 v_decoding = 1 << 3
47} Capabilities; 47} Capabilities;
48 48
49extern const uint16_t min_jbuf_size;
50
49typedef struct _CodecState { 51typedef struct _CodecState {
50 52
51 /* video encoding */ 53 /* video encoding */
@@ -54,6 +56,9 @@ typedef struct _CodecState {
54 56
55 /* video decoding */ 57 /* video decoding */
56 vpx_codec_ctx_t v_decoder; 58 vpx_codec_ctx_t v_decoder;
59 int bitrate;
60 int max_width;
61 int max_height;
57 62
58 /* audio encoding */ 63 /* audio encoding */
59 OpusEncoder *audio_encoder; 64 OpusEncoder *audio_encoder;
@@ -65,6 +70,9 @@ typedef struct _CodecState {
65 70
66 uint64_t capabilities; /* supports*/ 71 uint64_t capabilities; /* supports*/
67 72
73 /* Voice activity detection */
74 uint32_t EVAD_tolerance; /* In frames */
75 uint32_t EVAD_tolerance_cr;
68} CodecState; 76} CodecState;
69 77
70 78
@@ -90,10 +98,20 @@ CodecState *codec_init_session ( uint32_t audio_bitrate,
90 uint16_t audio_frame_duration, 98 uint16_t audio_frame_duration,
91 uint32_t audio_sample_rate, 99 uint32_t audio_sample_rate,
92 uint32_t audio_channels, 100 uint32_t audio_channels,
101 uint32_t audio_VAD_tolerance_ms,
93 uint16_t video_width, 102 uint16_t video_width,
94 uint16_t video_height, 103 uint16_t video_height,
95 uint32_t video_bitrate ); 104 uint32_t video_bitrate);
96 105
97void codec_terminate_session(CodecState *cs); 106void codec_terminate_session(CodecState *cs);
98 107
99#endif 108/* Reconfigure video encoder
109 return 0 on success.
110 return -1 on failure. */
111int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_t height);
112int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate);
113
114/* Calculate energy and return 1 if has voice, 0 if not */
115int energy_VAD(CodecState *cs, int16_t *PCM, uint16_t frame_size, float energy);
116
117#endif /* _CODEC_H_ */
diff --git a/toxav/event.c b/toxav/event.c
deleted file mode 100644
index 870abf2a..00000000
--- a/toxav/event.c
+++ /dev/null
@@ -1,382 +0,0 @@
1/** event.c
2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 *
5 * This file is part of Tox.
6 *
7 * Tox is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * Tox is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 *
20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */
23
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif /* HAVE_CONFIG_H */
28
29#include <stdlib.h>
30#include "../toxcore/network.h" /* current_time_monotonic() */
31#include "event.h"
32
33#define _GNU_SOURCE
34
35#include <assert.h>
36#include <unistd.h>
37#include <stddef.h>
38#include <inttypes.h>
39#include <pthread.h>
40#include <stdio.h>
41
42#define RUN_IN_THREAD(func, args) { pthread_t _tid; \
43pthread_create(&_tid, NULL, func, args); assert( pthread_detach(_tid) == 0 ); }
44
45#define LOCK(event_handler) pthread_mutex_lock (&event_handler->mutex)
46#define UNLOCK(event_handler) pthread_mutex_unlock(&event_handler->mutex)
47
48#define FREQUENCY 10000
49
50#define inline__ inline __attribute__((always_inline))
51
52
53typedef struct _EventContainer {
54 void *(*func)(void *);
55 void *func_args;
56 unsigned timeout;
57 long long id;
58
59} EventContainer;
60
61typedef struct _EventHandler {
62 EventContainer *timed_events;
63 size_t timed_events_count;
64
65 int running;
66
67 pthread_mutex_t mutex;
68
69} EventHandler;
70
71int throw_event( void *(func)(void *), void *arg );
72int reset_timer_event ( int id, uint32_t timeout );
73int throw_timer_event ( void *(func)(void *), void *arg, unsigned timeout);
74int cancel_timer_event ( int id );
75int execute_timer_event ( int id );
76
77struct _Event event = {
78 throw_event,
79 /* reset_timer_event */ NULL,
80 throw_timer_event,
81 cancel_timer_event,
82 /*execute_timer_event*/ NULL
83};
84
85/*
86 * Random functions used by this file
87 */
88void clear_events (EventContainer **event_container, size_t *counter)
89{
90 free(*event_container );
91
92 *event_container = NULL;
93 *counter = 0;
94}
95
96int pop_id ( EventContainer **event_container, size_t *counter, int id )
97{
98 if ( !*event_container || !*counter || !id )
99 return -1;
100
101 EventContainer *_it = *event_container;
102 int i;
103
104 for ( i = *counter; i; -- i ) {
105 if ( _it->id == id ) { /* Hit! */
106 break;
107 }
108
109 ++_it;
110 }
111
112 if ( i ) {
113 for ( ; i; -- i ) {
114 *_it = *(_it + 1);
115 ++_it;
116 }
117
118 -- (*counter );
119
120 if ( !(*counter)) { /* Free and set to NULL */
121 free(*event_container);
122 *event_container = NULL;
123 } else {
124 void *_result = realloc(*event_container, sizeof(EventContainer) * (*counter )); /* resize */
125
126
127 if ( _result != NULL ) {
128 *event_container = _result;
129 return 0;
130 } else {
131 /* Not sure what would happen next so abort execution.
132 */
133 fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__);
134 abort();
135 return -1;
136 }
137 }
138 }
139
140 /* not found here */
141
142 return -1;
143}
144
145void push_event ( EventContainer **container, size_t *counter, void *(func)(void *), void *arg )
146{
147 EventContainer *_new = realloc((*container ), sizeof(EventContainer) * ((*counter ) + 1));
148
149 if ( _new == NULL ) {
150 /* Not sure what would happen next so abort execution.
151 * TODO: This could notice the calling function
152 * about realloc failing.
153 */
154 fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__);
155 abort();
156 }
157
158 _new[*counter].func = func;
159 _new[*counter].func_args = arg;
160 _new[*counter].timeout = 0;
161 _new[*counter].id = 0;
162
163 (*container) = _new;
164
165 (*counter )++;
166}
167
168void reorder_events ( size_t counter, EventContainer *container, unsigned timeout )
169{
170 if ( counter > 1 ) {
171
172 int i = counter - 1;
173
174 /* start from behind excluding last added member */
175 EventContainer *_it = &container[i - 1];
176
177 EventContainer _last_added = container[i];
178
179 for ( ; i; --i ) {
180 if ( _it->timeout > timeout ) {
181 *(_it + 1) = *_it;
182 *_it = _last_added;
183 -- _it;
184 }
185 }
186
187 }
188}
189
190/* ============================================= */
191
192/* main poll for event execution */
193void *event_poll( void *arg )
194{
195 EventHandler *_event_handler = arg;
196
197 while ( _event_handler->running ) {
198
199 LOCK( _event_handler );
200
201 if ( _event_handler->timed_events ) {
202
203 uint32_t _time = ((uint32_t)current_time_monotonic());
204
205 if ( _event_handler->timed_events[0].timeout < _time ) {
206
207 RUN_IN_THREAD ( _event_handler->timed_events[0].func,
208 _event_handler->timed_events[0].func_args );
209
210 pop_id(&_event_handler->timed_events,
211 &_event_handler->timed_events_count,
212 _event_handler->timed_events[0].id);
213
214 }
215
216 }
217
218 UNLOCK( _event_handler );
219
220 usleep(FREQUENCY);
221 }
222
223 LOCK( _event_handler );
224
225 clear_events(&_event_handler->timed_events, &_event_handler->timed_events_count);
226
227 UNLOCK( _event_handler );
228
229 _event_handler->running = -1;
230 pthread_exit(NULL);
231}
232
233int throw_event( void *(func)(void *), void *arg )
234{
235 pthread_t _tid;
236 int _rc =
237 pthread_create(&_tid, NULL, func, arg );
238
239 return (0 != _rc ) ? _rc : pthread_detach(_tid);
240}
241
242EventHandler event_handler;
243
244/* Place and order array of timers */
245int throw_timer_event ( void *(func)(void *), void *arg, unsigned timeout)
246{
247 static int _unique_id = 1;
248
249 push_event(&event_handler.timed_events, &(event_handler.timed_events_count), func, arg );
250
251 size_t _counter = event_handler.timed_events_count;
252
253 event_handler.timed_events[_counter - 1].timeout = timeout + ((uint32_t)current_time_monotonic());
254 event_handler.timed_events[_counter - 1].id = _unique_id;
255 ++_unique_id;
256
257
258 /* reorder */
259
260 reorder_events(_counter, event_handler.timed_events, timeout );
261
262 return _unique_id - 1;
263}
264
265int execute_timer_event ( int id )
266{
267 int _status;
268
269 LOCK((&event_handler));
270 EventContainer *_it = event_handler.timed_events;
271
272 int _i = event_handler.timed_events_count;
273
274 /* Find it and execute */
275 for ( ; _i; _i-- ) {
276 if ( _it->id == id ) {
277 RUN_IN_THREAD ( _it->func, _it->func_args );
278 break;
279 }
280
281 ++_it;
282 }
283
284 /* Now remove it from the queue */
285
286 if ( _i ) {
287 for ( ; _i; -- _i ) {
288 *_it = *(_it + 1);
289 ++_it;
290 }
291
292 -- event_handler.timed_events_count;
293
294 if ( !event_handler.timed_events_count ) { /* Free and set to null */
295 free(event_handler.timed_events);
296 event_handler.timed_events = NULL;
297 } else {
298 void *_result = realloc(event_handler.timed_events,
299 sizeof(EventContainer) * event_handler.timed_events_count); /* resize */
300
301 if ( _result != NULL ) {
302 event_handler.timed_events = _result;
303 } else {
304 /* Not sure what would happen next so abort execution.
305 */
306 fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__);
307 abort();
308 return -1;
309 }
310 }
311
312 _status = 0;
313
314 } else _status = -1;
315
316 UNLOCK((&event_handler));
317
318 return _status;
319}
320
321int reset_timer_event ( int id, uint32_t timeout )
322{
323 int _status;
324
325 LOCK((&event_handler));
326
327 EventContainer *_it = event_handler.timed_events;
328
329 int _i = event_handler.timed_events_count;
330
331 /* Find it and change */
332 for ( ; _i; _i-- ) {
333 if ( _it->id == id ) {
334 _it->timeout = timeout + ((uint32_t)current_time_monotonic());
335 break;
336 }
337
338 ++_it;
339 }
340
341 _status = _i ? -1 : 0;
342
343 UNLOCK((&event_handler));
344
345 return _status;
346}
347
348/* Remove timer from array */
349inline__ int cancel_timer_event ( int id )
350{
351 return pop_id (&event_handler.timed_events, &event_handler.timed_events_count, id );
352}
353
354
355/* Initialization and termination of event polls
356 * This will be run at the beginning and the end of the program execution.
357 * I think that's the best way to do it.
358 */
359
360void __attribute__((constructor)) init_event_poll ()
361{
362 event_handler.timed_events = NULL;
363 event_handler.timed_events_count = 0;
364
365 event_handler.running = 1;
366
367 pthread_mutex_init(&event_handler.mutex, NULL);
368
369 RUN_IN_THREAD(event_poll, &event_handler);
370}
371
372/* NOTE: Do we need this? */
373void __attribute__((destructor)) terminate_event_poll()
374{
375 /* Exit thread */
376 event_handler.running = 0;
377
378 /* Give it enought time to exit */
379 usleep(FREQUENCY * 2);
380
381 pthread_mutex_destroy( &event_handler.mutex );
382} \ No newline at end of file
diff --git a/toxav/event.h b/toxav/event.h
deleted file mode 100644
index f9e67543..00000000
--- a/toxav/event.h
+++ /dev/null
@@ -1,49 +0,0 @@
1/** event.h
2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 *
5 * This file is part of Tox.
6 *
7 * Tox is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * Tox is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 *
20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */
23
24
25#ifndef __TOXEVENT
26#define __TOXEVENT
27
28
29/**
30 * - Events are, in fact, ran in their own threads upon execution.
31 * - Event handler is initialized at the start, before the main() function
32 * and terminated after it's execution.
33 * - Timers are checked for timeout every ~10000 ns.
34 * - Timers can be canceled or ran immediately via
35 * timer_release() or timer_now() functions.
36 * - Timeout is measured in milliseconds.
37 *
38 * NOTE: timer_reset () and timer_now() are not tested nor usable atm
39 *
40 */
41extern struct _Event {
42 int (*rise) (void *( func ) ( void *), void *arg);
43 int (*timer_reset ) ( int id, unsigned timeout );
44 int (*timer_alloc) (void *( func ) ( void *), void *arg, unsigned timeout);
45 int (*timer_release) (int id);
46 int (*timer_now) ( int id );
47} event;
48
49#endif /* _MSI__EVENT_H_ */
diff --git a/toxav/msi.c b/toxav/msi.c
index 8476c5be..88f62ebd 100644
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -17,8 +17,6 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 20 */
23 21
24 22
@@ -30,13 +28,11 @@
30#include "../toxcore/util.h" 28#include "../toxcore/util.h"
31 29
32#include "msi.h" 30#include "msi.h"
33#include "event.h"
34
35 31
36#include <assert.h>
37#include <unistd.h> 32#include <unistd.h>
38#include <string.h> 33#include <string.h>
39#include <stdlib.h> 34#include <stdlib.h>
35#include <stdbool.h>
40 36
41#define same(x, y) strcmp((const char*) x, (const char*) y) == 0 37#define same(x, y) strcmp((const char*) x, (const char*) y) == 0
42 38
@@ -86,8 +82,6 @@ GENERIC_HEADER ( CallType )
86GENERIC_HEADER ( CallId ) 82GENERIC_HEADER ( CallId )
87GENERIC_HEADER ( Info ) 83GENERIC_HEADER ( Info )
88GENERIC_HEADER ( Reason ) 84GENERIC_HEADER ( Reason )
89GENERIC_HEADER ( CryptoKey )
90GENERIC_HEADER ( Nonce )
91 85
92 86
93/** 87/**
@@ -104,8 +98,6 @@ typedef struct _MSIMessage {
104 MSIHeaderInfo info; 98 MSIHeaderInfo info;
105 MSIHeaderReason reason; 99 MSIHeaderReason reason;
106 MSIHeaderCallId callid; 100 MSIHeaderCallId callid;
107 MSIHeaderCryptoKey cryptokey;
108 MSIHeaderNonce nonce;
109 101
110 struct _MSIMessage *next; 102 struct _MSIMessage *next;
111 103
@@ -117,11 +109,10 @@ typedef struct _MSIMessage {
117static struct _Callbacks { 109static struct _Callbacks {
118 MSICallback function; 110 MSICallback function;
119 void *data; 111 void *data;
120} callbacks[11] = {0}; 112} callbacks[11] = {{0}};
121 113
122inline__ void invoke_callback(int32_t call_index, MSICallbackID id) 114inline__ void invoke_callback(int32_t call_index, MSICallbackID id)
123{ 115{
124 /*if ( callbacks[id].function ) event.rise ( callbacks[id].function, callbacks[id].data );*/
125 if ( callbacks[id].function ) { 116 if ( callbacks[id].function ) {
126 LOGGER_DEBUG("Invoking callback function: %d", id); 117 LOGGER_DEBUG("Invoking callback function: %d", id);
127 callbacks[id].function ( call_index, callbacks[id].data ); 118 callbacks[id].function ( call_index, callbacks[id].data );
@@ -139,8 +130,6 @@ inline__ void invoke_callback(int32_t call_index, MSICallbackID id)
139#define REASON_FIELD "Reason" 130#define REASON_FIELD "Reason"
140#define CALLTYPE_FIELD "Call-type" 131#define CALLTYPE_FIELD "Call-type"
141#define CALLID_FIELD "Call-id" 132#define CALLID_FIELD "Call-id"
142#define CRYPTOKEY_FIELD "Crypto-key"
143#define NONCE_FIELD "Nonce"
144 133
145/* protocol descriptors */ 134/* protocol descriptors */
146#define end_byte 0x0 135#define end_byte 0x0
@@ -228,7 +217,8 @@ if ( *iterator != value_byte || size_con <= type_size_const) { return -1; } size
228iterator ++; if(size_con <= 3) {return -1;} size_con -= 3; \ 217iterator ++; if(size_con <= 3) {return -1;} size_con -= 3; \
229uint16_t _value_size; memcpy(&_value_size, iterator, sizeof(_value_size)); _value_size = ntohs(_value_size);\ 218uint16_t _value_size; memcpy(&_value_size, iterator, sizeof(_value_size)); _value_size = ntohs(_value_size);\
230if(size_con < _value_size) { return -1; } size_con -= _value_size; \ 219if(size_con < _value_size) { return -1; } size_con -= _value_size; \
231header.header_value = calloc(sizeof(uint8_t), _value_size); \ 220if ( !(header.header_value = calloc(sizeof(uint8_t), _value_size)) ) \
221LOGGER_ERROR("Allocation failed! Program might misbehave!"); \
232header.size = _value_size; \ 222header.size = _value_size; \
233memcpy(header.header_value, iterator + 2, _value_size);\ 223memcpy(header.header_value, iterator + 2, _value_size);\
234iterator = iterator + 2 + _value_size; /* set iterator at new header or end_byte */ } 224iterator = iterator + 2 + _value_size; /* set iterator at new header or end_byte */ }
@@ -259,18 +249,13 @@ iterator = iterator + 2 + _value_size; /* set iterator at new header or end_byte
259 _it += 3; /* place it at the field value beginning */ 249 _it += 3; /* place it at the field value beginning */
260 size_max -= 3; 250 size_max -= 3;
261 251
262 switch ( _size ) { /* Compare the size of the hardcoded values ( vary fast and convenient ) */ 252 switch ( _size ) { /* Compare the size of the hardcoded values ( very convenient ) */
263 253
264 case 4: { /* INFO header */ 254 case 4: { /* INFO header */
265 if ON_HEADER ( _it, size_max, msg->info, INFO_FIELD, 4 ) 255 if ON_HEADER ( _it, size_max, msg->info, INFO_FIELD, 4 )
266 } 256 }
267 break; 257 break;
268 258
269 case 5: { /* NONCE header */
270 if ON_HEADER ( _it, size_max, msg->nonce, NONCE_FIELD, 5 )
271 }
272 break;
273
274 case 6: { /* Reason header */ 259 case 6: { /* Reason header */
275 if ON_HEADER ( _it, size_max, msg->reason, REASON_FIELD, 6 ) 260 if ON_HEADER ( _it, size_max, msg->reason, REASON_FIELD, 6 )
276 } 261 }
@@ -293,11 +278,6 @@ iterator = iterator + 2 + _value_size; /* set iterator at new header or end_byte
293 } 278 }
294 break; 279 break;
295 280
296 case 10: { /* Crypto-key headers */
297 if ON_HEADER ( _it, size_max, msg->cryptokey, CRYPTOKEY_FIELD, 10 )
298 }
299 break;
300
301 default: 281 default:
302 LOGGER_ERROR("Unkown field value"); 282 LOGGER_ERROR("Unkown field value");
303 return -1; 283 return -1;
@@ -316,8 +296,8 @@ iterator = iterator + 2 + _value_size; /* set iterator at new header or end_byte
316 296
317 297
318#define ALLOCATE_HEADER( var, mheader_value, t_size) \ 298#define ALLOCATE_HEADER( var, mheader_value, t_size) \
319var.header_value = calloc(sizeof *mheader_value, t_size); \ 299if (!(var.header_value = calloc(sizeof *mheader_value, t_size))) \
320if (var.header_value == NULL) { LOGGER_WARNING("Header allocation failed!"); } \ 300{ LOGGER_WARNING("Header allocation failed! Program might misbehave!"); } \
321else { memcpy(var.header_value, mheader_value, t_size); \ 301else { memcpy(var.header_value, mheader_value, t_size); \
322var.size = t_size; } 302var.size = t_size; }
323 303
@@ -340,8 +320,6 @@ void free_message ( MSIMessage *msg )
340 free ( msg->response.header_value ); 320 free ( msg->response.header_value );
341 free ( msg->version.header_value ); 321 free ( msg->version.header_value );
342 free ( msg->info.header_value ); 322 free ( msg->info.header_value );
343 free ( msg->cryptokey.header_value );
344 free ( msg->nonce.header_value );
345 free ( msg->reason.header_value ); 323 free ( msg->reason.header_value );
346 free ( msg->callid.header_value ); 324 free ( msg->callid.header_value );
347 325
@@ -362,7 +340,7 @@ MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id )
362 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 ); 340 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 );
363 341
364 if ( _retu == NULL ) { 342 if ( _retu == NULL ) {
365 LOGGER_WARNING("Allocation failed!"); 343 LOGGER_WARNING("Allocation failed! Program might misbehave!");
366 return NULL; 344 return NULL;
367 } 345 }
368 346
@@ -400,7 +378,7 @@ MSIMessage *parse_message ( const uint8_t *data, uint16_t length )
400 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 ); 378 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 );
401 379
402 if ( _retu == NULL ) { 380 if ( _retu == NULL ) {
403 LOGGER_WARNING("Allocation failed!"); 381 LOGGER_WARNING("Allocation failed! Program might misbehave!");
404 return NULL; 382 return NULL;
405 } 383 }
406 384
@@ -423,43 +401,6 @@ MSIMessage *parse_message ( const uint8_t *data, uint16_t length )
423} 401}
424 402
425 403
426
427/**
428 * @brief Makes clear message presentation
429 *
430 * @param msg Message
431 * @param dest Dest string
432 * @return int
433 */
434int stringify_message(MSIMessage *msg, char *dest)
435{
436#define HDR_TO_STR(__dest, __hdr) if (__hdr.header_value) {\
437 char nltstr[MSI_MAXMSG_SIZE]; memset(nltstr, '\0', MSI_MAXMSG_SIZE); int i = 0; \
438 for ( ; i < __hdr.size; i ++) nltstr[i] = (char)__hdr.header_value[i]; \
439 }
440
441 if ( !msg || !dest )
442 return -1;
443
444 HDR_TO_STR(dest, msg->version);
445 HDR_TO_STR(dest, msg->request);
446 HDR_TO_STR(dest, msg->response);
447 HDR_TO_STR(dest, msg->reason);
448 HDR_TO_STR(dest, msg->callid);
449 HDR_TO_STR(dest, msg->calltype);
450 HDR_TO_STR(dest, msg->cryptokey);
451 HDR_TO_STR(dest, msg->nonce);
452
453// if (msg->version.header_value) {
454// U8_TO_NLTCHAR(msg->version.header_value, msg->version.size, nltstr, MSI_MAXMSG_SIZE);
455// sprintf(dest, "Version: %s\n", nltstr);
456// }
457
458 return 0;
459}
460
461
462
463/** 404/**
464 * @brief Speaks for it self. 405 * @brief Speaks for it self.
465 * 406 *
@@ -479,7 +420,7 @@ uint8_t *append_header_to_string (
479{ 420{
480 if ( dest == NULL ) { 421 if ( dest == NULL ) {
481 LOGGER_ERROR("No destination space!"); 422 LOGGER_ERROR("No destination space!");
482 assert(dest); 423 return NULL;
483 } 424 }
484 425
485 if (header_value == NULL) { 426 if (header_value == NULL) {
@@ -574,8 +515,6 @@ uint16_t message_to_send ( MSIMessage *msg, uint8_t *dest )
574 CLEAN_ASSIGN ( _size, _iterated, INFO_FIELD, msg->info ); 515 CLEAN_ASSIGN ( _size, _iterated, INFO_FIELD, msg->info );
575 CLEAN_ASSIGN ( _size, _iterated, CALLID_FIELD, msg->callid ); 516 CLEAN_ASSIGN ( _size, _iterated, CALLID_FIELD, msg->callid );
576 CLEAN_ASSIGN ( _size, _iterated, REASON_FIELD, msg->reason ); 517 CLEAN_ASSIGN ( _size, _iterated, REASON_FIELD, msg->reason );
577 CLEAN_ASSIGN ( _size, _iterated, CRYPTOKEY_FIELD, msg->cryptokey );
578 CLEAN_ASSIGN ( _size, _iterated, NONCE_FIELD, msg->nonce );
579 518
580 *_iterated = end_byte; 519 *_iterated = end_byte;
581 _size ++; 520 _size ++;
@@ -586,7 +525,7 @@ uint16_t message_to_send ( MSIMessage *msg, uint8_t *dest )
586 525
587#define GENERIC_SETTER_DEFINITION(header) \ 526#define GENERIC_SETTER_DEFINITION(header) \
588void msi_msg_set_##header ( MSIMessage* _msg, const uint8_t* header_value, uint16_t _size ) \ 527void msi_msg_set_##header ( MSIMessage* _msg, const uint8_t* header_value, uint16_t _size ) \
589{ assert(_msg); assert(header_value); \ 528{ if ( !_msg || !header_value) { LOGGER_WARNING("No setter values!"); return; } \
590 free(_msg->header.header_value); \ 529 free(_msg->header.header_value); \
591 ALLOCATE_HEADER( _msg->header, header_value, _size )} 530 ALLOCATE_HEADER( _msg->header, header_value, _size )}
592 531
@@ -594,10 +533,259 @@ GENERIC_SETTER_DEFINITION ( calltype )
594GENERIC_SETTER_DEFINITION ( reason ) 533GENERIC_SETTER_DEFINITION ( reason )
595GENERIC_SETTER_DEFINITION ( info ) 534GENERIC_SETTER_DEFINITION ( info )
596GENERIC_SETTER_DEFINITION ( callid ) 535GENERIC_SETTER_DEFINITION ( callid )
597GENERIC_SETTER_DEFINITION ( cryptokey )
598GENERIC_SETTER_DEFINITION ( nonce )
599 536
600 537
538
539
540typedef struct _Timer {
541 void *(*func)(void *);
542 void *func_arg1;
543 int func_arg2;
544 uint64_t timeout;
545 size_t idx;
546
547} Timer;
548
549typedef struct _TimerHandler {
550 Timer **timers;
551 pthread_mutex_t mutex;
552
553 size_t max_capacity;
554 size_t size;
555 uint64_t resolution;
556
557 _Bool running;
558
559} TimerHandler;
560
561struct timer_function_args {
562 void *arg1;
563 int arg2;
564};
565
566/**
567 * @brief Allocate timer in array
568 *
569 * @param timers_container Handler
570 * @param func Function to be executed
571 * @param arg Its args
572 * @param timeout Timeout in ms
573 * @return int
574 */
575int timer_alloc ( TimerHandler *timers_container, void *(func)(void *), void *arg1, int arg2, unsigned timeout)
576{
577 static int timer_id;
578 pthread_mutex_lock(&timers_container->mutex);
579
580 int i = 0;
581
582 for (; i < timers_container->max_capacity && timers_container->timers[i]; i ++);
583
584 if (i == timers_container->max_capacity) {
585 LOGGER_WARNING("Maximum capacity reached!");
586 pthread_mutex_unlock(&timers_container->mutex);
587 return -1;
588 }
589
590 Timer *timer = timers_container->timers[i] = calloc(sizeof(Timer), 1);
591
592 if (timer == NULL) {
593 LOGGER_ERROR("Failed to allocate timer!");
594 pthread_mutex_unlock(&timers_container->mutex);
595 return -1;
596 }
597
598 timers_container->size ++;
599
600 timer->func = func;
601 timer->func_arg1 = arg1;
602 timer->func_arg2 = arg2;
603 timer->timeout = timeout + current_time_monotonic(); /* In ms */
604 ++timer_id;
605 timer->idx = timer_id;
606
607 /* reorder */
608 if (i) {
609 int j = i - 1;
610
611 for (; j >= 0 && timeout < timers_container->timers[j]->timeout; j--) {
612 Timer *tmp = timers_container->timers[j];
613 timers_container->timers[j] = timer;
614 timers_container->timers[j + 1] = tmp;
615 }
616 }
617
618 pthread_mutex_unlock(&timers_container->mutex);
619
620 LOGGER_DEBUG("Allocated timer index: %d timeout: %d, current size: %d", i, timeout, timers_container->size);
621 return timer->idx;
622}
623
624/**
625 * @brief Remove timer from array
626 *
627 * @param timers_container handler
628 * @param idx timer id
629 * @param lock_mutex (does the mutex need to be locked)
630 * @return int
631 */
632int timer_release ( TimerHandler *timers_container, int idx , int lock_mutex)
633{
634 if (lock_mutex)
635 pthread_mutex_lock(&timers_container->mutex);
636
637 Timer **timed_events = timers_container->timers;
638
639 int i, res = -1;
640
641 for (i = 0; i < timers_container->max_capacity; ++i) {
642 if (timed_events[i] && timed_events[i]->idx == idx) {
643 res = i;
644 break;
645 }
646 }
647
648 if (res == -1) {
649 LOGGER_WARNING("No event with id: %d", idx);
650
651 if (lock_mutex) pthread_mutex_unlock(&timers_container->mutex);
652
653 return -1;
654 }
655
656 free(timed_events[res]);
657
658 timed_events[res] = NULL;
659
660 i = res + 1;
661
662 for (; i < timers_container->max_capacity && timed_events[i]; i ++) {
663 timed_events[i - 1] = timed_events[i];
664 timed_events[i] = NULL;
665 }
666
667 timers_container->size--;
668
669 LOGGER_DEBUG("Popped index: %d, current size: %d ", idx, timers_container->size);
670
671 if (lock_mutex) pthread_mutex_unlock(&timers_container->mutex);
672
673 return 0;
674}
675
676/**
677 * @brief Main poll for timer execution
678 *
679 * @param arg ...
680 * @return void*
681 */
682void *timer_poll( void *arg )
683{
684 TimerHandler *handler = arg;
685
686 while ( handler->running ) {
687
688 pthread_mutex_lock(&handler->mutex);
689
690 if ( handler->running ) {
691
692 uint64_t time = current_time_monotonic();
693
694 if ( handler->timers[0] && handler->timers[0]->timeout < time ) {
695 pthread_t _tid;
696
697 struct timer_function_args *args = malloc(sizeof(struct timer_function_args));
698 args->arg1 = handler->timers[0]->func_arg1;
699 args->arg2 = handler->timers[0]->func_arg2;
700
701 if ( 0 != pthread_create(&_tid, NULL, handler->timers[0]->func, args) ||
702 0 != pthread_detach(_tid) ) {
703 LOGGER_ERROR("Failed to execute timer at: %d!", handler->timers[0]->timeout);
704 free(args);
705 } else {
706 LOGGER_DEBUG("Exectued timer assigned at: %d", handler->timers[0]->timeout);
707 }
708
709 timer_release(handler, handler->timers[0]->idx, 0);
710 }
711
712 }
713
714 pthread_mutex_unlock(&handler->mutex);
715
716 usleep(handler->resolution);
717 }
718
719 pthread_exit(NULL);
720}
721
722/**
723 * @brief Start timer poll and return handler
724 *
725 * @param max_capacity capacity
726 * @param resolution ...
727 * @return TimerHandler*
728 */
729TimerHandler *timer_init_session (int max_capacity, int resolution)
730{
731 TimerHandler *handler = calloc(1, sizeof(TimerHandler));
732
733 if (handler == NULL) {
734 LOGGER_ERROR("Failed to allocate memory, program might misbehave!");
735 return NULL;
736 }
737
738 handler->timers = calloc(max_capacity, sizeof(Timer *));
739
740 if (handler->timers == NULL) {
741 LOGGER_ERROR("Failed to allocate %d timed events!", max_capacity);
742 free(handler);
743 return NULL;
744 }
745
746 handler->max_capacity = max_capacity;
747 handler->running = 1;
748 handler->resolution = resolution;
749
750 pthread_mutex_init(&handler->mutex, NULL);
751
752
753 pthread_t _tid;
754
755 if ( 0 != pthread_create(&_tid, NULL, timer_poll, handler) || 0 != pthread_detach(_tid) ) {
756 LOGGER_ERROR("Failed to start timer poll thread!");
757 free(handler->timers);
758 free(handler);
759 return NULL;
760 }
761
762 return handler;
763}
764
765/**
766 * @brief Terminate timer session
767 *
768 * @param handler The timer handler
769 * @return void
770 */
771void timer_terminate_session(TimerHandler *handler)
772{
773 pthread_mutex_lock(&handler->mutex);
774
775 handler->running = 0;
776
777 pthread_mutex_unlock(&handler->mutex);
778
779 int i = 0;
780
781 for (; i < handler->max_capacity; i ++)
782 free(handler->timers[i]);
783
784 free(handler->timers);
785
786 pthread_mutex_destroy( &handler->mutex );
787}
788
601/** 789/**
602 * @brief Generate _random_ alphanumerical string. 790 * @brief Generate _random_ alphanumerical string.
603 * 791 *
@@ -605,7 +793,7 @@ GENERIC_SETTER_DEFINITION ( nonce )
605 * @param size Size of string. 793 * @param size Size of string.
606 * @return void 794 * @return void
607 */ 795 */
608void t_randomstr ( uint8_t *str, size_t size ) 796void t_randomstr ( uint8_t *str, uint32_t size )
609{ 797{
610 if (str == NULL) { 798 if (str == NULL) {
611 LOGGER_DEBUG("Empty destination!"); 799 LOGGER_DEBUG("Empty destination!");
@@ -617,7 +805,7 @@ void t_randomstr ( uint8_t *str, size_t size )
617 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 805 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
618 "abcdefghijklmnopqrstuvwxyz"; 806 "abcdefghijklmnopqrstuvwxyz";
619 807
620 size_t _it = 0; 808 uint32_t _it = 0;
621 809
622 for ( ; _it < size; _it++ ) { 810 for ( ; _it < size; _it++ ) {
623 str[_it] = _bytes[ random_int() % 61 ]; 811 str[_it] = _bytes[ random_int() % 61 ];
@@ -626,7 +814,8 @@ void t_randomstr ( uint8_t *str, size_t size )
626 814
627 815
628typedef enum { 816typedef enum {
629 error_deadcall = 1, /* has call id but it's from old call */ 817 error_none,
818 error_deadcall, /* has call id but it's from old call */
630 error_id_mismatch, /* non-existing call */ 819 error_id_mismatch, /* non-existing call */
631 820
632 error_no_callid, /* not having call id */ 821 error_no_callid, /* not having call id */
@@ -704,14 +893,6 @@ int send_message ( MSISession *session, MSICall *call, MSIMessage *msg, uint32_t
704 return -1; 893 return -1;
705 } 894 }
706 895
707 /*
708 LOGGER_SCOPE(
709 char cast[MSI_MAXMSG_SIZE];
710 stringify_message(msg, cast);
711 LOGGER_DEBUG("[Call: %s] [to: %u] Sending message: len: %d\n%s", call->id, to, _length, cast);
712 );*/
713
714
715 if ( m_msi_packet(session->messenger_handle, to, _msg_string_final, _length) ) { 896 if ( m_msi_packet(session->messenger_handle, to, _msg_string_final, _length) ) {
716 LOGGER_DEBUG("Sent message"); 897 LOGGER_DEBUG("Sent message");
717 return 0; 898 return 0;
@@ -732,13 +913,7 @@ int send_message ( MSISession *session, MSICall *call, MSIMessage *msg, uint32_t
732 */ 913 */
733int call_id_bigger( const uint8_t *first, const uint8_t *second) 914int call_id_bigger( const uint8_t *first, const uint8_t *second)
734{ 915{
735 int i = 0; 916 return (memcmp(first, second, CALL_ID_LEN) < 0);
736
737 for (; i < CALL_ID_LEN; i ++) {
738
739 if ( first[i] != second[i] )
740 return first[i] > second [i] ? 0 : 1;
741 }
742} 917}
743 918
744 919
@@ -804,7 +979,11 @@ MSICall *find_call ( MSISession *session, uint8_t *call_id )
804 979
805 for (; i < session->max_calls; i ++ ) 980 for (; i < session->max_calls; i ++ )
806 if ( session->calls[i] && memcmp(session->calls[i]->id, call_id, CALL_ID_LEN) == 0 ) { 981 if ( session->calls[i] && memcmp(session->calls[i]->id, call_id, CALL_ID_LEN) == 0 ) {
807 LOGGER_DEBUG("Found call id: %s", session->calls[i]->id); 982 LOGGER_SCOPE(
983 char tmp[CALL_ID_LEN + 1] = {'\0'};
984 memcpy(tmp, session->calls[i]->id, CALL_ID_LEN);
985 LOGGER_DEBUG("Found call id: %s", tmp);
986 );
808 return session->calls[i]; 987 return session->calls[i];
809 } 988 }
810 989
@@ -818,9 +997,9 @@ MSICall *find_call ( MSISession *session, uint8_t *call_id )
818 * @param errid The id. 997 * @param errid The id.
819 * @param to Where to? 998 * @param to Where to?
820 * @return int 999 * @return int
821 * @retval 0 It's always success. 1000 * @retval -1/0 It's usually always success.
822 */ 1001 */
823int handle_error ( MSISession *session, MSICall *call, MSICallError errid, uint32_t to ) 1002int send_error ( MSISession *session, MSICall *call, MSICallError errid, uint32_t to )
824{ 1003{
825 if (!call) { 1004 if (!call) {
826 LOGGER_WARNING("Cannot handle error on 'null' call"); 1005 LOGGER_WARNING("Cannot handle error on 'null' call");
@@ -840,38 +1019,12 @@ int handle_error ( MSISession *session, MSICall *call, MSICallError errid, uint3
840 session->last_error_id = errid; 1019 session->last_error_id = errid;
841 session->last_error_str = stringify_error ( errid ); 1020 session->last_error_str = stringify_error ( errid );
842 1021
843 invoke_callback(call->call_idx, MSI_OnError); 1022 /* invoke_callback(call->call_idx, MSI_OnError); */
844 1023
845 return 0; 1024 return 0;
846} 1025}
847 1026
848 1027
849/**
850 * @brief Determine the error if any.
851 *
852 * @param session Control session.
853 * @param msg The message.
854 * @return int
855 * @retval -1 No error.
856 * @retval 0 Error occurred and response sent.
857 */
858int has_call_error ( MSISession *session, MSICall *call, MSIMessage *msg )
859{
860 if ( !msg->callid.header_value ) {
861 return handle_error ( session, call, error_no_callid, msg->friend_id );
862
863 } else if ( !call ) {
864 LOGGER_WARNING("Handling message while no call!");
865 return 0;
866
867 } else if ( memcmp ( call->id, msg->callid.header_value, CALL_ID_LEN ) != 0 ) {
868 return handle_error ( session, call, error_id_mismatch, msg->friend_id );
869
870 }
871
872 return -1;
873}
874
875 1028
876/** 1029/**
877 * @brief Add peer to peer list. 1030 * @brief Add peer to peer list.
@@ -882,14 +1035,16 @@ int has_call_error ( MSISession *session, MSICall *call, MSIMessage *msg )
882 */ 1035 */
883void add_peer( MSICall *call, int peer_id ) 1036void add_peer( MSICall *call, int peer_id )
884{ 1037{
885 if ( !call->peers ) { 1038 uint32_t *peers = !call->peers ? peers = calloc(sizeof(uint32_t), 1) :
886 call->peers = calloc(sizeof(uint32_t), 1); 1039 realloc( call->peers, sizeof(uint32_t) * call->peer_count);
887 call->peer_count = 1; 1040
888 } else { 1041 if (!peers) {
889 call->peer_count ++; 1042 LOGGER_WARNING("Allocation failed! Program might misbehave!");
890 call->peers = realloc( call->peers, sizeof(uint32_t) * call->peer_count); 1043 return;
891 } 1044 }
892 1045
1046 call->peer_count ++;
1047 call->peers = peers;
893 call->peers[call->peer_count - 1] = peer_id; 1048 call->peers[call->peer_count - 1] = peer_id;
894 1049
895 LOGGER_DEBUG("Added peer: %d", peer_id); 1050 LOGGER_DEBUG("Added peer: %d", peer_id);
@@ -912,54 +1067,49 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
912 return NULL; 1067 return NULL;
913 } 1068 }
914 1069
915 int32_t _call_idx = 0; 1070 int32_t call_idx = 0;
1071
1072 for (; call_idx < session->max_calls; call_idx ++) {
1073 if ( !session->calls[call_idx] ) {
1074
1075 if (!(session->calls[call_idx] = calloc ( sizeof ( MSICall ), 1 ))) {
1076 LOGGER_WARNING("Allocation failed! Program might misbehave!");
1077 return NULL;
1078 }
916 1079
917 for (; _call_idx < session->max_calls; _call_idx ++) {
918 if ( !session->calls[_call_idx] ) {
919 session->calls[_call_idx] = calloc ( sizeof ( MSICall ), 1 );
920 break; 1080 break;
921 } 1081 }
922 } 1082 }
923 1083
924 if ( _call_idx == session->max_calls ) { 1084 if ( call_idx == session->max_calls ) {
925 LOGGER_WARNING("Reached maximum amount of calls!"); 1085 LOGGER_WARNING("Reached maximum amount of calls!");
926 return NULL; 1086 return NULL;
927 } 1087 }
928 1088
929 1089
930 MSICall *_call = session->calls[_call_idx]; 1090 MSICall *call = session->calls[call_idx];
931 1091
932 if ( _call == NULL ) { 1092 call->call_idx = call_idx;
933 LOGGER_WARNING("Allocation failed!");
934 return NULL;
935 }
936
937 _call->call_idx = _call_idx;
938 _call->type_peer = calloc ( sizeof ( MSICallType ), peers );
939 1093
940 if ( _call->type_peer == NULL ) { 1094 if ( !(call->type_peer = calloc ( sizeof ( MSICallType ), peers )) ) {
941 LOGGER_WARNING("Allocation failed!"); 1095 LOGGER_WARNING("Allocation failed! Program might misbehave!");
1096 free(call);
942 return NULL; 1097 return NULL;
943 } 1098 }
944 1099
945 _call->session = session; 1100 call->session = session;
946 1101
947 /*_call->_participant_count = _peers;*/ 1102 /*_call->_participant_count = _peers;*/
948 1103
949 _call->request_timer_id = 0; 1104 call->request_timer_id = 0;
950 _call->ringing_timer_id = 0; 1105 call->ringing_timer_id = 0;
951 1106
952 _call->key_local = NULL; 1107 call->ringing_tout_ms = ringing_timeout;
953 _call->key_peer = NULL;
954 _call->nonce_local = NULL;
955 _call->nonce_peer = NULL;
956 1108
957 _call->ringing_tout_ms = ringing_timeout; 1109 pthread_mutex_init ( &call->mutex, NULL );
958 1110
959 pthread_mutex_init ( &_call->mutex, NULL ); 1111 LOGGER_DEBUG("Started new call with index: %u", call_idx);
960 1112 return call;
961 LOGGER_DEBUG("Started new call with index: %u", _call_idx);
962 return _call;
963} 1113}
964 1114
965 1115
@@ -985,8 +1135,8 @@ int terminate_call ( MSISession *session, MSICall *call )
985 * NOTE: This has to be done before possibly 1135 * NOTE: This has to be done before possibly
986 * locking the mutex the second time 1136 * locking the mutex the second time
987 */ 1137 */
988 event.timer_release ( call->request_timer_id ); 1138 timer_release ( session->timer_handler, call->request_timer_id, 1);
989 event.timer_release ( call->ringing_timer_id ); 1139 timer_release ( session->timer_handler, call->ringing_timer_id, 1);
990 1140
991 /* Get a handle */ 1141 /* Get a handle */
992 pthread_mutex_lock ( &call->mutex ); 1142 pthread_mutex_lock ( &call->mutex );
@@ -994,8 +1144,6 @@ int terminate_call ( MSISession *session, MSICall *call )
994 session->calls[call->call_idx] = NULL; 1144 session->calls[call->call_idx] = NULL;
995 1145
996 free ( call->type_peer ); 1146 free ( call->type_peer );
997 free ( call->key_local );
998 free ( call->key_peer );
999 free ( call->peers); 1147 free ( call->peers);
1000 1148
1001 /* Release handle */ 1149 /* Release handle */
@@ -1024,12 +1172,15 @@ void *handle_timeout ( void *arg )
1024 * timers on these cancels and terminate call on 1172 * timers on these cancels and terminate call on
1025 * their timeout 1173 * their timeout
1026 */ 1174 */
1027 MSICall *_call = arg; 1175 struct timer_function_args *args = arg;
1176 int call_index = args->arg2;
1177 MSISession *session = args->arg1;
1178 MSICall *_call = session->calls[call_index];
1028 1179
1029 if (_call) { 1180 if (_call) {
1030 LOGGER_DEBUG("[Call: %s] Request timed out!", _call->id); 1181 LOGGER_DEBUG("[Call: %s] Request timed out!", _call->id);
1031 1182
1032 invoke_callback(_call->call_idx, MSI_OnRequestTimeout); 1183 invoke_callback(call_index, MSI_OnRequestTimeout);
1033 } 1184 }
1034 1185
1035 if ( _call && _call->session ) { 1186 if ( _call && _call->session ) {
@@ -1041,6 +1192,7 @@ void *handle_timeout ( void *arg )
1041 /*terminate_call(_call->session, _call);*/ 1192 /*terminate_call(_call->session, _call);*/
1042 } 1193 }
1043 1194
1195 free(arg);
1044 pthread_exit(NULL); 1196 pthread_exit(NULL);
1045} 1197}
1046 1198
@@ -1081,7 +1233,8 @@ int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *msg )
1081 } 1233 }
1082 1234
1083 } else { 1235 } else {
1084 handle_error ( session, call, error_busy, msg->friend_id ); /* TODO: Ugh*/ 1236 send_error ( session, call, error_busy, msg->friend_id ); /* TODO: Ugh*/
1237 terminate_call(session, call);
1085 pthread_mutex_unlock(&session->mutex); 1238 pthread_mutex_unlock(&session->mutex);
1086 return 0; 1239 return 0;
1087 } 1240 }
@@ -1096,7 +1249,8 @@ int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *msg )
1096 } 1249 }
1097 1250
1098 if ( !msg->callid.header_value ) { 1251 if ( !msg->callid.header_value ) {
1099 handle_error ( session, call, error_no_callid, msg->friend_id ); 1252 send_error ( session, call, error_no_callid, msg->friend_id );
1253 terminate_call(session, call);
1100 pthread_mutex_unlock(&session->mutex); 1254 pthread_mutex_unlock(&session->mutex);
1101 return 0; 1255 return 0;
1102 } 1256 }
@@ -1120,29 +1274,17 @@ int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *msg )
1120} 1274}
1121int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *msg ) 1275int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *msg )
1122{ 1276{
1277 if ( !call ) {
1278 LOGGER_WARNING("Session: %p Handling 'start' on no call");
1279 return 0;
1280 }
1281
1123 LOGGER_DEBUG("Session: %p Handling 'start' on call: %s, friend id: %d", session, call->id, msg->friend_id ); 1282 LOGGER_DEBUG("Session: %p Handling 'start' on call: %s, friend id: %d", session, call->id, msg->friend_id );
1124 1283
1125 pthread_mutex_lock(&session->mutex); 1284 pthread_mutex_lock(&session->mutex);
1126 1285
1127 if ( has_call_error ( session, call, msg ) == 0 ) {
1128 pthread_mutex_unlock(&session->mutex);
1129 return -1;
1130 }
1131
1132 if ( !msg->cryptokey.header_value ) {
1133 int rc = handle_error ( session, call, error_no_crypto_key, msg->friend_id );
1134 pthread_mutex_unlock(&session->mutex);
1135 return rc;
1136 }
1137
1138 call->state = call_active; 1286 call->state = call_active;
1139 1287
1140 call->key_peer = calloc ( sizeof ( uint8_t ), crypto_box_KEYBYTES );
1141 memcpy ( call->key_peer, msg->cryptokey.header_value, crypto_box_KEYBYTES );
1142
1143 call->nonce_peer = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES );
1144 memcpy ( call->nonce_peer, msg->nonce.header_value, crypto_box_NONCEBYTES );
1145
1146 flush_peer_type ( call, msg, 0 ); 1288 flush_peer_type ( call, msg, 0 );
1147 1289
1148 pthread_mutex_unlock(&session->mutex); 1290 pthread_mutex_unlock(&session->mutex);
@@ -1152,15 +1294,14 @@ int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *msg )
1152} 1294}
1153int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *msg ) 1295int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *msg )
1154{ 1296{
1155 LOGGER_DEBUG("Session: %p Handling 'reject' on call: %s", session, call->id); 1297 if ( !call ) {
1156 1298 LOGGER_WARNING("Session: %p Handling 'start' on no call");
1157 pthread_mutex_lock(&session->mutex);
1158
1159 if ( has_call_error ( session, call, msg ) == 0 ) {
1160 pthread_mutex_unlock(&session->mutex);
1161 return 0; 1299 return 0;
1162 } 1300 }
1163 1301
1302 LOGGER_DEBUG("Session: %p Handling 'reject' on call: %s", session, call->id);
1303
1304 pthread_mutex_lock(&session->mutex);
1164 1305
1165 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) ); 1306 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) );
1166 send_message ( session, call, _msg_ending, msg->friend_id ); 1307 send_message ( session, call, _msg_ending, msg->friend_id );
@@ -1170,30 +1311,22 @@ int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *msg )
1170 pthread_mutex_unlock(&session->mutex); 1311 pthread_mutex_unlock(&session->mutex);
1171 1312
1172 invoke_callback(call->call_idx, MSI_OnReject); 1313 invoke_callback(call->call_idx, MSI_OnReject);
1173 /*
1174 event.timer_release ( session->call->request_timer_id );
1175 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
1176 */
1177 1314
1178 terminate_call(session, call); 1315 terminate_call(session, call);
1179 return 1; 1316 return 1;
1180} 1317}
1181int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *msg ) 1318int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *msg )
1182{ 1319{
1320 if ( !call ) {
1321 LOGGER_WARNING("Session: %p Handling 'start' on no call");
1322 return 0;
1323 }
1324
1183 LOGGER_DEBUG("Session: %p Handling 'cancel' on call: %s", session, call->id ); 1325 LOGGER_DEBUG("Session: %p Handling 'cancel' on call: %s", session, call->id );
1184 1326
1185 pthread_mutex_lock(&session->mutex); 1327 pthread_mutex_lock(&session->mutex);
1186 1328
1187 if ( has_call_error ( session, call, msg ) == 0 ) {
1188 pthread_mutex_unlock(&session->mutex);
1189 return 0;
1190 }
1191
1192 /* Act as end message */ 1329 /* Act as end message */
1193 /*
1194 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) );
1195 send_message ( session, call, _msg_ending, msg->friend_id );
1196 free_message ( _msg_ending );*/
1197 1330
1198 pthread_mutex_unlock(&session->mutex); 1331 pthread_mutex_unlock(&session->mutex);
1199 invoke_callback(call->call_idx, MSI_OnCancel); 1332 invoke_callback(call->call_idx, MSI_OnCancel);
@@ -1203,15 +1336,15 @@ int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *msg )
1203} 1336}
1204int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg ) 1337int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg )
1205{ 1338{
1339 if ( !call ) {
1340 LOGGER_WARNING("Session: %p Handling 'start' on no call");
1341 return 0;
1342 }
1343
1206 LOGGER_DEBUG("Session: %p Handling 'end' on call: %s", session, call->id ); 1344 LOGGER_DEBUG("Session: %p Handling 'end' on call: %s", session, call->id );
1207 1345
1208 pthread_mutex_lock(&session->mutex); 1346 pthread_mutex_lock(&session->mutex);
1209 1347
1210 if ( has_call_error ( session, call, msg ) == 0 ) {
1211 pthread_mutex_unlock(&session->mutex);
1212 return 0;
1213 }
1214
1215 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) ); 1348 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) );
1216 send_message ( session, call, _msg_ending, msg->friend_id ); 1349 send_message ( session, call, _msg_ending, msg->friend_id );
1217 free_message ( _msg_ending ); 1350 free_message ( _msg_ending );
@@ -1227,16 +1360,23 @@ int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg )
1227/********** Response handlers **********/ 1360/********** Response handlers **********/
1228int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg ) 1361int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg )
1229{ 1362{
1363 if ( !call ) {
1364 LOGGER_WARNING("Session: %p Handling 'start' on no call");
1365 return 0;
1366 }
1367
1230 pthread_mutex_lock(&session->mutex); 1368 pthread_mutex_lock(&session->mutex);
1231 1369
1232 if ( has_call_error ( session, call, msg ) == 0 ) { 1370 if ( call->ringing_timer_id ) {
1371 LOGGER_WARNING("Call already ringing");
1233 pthread_mutex_unlock(&session->mutex); 1372 pthread_mutex_unlock(&session->mutex);
1234 return 0; 1373 return 0;
1235 } 1374 }
1236 1375
1237 LOGGER_DEBUG("Session: %p Handling 'ringing' on call: %s", session, call->id ); 1376 LOGGER_DEBUG("Session: %p Handling 'ringing' on call: %s", session, call->id );
1238 1377
1239 call->ringing_timer_id = event.timer_alloc ( handle_timeout, call, call->ringing_tout_ms ); 1378 call->ringing_timer_id = timer_alloc ( session->timer_handler, handle_timeout, session, call->call_idx,
1379 call->ringing_tout_ms );
1240 1380
1241 pthread_mutex_unlock(&session->mutex); 1381 pthread_mutex_unlock(&session->mutex);
1242 1382
@@ -1245,48 +1385,25 @@ int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg )
1245} 1385}
1246int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg ) 1386int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg )
1247{ 1387{
1248 pthread_mutex_lock(&session->mutex); 1388 if ( !call ) {
1249 1389 LOGGER_WARNING("Session: %p Handling 'start' on no call");
1250 if ( has_call_error ( session, call, msg ) == 0 ) {
1251 pthread_mutex_unlock(&session->mutex);
1252 return 0; 1390 return 0;
1253 } 1391 }
1254 1392
1255 LOGGER_DEBUG("Session: %p Handling 'starting' on call: %s", session, call->id ); 1393 pthread_mutex_lock(&session->mutex);
1256
1257
1258 if ( !msg->cryptokey.header_value ) {
1259 int rc = handle_error ( session, call, error_no_crypto_key, msg->friend_id );
1260 pthread_mutex_unlock(&session->mutex);
1261 return rc;
1262 }
1263
1264 /* Generate local key/nonce to send */
1265 call->key_local = calloc ( sizeof ( uint8_t ), crypto_box_KEYBYTES );
1266 new_symmetric_key ( call->key_local );
1267
1268 call->nonce_local = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES );
1269 new_nonce ( call->nonce_local );
1270
1271 /* Save peer key/nonce */
1272 call->key_peer = calloc ( sizeof ( uint8_t ), crypto_box_KEYBYTES );
1273 memcpy ( call->key_peer, msg->cryptokey.header_value, crypto_box_KEYBYTES );
1274 1394
1275 call->nonce_peer = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES ); 1395 LOGGER_DEBUG("Session: %p Handling 'starting' on call: %s", session, call->id );
1276 memcpy ( call->nonce_peer, msg->nonce.header_value, crypto_box_NONCEBYTES );
1277 1396
1278 call->state = call_active; 1397 call->state = call_active;
1279 1398
1280 MSIMessage *_msg_start = msi_new_message ( TYPE_REQUEST, stringify_request ( start ) ); 1399 MSIMessage *_msg_start = msi_new_message ( TYPE_REQUEST, stringify_request ( start ) );
1281 msi_msg_set_cryptokey ( _msg_start, call->key_local, crypto_box_KEYBYTES );
1282 msi_msg_set_nonce ( _msg_start, call->nonce_local, crypto_box_NONCEBYTES );
1283 send_message ( session, call, _msg_start, msg->friend_id ); 1400 send_message ( session, call, _msg_start, msg->friend_id );
1284 free_message ( _msg_start ); 1401 free_message ( _msg_start );
1285 1402
1286 flush_peer_type ( call, msg, 0 ); 1403 flush_peer_type ( call, msg, 0 );
1287 1404
1288 1405
1289 event.timer_release ( call->ringing_timer_id ); 1406 timer_release ( session->timer_handler, call->ringing_timer_id, 1 );
1290 pthread_mutex_unlock(&session->mutex); 1407 pthread_mutex_unlock(&session->mutex);
1291 1408
1292 invoke_callback(call->call_idx, MSI_OnStarting); 1409 invoke_callback(call->call_idx, MSI_OnStarting);
@@ -1294,17 +1411,17 @@ int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg )
1294} 1411}
1295int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg ) 1412int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg )
1296{ 1413{
1297 pthread_mutex_lock(&session->mutex); 1414 if ( !call ) {
1298 1415 LOGGER_WARNING("Session: %p Handling 'start' on no call");
1299 if ( has_call_error ( session, call, msg ) == 0 ) {
1300 pthread_mutex_unlock(&session->mutex);
1301 return 0; 1416 return 0;
1302 } 1417 }
1303 1418
1419 pthread_mutex_lock(&session->mutex);
1420
1304 LOGGER_DEBUG("Session: %p Handling 'ending' on call: %s", session, call->id ); 1421 LOGGER_DEBUG("Session: %p Handling 'ending' on call: %s", session, call->id );
1305 1422
1306 /* Stop timer */ 1423 /* Stop timer */
1307 event.timer_release ( call->request_timer_id ); 1424 timer_release ( session->timer_handler, call->request_timer_id, 1 );
1308 1425
1309 pthread_mutex_unlock(&session->mutex); 1426 pthread_mutex_unlock(&session->mutex);
1310 1427
@@ -1376,95 +1493,94 @@ int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *msg )
1376 * 1493 *
1377 * 1494 *
1378 */ 1495 */
1379void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16_t length, void *object ) 1496void msi_handle_packet ( Messenger *messenger, int source, const uint8_t *data, uint16_t length, void *object )
1380{ 1497{
1381 LOGGER_DEBUG("Got msi message"); 1498 LOGGER_DEBUG("Got msi message");
1382 /* Unused */ 1499 /* Unused */
1383 (void)messenger; 1500 (void)messenger;
1384 1501
1385 MSISession *_session = object; 1502 MSISession *session = object;
1386 MSIMessage *_msg; 1503 MSIMessage *msg;
1387 1504
1388 if ( !length ) { 1505 if ( !length ) {
1389 LOGGER_WARNING("Lenght param negative"); 1506 LOGGER_WARNING("Lenght param negative");
1390 return; 1507 return;
1391 } 1508 }
1392 1509
1393 _msg = parse_message ( data, length ); 1510 msg = parse_message ( data, length );
1394 1511
1395 if ( !_msg ) { 1512 if ( !msg ) {
1396 LOGGER_WARNING("Error parsing message"); 1513 LOGGER_WARNING("Error parsing message");
1397 return; 1514 return;
1398 } else { 1515 } else {
1399 LOGGER_DEBUG("Successfully parsed message"); 1516 LOGGER_DEBUG("Successfully parsed message");
1400 } 1517 }
1401 1518
1402 _msg->friend_id = source; 1519 msg->friend_id = source;
1403 1520
1404 1521
1405 /* Find what call */ 1522 /* Find what call */
1406 MSICall *_call = _msg->callid.header_value ? find_call(_session, _msg->callid.header_value ) : NULL; 1523 MSICall *call = msg->callid.header_value ? find_call(session, msg->callid.header_value ) : NULL;
1407 1524
1408 /* Now handle message */ 1525 /* Now handle message */
1409 1526
1410 if ( _msg->request.header_value ) { /* Handle request */ 1527 if ( msg->request.header_value ) { /* Handle request */
1411 1528
1412 if ( _msg->response.size > 32 ) { 1529 if ( msg->response.size > 32 ) {
1413 LOGGER_WARNING("Header size too big"); 1530 LOGGER_WARNING("Header size too big");
1414 goto free_end; 1531 goto free_end;
1415 } 1532 }
1416 1533
1417 uint8_t _request_value[32]; 1534 uint8_t _request_value[32];
1418 1535
1419 memcpy(_request_value, _msg->request.header_value, _msg->request.size); 1536 memcpy(_request_value, msg->request.header_value, msg->request.size);
1420 _request_value[_msg->request.size] = '\0'; 1537 _request_value[msg->request.size] = '\0';
1421 1538
1422 if ( same ( _request_value, stringify_request ( invite ) ) ) { 1539 if ( same ( _request_value, stringify_request ( invite ) ) ) {
1423 handle_recv_invite ( _session, _call, _msg ); 1540 handle_recv_invite ( session, call, msg );
1424 1541
1425 } else if ( same ( _request_value, stringify_request ( start ) ) ) { 1542 } else if ( same ( _request_value, stringify_request ( start ) ) ) {
1426 handle_recv_start ( _session, _call, _msg ); 1543 handle_recv_start ( session, call, msg );
1427 1544
1428 } else if ( same ( _request_value, stringify_request ( cancel ) ) ) { 1545 } else if ( same ( _request_value, stringify_request ( cancel ) ) ) {
1429 handle_recv_cancel ( _session, _call, _msg ); 1546 handle_recv_cancel ( session, call, msg );
1430 1547
1431 } else if ( same ( _request_value, stringify_request ( reject ) ) ) { 1548 } else if ( same ( _request_value, stringify_request ( reject ) ) ) {
1432 handle_recv_reject ( _session, _call, _msg ); 1549 handle_recv_reject ( session, call, msg );
1433 1550
1434 } else if ( same ( _request_value, stringify_request ( end ) ) ) { 1551 } else if ( same ( _request_value, stringify_request ( end ) ) ) {
1435 handle_recv_end ( _session, _call, _msg ); 1552 handle_recv_end ( session, call, msg );
1436 } else { 1553 } else {
1437 LOGGER_WARNING("Uknown request"); 1554 LOGGER_WARNING("Uknown request");
1438 goto free_end; 1555 goto free_end;
1439 } 1556 }
1440 1557
1441 } else if ( _msg->response.header_value ) { /* Handle response */ 1558 } else if ( msg->response.header_value ) { /* Handle response */
1442 1559
1443 if ( _msg->response.size > 32 ) { 1560 if ( msg->response.size > 32 ) {
1444 LOGGER_WARNING("Header size too big"); 1561 LOGGER_WARNING("Header size too big");
1445 goto free_end; 1562 goto free_end;
1446 } 1563 }
1447 1564
1448 /* Got response so cancel timer */ 1565 /* Got response so cancel timer */
1449 if ( _call ) 1566 if ( call ) timer_release ( session->timer_handler, call->request_timer_id, 1 );
1450 event.timer_release ( _call->request_timer_id );
1451 1567
1452 uint8_t _response_value[32]; 1568 uint8_t _response_value[32];
1453 1569
1454 memcpy(_response_value, _msg->response.header_value, _msg->response.size); 1570 memcpy(_response_value, msg->response.header_value, msg->response.size);
1455 _response_value[_msg->response.size] = '\0'; 1571 _response_value[msg->response.size] = '\0';
1456 1572
1457 if ( same ( _response_value, stringify_response ( ringing ) ) ) { 1573 if ( same ( _response_value, stringify_response ( ringing ) ) ) {
1458 handle_recv_ringing ( _session, _call, _msg ); 1574 handle_recv_ringing ( session, call, msg );
1459 1575
1460 } else if ( same ( _response_value, stringify_response ( starting ) ) ) { 1576 } else if ( same ( _response_value, stringify_response ( starting ) ) ) {
1461 handle_recv_starting ( _session, _call, _msg ); 1577 handle_recv_starting ( session, call, msg );
1462 1578
1463 } else if ( same ( _response_value, stringify_response ( ending ) ) ) { 1579 } else if ( same ( _response_value, stringify_response ( ending ) ) ) {
1464 handle_recv_ending ( _session, _call, _msg ); 1580 handle_recv_ending ( session, call, msg );
1465 1581
1466 } else if ( same ( _response_value, stringify_response ( error ) ) ) { 1582 } else if ( same ( _response_value, stringify_response ( error ) ) ) {
1467 handle_recv_error ( _session, _call, _msg ); 1583 handle_recv_error ( session, call, msg );
1468 1584
1469 } else { 1585 } else {
1470 LOGGER_WARNING("Uknown response"); 1586 LOGGER_WARNING("Uknown response");
@@ -1476,7 +1592,7 @@ void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16
1476 } 1592 }
1477 1593
1478free_end: 1594free_end:
1479 free_message ( _msg ); 1595 free_message ( msg );
1480} 1596}
1481 1597
1482 1598
@@ -1509,34 +1625,45 @@ MSISession *msi_init_session ( Messenger *messenger, int32_t max_calls )
1509 return NULL; 1625 return NULL;
1510 } 1626 }
1511 1627
1512 if ( !max_calls) return NULL; 1628 TimerHandler *handler = timer_init_session(max_calls * 10, 10000);
1513 1629
1514 MSISession *_retu = calloc ( sizeof ( MSISession ), 1 ); 1630 if ( !max_calls || !handler ) {
1631 LOGGER_WARNING("Invalid max call treshold or timer handler initialization failed!");
1632 return NULL;
1633 }
1515 1634
1516 if (_retu == NULL) { 1635 MSISession *retu = calloc ( sizeof ( MSISession ), 1 );
1517 LOGGER_ERROR("Allocation failed!"); 1636
1637 if (retu == NULL) {
1638 LOGGER_ERROR("Allocation failed! Program might misbehave!");
1518 return NULL; 1639 return NULL;
1519 } 1640 }
1520 1641
1521 _retu->messenger_handle = messenger; 1642 retu->messenger_handle = messenger;
1522 _retu->agent_handler = NULL; 1643 retu->agent_handler = NULL;
1644 retu->timer_handler = handler;
1645
1646 if (!(retu->calls = calloc( sizeof (MSICall *), max_calls ))) {
1647 LOGGER_ERROR("Allocation failed! Program might misbehave!");
1648 free(retu);
1649 return NULL;
1650 }
1523 1651
1524 _retu->calls = calloc( sizeof (MSICall *), max_calls ); 1652 retu->max_calls = max_calls;
1525 _retu->max_calls = max_calls;
1526 1653
1527 _retu->frequ = 10000; /* default value? */ 1654 retu->frequ = 10000; /* default value? */
1528 _retu->call_timeout = 30000; /* default value? */ 1655 retu->call_timeout = 30000; /* default value? */
1529 1656
1530 1657
1531 m_callback_msi_packet(messenger, msi_handle_packet, _retu ); 1658 m_callback_msi_packet(messenger, msi_handle_packet, retu );
1532 1659
1533 /* This is called when remote terminates session */ 1660 /* This is called when remote terminates session */
1534 m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, _retu); 1661 m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, retu);
1535 1662
1536 pthread_mutex_init(&_retu->mutex, NULL); 1663 pthread_mutex_init(&retu->mutex, NULL);
1537 1664
1538 LOGGER_DEBUG("New msi session: %p max calls: %u", _retu, max_calls); 1665 LOGGER_DEBUG("New msi session: %p max calls: %u", retu, max_calls);
1539 return _retu; 1666 return retu;
1540} 1667}
1541 1668
1542 1669
@@ -1571,6 +1698,7 @@ int msi_terminate_session ( MSISession *session )
1571 msi_cancel ( session, idx, session->calls[idx]->peers [_it], "MSI session terminated!" ); 1698 msi_cancel ( session, idx, session->calls[idx]->peers [_it], "MSI session terminated!" );
1572 } 1699 }
1573 1700
1701 timer_terminate_session(session->timer_handler);
1574 1702
1575 pthread_mutex_destroy(&session->mutex); 1703 pthread_mutex_destroy(&session->mutex);
1576 1704
@@ -1626,7 +1754,7 @@ int msi_invite ( MSISession *session, int32_t *call_index, MSICallType call_type
1626 1754
1627 _call->state = call_inviting; 1755 _call->state = call_inviting;
1628 1756
1629 _call->request_timer_id = event.timer_alloc ( handle_timeout, _call, m_deftout ); 1757 _call->request_timer_id = timer_alloc ( session->timer_handler, handle_timeout, session, _call->call_idx, m_deftout );
1630 1758
1631 LOGGER_DEBUG("Invite sent"); 1759 LOGGER_DEBUG("Invite sent");
1632 1760
@@ -1670,11 +1798,12 @@ int msi_hangup ( MSISession *session, int32_t call_index )
1670 for ( ; _it < session->calls[call_index]->peer_count; _it ++ ) 1798 for ( ; _it < session->calls[call_index]->peer_count; _it ++ )
1671 send_message ( session, session->calls[call_index], _msg_end, session->calls[call_index]->peers[_it] ); 1799 send_message ( session, session->calls[call_index], _msg_end, session->calls[call_index]->peers[_it] );
1672 1800
1801 session->calls[call_index]->state = call_hanged_up;
1673 1802
1674 free_message ( _msg_end ); 1803 free_message ( _msg_end );
1675 1804
1676 session->calls[call_index]->request_timer_id = event.timer_alloc ( handle_timeout, session->calls[call_index], 1805 session->calls[call_index]->request_timer_id =
1677 m_deftout ); 1806 timer_alloc ( session->timer_handler, handle_timeout, session, call_index, m_deftout );
1678 1807
1679 pthread_mutex_unlock(&session->mutex); 1808 pthread_mutex_unlock(&session->mutex);
1680 return 0; 1809 return 0;
@@ -1712,17 +1841,6 @@ int msi_answer ( MSISession *session, int32_t call_index, MSICallType call_type
1712 ( _msg_starting, ( const uint8_t *) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) ); 1841 ( _msg_starting, ( const uint8_t *) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) );
1713 } 1842 }
1714 1843
1715 /* Now set the local encryption key and pass it with STARTING message */
1716
1717 session->calls[call_index]->key_local = calloc ( sizeof ( uint8_t ), crypto_box_KEYBYTES );
1718 new_symmetric_key ( session->calls[call_index]->key_local );
1719
1720 session->calls[call_index]->nonce_local = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES );
1721 new_nonce ( session->calls[call_index]->nonce_local );
1722
1723 msi_msg_set_cryptokey ( _msg_starting, session->calls[call_index]->key_local, crypto_box_KEYBYTES );
1724 msi_msg_set_nonce ( _msg_starting, session->calls[call_index]->nonce_local, crypto_box_NONCEBYTES );
1725
1726 send_message ( session, session->calls[call_index], _msg_starting, 1844 send_message ( session, session->calls[call_index], _msg_starting,
1727 session->calls[call_index]->peers[session->calls[call_index]->peer_count - 1] ); 1845 session->calls[call_index]->peers[session->calls[call_index]->peer_count - 1] );
1728 free_message ( _msg_starting ); 1846 free_message ( _msg_starting );
@@ -1760,7 +1878,8 @@ int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const c
1760 send_message ( session, session->calls[call_index], _msg_cancel, peer ); 1878 send_message ( session, session->calls[call_index], _msg_cancel, peer );
1761 free_message ( _msg_cancel ); 1879 free_message ( _msg_cancel );
1762 1880
1763 /*session->calls[call_index]->request_timer_id = event.timer_alloc ( handle_timeout, session->calls[call_index], m_deftout );*/ 1881 /*session->calls[call_index]->state = call_hanged_up;
1882 session->calls[call_index]->request_timer_id = timer_alloc ( handle_timeout, session, call_index, m_deftout );*/
1764 terminate_call ( session, session->calls[call_index] ); 1883 terminate_call ( session, session->calls[call_index] );
1765 pthread_mutex_unlock(&session->mutex); 1884 pthread_mutex_unlock(&session->mutex);
1766 1885
@@ -1794,8 +1913,10 @@ int msi_reject ( MSISession *session, int32_t call_index, const uint8_t *reason
1794 session->calls[call_index]->peers[session->calls[call_index]->peer_count - 1] ); 1913 session->calls[call_index]->peers[session->calls[call_index]->peer_count - 1] );
1795 free_message ( _msg_reject ); 1914 free_message ( _msg_reject );
1796 1915
1797 session->calls[call_index]->request_timer_id = event.timer_alloc ( handle_timeout, session->calls[call_index], 1916 session->calls[call_index]->state = call_hanged_up;
1798 m_deftout ); 1917
1918 session->calls[call_index]->request_timer_id =
1919 timer_alloc ( session->timer_handler, handle_timeout, session, call_index, m_deftout );
1799 1920
1800 pthread_mutex_unlock(&session->mutex); 1921 pthread_mutex_unlock(&session->mutex);
1801 return 0; 1922 return 0;
diff --git a/toxav/msi.h b/toxav/msi.h
index 042f3f0f..0020df4c 100644
--- a/toxav/msi.h
+++ b/toxav/msi.h
@@ -17,8 +17,6 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 20 */
23 21
24#ifndef __TOXMSI 22#ifndef __TOXMSI
@@ -52,7 +50,8 @@ typedef enum {
52 call_inviting, /* when sending call invite */ 50 call_inviting, /* when sending call invite */
53 call_starting, /* when getting call invite */ 51 call_starting, /* when getting call invite */
54 call_active, 52 call_active,
55 call_hold 53 call_hold,
54 call_hanged_up
56 55
57} MSICallState; 56} MSICallState;
58 57
@@ -72,12 +71,6 @@ typedef struct _MSICall { /* Call info structure */
72 71
73 uint8_t id[CALL_ID_LEN]; /* Random value identifying the call */ 72 uint8_t id[CALL_ID_LEN]; /* Random value identifying the call */
74 73
75 uint8_t *key_local; /* The key for encryption */
76 uint8_t *key_peer; /* The key for decryption */
77
78 uint8_t *nonce_local; /* Local nonce */
79 uint8_t *nonce_peer; /* Peer nonce */
80
81 int ringing_tout_ms; /* Ringing timeout in ms */ 74 int ringing_tout_ms; /* Ringing timeout in ms */
82 75
83 int request_timer_id; /* Timer id for outgoing request/action */ 76 int request_timer_id; /* Timer id for outgoing request/action */
@@ -112,6 +105,8 @@ typedef struct _MSISession {
112 uint32_t call_timeout; /* Time of the timeout for some action to end; 0 if infinite */ 105 uint32_t call_timeout; /* Time of the timeout for some action to end; 0 if infinite */
113 106
114 pthread_mutex_t mutex; 107 pthread_mutex_t mutex;
108
109 void *timer_handler;
115} MSISession; 110} MSISession;
116 111
117 112
diff --git a/toxav/rtp.c b/toxav/rtp.c
index d4fdf656..a6bcaf18 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -17,8 +17,6 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 20 */
23 21
24#ifdef HAVE_CONFIG_H 22#ifdef HAVE_CONFIG_H
@@ -29,12 +27,8 @@
29#include "../toxcore/util.h" 27#include "../toxcore/util.h"
30 28
31#include "rtp.h" 29#include "rtp.h"
32#include <assert.h>
33#include <stdlib.h> 30#include <stdlib.h>
34 31void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg);
35
36#define PAYLOAD_ID_VALUE_OPUS 1
37#define PAYLOAD_ID_VALUE_VP8 2
38 32
39#define size_32 4 33#define size_32 4
40 34
@@ -52,7 +46,6 @@
52#define GET_SETTING_MARKER(_h) (( _h->marker_payloadt ) >> 7) 46#define GET_SETTING_MARKER(_h) (( _h->marker_payloadt ) >> 7)
53#define GET_SETTING_PAYLOAD(_h) ((_h->marker_payloadt) & 0x7f) 47#define GET_SETTING_PAYLOAD(_h) ((_h->marker_payloadt) & 0x7f)
54 48
55
56/** 49/**
57 * @brief Checks if message came in late. 50 * @brief Checks if message came in late.
58 * 51 *
@@ -74,66 +67,6 @@ inline__ int check_late_message (RTPSession *session, RTPMessage *msg)
74 67
75 68
76/** 69/**
77 * @brief Increases nonce value by 'target'
78 *
79 * @param nonce The nonce
80 * @param target The target
81 * @return void
82 */
83inline__ void increase_nonce(uint8_t *nonce, uint16_t target)
84{
85 uint16_t _nonce_counter;
86
87 uint8_t _reverse_bytes[2];
88 _reverse_bytes[0] = nonce[crypto_box_NONCEBYTES - 1];
89 _reverse_bytes[1] = nonce[crypto_box_NONCEBYTES - 2];
90
91 bytes_to_U16(&_nonce_counter, _reverse_bytes );
92
93 /* Check overflow */
94 if (_nonce_counter > UINT16_MAX - target ) { /* 2 bytes are not long enough */
95 uint8_t _it = 3;
96
97 while ( _it <= crypto_box_NONCEBYTES ) _it += ++nonce[crypto_box_NONCEBYTES - _it] ?
98 crypto_box_NONCEBYTES : 1;
99
100 _nonce_counter = _nonce_counter - (UINT16_MAX - target ); /* Assign the rest of it */
101 } else { /* Increase nonce */
102
103 _nonce_counter += target;
104 }
105
106 /* Assign the last bytes */
107
108 U16_to_bytes( _reverse_bytes, _nonce_counter);
109 nonce [crypto_box_NONCEBYTES - 1] = _reverse_bytes[0];
110 nonce [crypto_box_NONCEBYTES - 2] = _reverse_bytes[1];
111
112}
113
114
115/**
116 * @brief Speaks for it self.
117 *
118 */
119static const uint32_t payload_table[] = {
120 8000, 8000, 8000, 8000, 8000, 8000, 16000, 8000, 8000, 8000, /* 0-9 */
121 44100, 44100, 0, 0, 90000, 8000, 11025, 22050, 0, 0, /* 10-19 */
122 0, 0, 0, 0, 0, 90000, 90000, 0, 90000, 0, /* 20-29 */
123 0, 90000, 90000, 90000, 90000, 0, 0, 0, 0, 0, /* 30-39 */
124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40-49 */
125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50-59 */
126 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60-69 */
127 PAYLOAD_ID_VALUE_OPUS, PAYLOAD_ID_VALUE_VP8, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-79 */
128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-89 */
129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90-99 */
130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 100-109 */
131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 110-119 */
132 0, 0, 0, 0, 0, 0, 0, 0 /* 120-127 */
133};
134
135
136/**
137 * @brief Extracts header from payload. 70 * @brief Extracts header from payload.
138 * 71 *
139 * @param payload The payload. 72 * @param payload The payload.
@@ -148,10 +81,16 @@ RTPHeader *extract_header ( const uint8_t *payload, int length )
148 return NULL; 81 return NULL;
149 } 82 }
150 83
151 const uint8_t *_it = payload;
152
153 RTPHeader *_retu = calloc(1, sizeof (RTPHeader)); 84 RTPHeader *_retu = calloc(1, sizeof (RTPHeader));
154 assert(_retu); 85
86 if ( !_retu ) {
87 LOGGER_WARNING("Alloc failed! Program might misbehave!");
88 return NULL;
89 }
90
91 bytes_to_U16(&_retu->sequnum, payload);
92
93 const uint8_t *_it = payload + 2;
155 94
156 _retu->flags = *_it; 95 _retu->flags = *_it;
157 ++_it; 96 ++_it;
@@ -216,7 +155,11 @@ RTPExtHeader *extract_ext_header ( const uint8_t *payload, uint16_t length )
216 const uint8_t *_it = payload; 155 const uint8_t *_it = payload;
217 156
218 RTPExtHeader *_retu = calloc(1, sizeof (RTPExtHeader)); 157 RTPExtHeader *_retu = calloc(1, sizeof (RTPExtHeader));
219 assert(_retu); 158
159 if ( !_retu ) {
160 LOGGER_WARNING("Alloc failed! Program might misbehave!");
161 return NULL;
162 }
220 163
221 uint16_t _ext_length; 164 uint16_t _ext_length;
222 bytes_to_U16(&_ext_length, _it); 165 bytes_to_U16(&_ext_length, _it);
@@ -233,8 +176,11 @@ RTPExtHeader *extract_ext_header ( const uint8_t *payload, uint16_t length )
233 bytes_to_U16(&_retu->type, _it); 176 bytes_to_U16(&_retu->type, _it);
234 _it += 2; 177 _it += 2;
235 178
236 _retu->table = calloc(_ext_length, sizeof (uint32_t)); 179 if ( !(_retu->table = calloc(_ext_length, sizeof (uint32_t))) ) {
237 assert(_retu->table); 180 LOGGER_WARNING("Alloc failed! Program might misbehave!");
181 free(_retu);
182 return NULL;
183 }
238 184
239 uint16_t _x; 185 uint16_t _x;
240 186
@@ -321,7 +267,11 @@ uint8_t *add_ext_header ( RTPExtHeader *header, uint8_t *payload )
321RTPHeader *build_header ( RTPSession *session ) 267RTPHeader *build_header ( RTPSession *session )
322{ 268{
323 RTPHeader *_retu = calloc ( 1, sizeof (RTPHeader) ); 269 RTPHeader *_retu = calloc ( 1, sizeof (RTPHeader) );
324 assert(_retu); 270
271 if ( !_retu ) {
272 LOGGER_WARNING("Alloc failed! Program might misbehave!");
273 return NULL;
274 }
325 275
326 ADD_FLAG_VERSION ( _retu, session->version ); 276 ADD_FLAG_VERSION ( _retu, session->version );
327 ADD_FLAG_PADDING ( _retu, session->padding ); 277 ADD_FLAG_PADDING ( _retu, session->padding );
@@ -357,7 +307,7 @@ RTPHeader *build_header ( RTPSession *session )
357 * @return RTPMessage* 307 * @return RTPMessage*
358 * @retval NULL Error occurred. 308 * @retval NULL Error occurred.
359 */ 309 */
360RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length ) 310RTPMessage *msg_parse ( const uint8_t *data, int length )
361{ 311{
362 RTPMessage *_retu = calloc(1, sizeof (RTPMessage)); 312 RTPMessage *_retu = calloc(1, sizeof (RTPMessage));
363 313
@@ -369,11 +319,9 @@ RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length )
369 return NULL; 319 return NULL;
370 } 320 }
371 321
372 _retu->header->sequnum = sequnum; 322 uint16_t _from_pos = _retu->header->length;
323 _retu->length = length - _from_pos;
373 324
374 _retu->length = length - _retu->header->length;
375
376 uint16_t _from_pos = _retu->header->length - 2 /* Since sequ num is excluded */ ;
377 325
378 326
379 if ( GET_FLAG_EXTENSION ( _retu->header ) ) { 327 if ( GET_FLAG_EXTENSION ( _retu->header ) ) {
@@ -415,70 +363,17 @@ RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length )
415 * @retval -1 Error occurred. 363 * @retval -1 Error occurred.
416 * @retval 0 Success. 364 * @retval 0 Success.
417 */ 365 */
418int rtp_handle_packet ( void *object, uint8_t *data, uint32_t length ) 366int rtp_handle_packet ( void *object, const uint8_t *data, uint32_t length )
419{ 367{
420 RTPSession *_session = object; 368 RTPSession *_session = object;
421 RTPMessage *_msg; 369 RTPMessage *_msg;
422 370
423 if ( !_session || length < 13 + crypto_box_MACBYTES) { /* 12 is the minimum length for rtp + desc. byte */ 371 if ( !_session || length < 13 ) { /* 12 is the minimum length for rtp + desc. byte */
424 LOGGER_WARNING("No session or invalid length of received buffer!"); 372 LOGGER_WARNING("No session or invalid length of received buffer!");
425 return -1; 373 return -1;
426 } 374 }
427 375
428 if ( _session->queue_limit <= _session->queue_size ) { 376 _msg = msg_parse ( data + 1, length - 1 );
429 LOGGER_WARNING("Queue limit reached!");
430 return -1;
431 }
432
433 uint8_t _plain[MAX_UDP_PACKET_SIZE];
434
435 uint16_t _sequnum;
436 bytes_to_U16(&_sequnum, data + 1);
437
438 /* Clculate the right nonce */
439 uint8_t _calculated[crypto_box_NONCEBYTES];
440 memcpy(_calculated, _session->decrypt_nonce, crypto_box_NONCEBYTES);
441 increase_nonce ( _calculated, _sequnum );
442
443 /* Decrypt message */
444 int _decrypted_length = decrypt_data_symmetric(
445 (uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
446
447 /* This packet is either not encrypted properly or late
448 */
449 if ( -1 == _decrypted_length ) {
450
451 /* If this is the case, then the packet is most likely late.
452 * Try with old nonce cycle.
453 */
454 if ( _session->rsequnum < _sequnum ) {
455 _decrypted_length = decrypt_data_symmetric(
456 (uint8_t *)_session->decrypt_key, _session->nonce_cycle, data + 3, length - 3, _plain );
457
458 if ( _decrypted_length == -1 ) {
459 LOGGER_WARNING("Packet not ecrypted properly!");
460 return -1; /* This packet is not encrypted properly */
461 }
462
463 /* Otherwise, if decryption is ok with new cycle, set new cycle
464 */
465 } else {
466 increase_nonce ( _calculated, MAX_SEQU_NUM );
467 _decrypted_length = decrypt_data_symmetric(
468 (uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
469
470 if ( _decrypted_length == -1 ) {
471 LOGGER_WARNING("Error decrypting!");
472 return -1; /* This is just an error */
473 }
474
475 /* A new cycle setting. */
476 memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_box_NONCEBYTES);
477 memcpy(_session->decrypt_nonce, _calculated, crypto_box_NONCEBYTES);
478 }
479 }
480
481 _msg = msg_parse ( _sequnum, _plain, _decrypted_length );
482 377
483 if ( !_msg ) { 378 if ( !_msg ) {
484 LOGGER_WARNING("Could not parse message!"); 379 LOGGER_WARNING("Could not parse message!");
@@ -491,18 +386,7 @@ int rtp_handle_packet ( void *object, uint8_t *data, uint32_t length )
491 _session->timestamp = _msg->header->timestamp; 386 _session->timestamp = _msg->header->timestamp;
492 } 387 }
493 388
494 pthread_mutex_lock(&_session->mutex); 389 toxav_handle_packet(_session, _msg);
495
496 if ( _session->last_msg ) {
497 _session->last_msg->next = _msg;
498 _session->last_msg = _msg;
499 } else {
500 _session->last_msg = _session->oldest_msg = _msg;
501 }
502
503 _session->queue_size++;
504
505 pthread_mutex_unlock(&_session->mutex);
506 390
507 return 0; 391 return 0;
508} 392}
@@ -528,22 +412,28 @@ RTPMessage *rtp_new_message ( RTPSession *session, const uint8_t *data, uint32_t
528 412
529 uint8_t *_from_pos; 413 uint8_t *_from_pos;
530 RTPMessage *_retu = calloc(1, sizeof (RTPMessage)); 414 RTPMessage *_retu = calloc(1, sizeof (RTPMessage));
531 assert(_retu); 415
416 if ( !_retu ) {
417 LOGGER_WARNING("Alloc failed! Program might misbehave!");
418 return NULL;
419 }
532 420
533 /* Sets header values and copies the extension header in _retu */ 421 /* Sets header values and copies the extension header in _retu */
534 _retu->header = build_header ( session ); /* It allocates memory and all */ 422 _retu->header = build_header ( session ); /* It allocates memory and all */
535 _retu->ext_header = session->ext_header; 423 _retu->ext_header = session->ext_header;
536 424
537 425
538 uint32_t _total_length = length + _retu->header->length; 426 uint32_t _total_length = length + _retu->header->length + 1;
427
428 _retu->data[0] = session->prefix;
539 429
540 if ( _retu->ext_header ) { 430 if ( _retu->ext_header ) {
541 _total_length += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 ); 431 _total_length += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
542 432
543 _from_pos = add_header ( _retu->header, _retu->data ); 433 _from_pos = add_header ( _retu->header, _retu->data + 1 );
544 _from_pos = add_ext_header ( _retu->ext_header, _from_pos + 1 ); 434 _from_pos = add_ext_header ( _retu->ext_header, _from_pos + 1 );
545 } else { 435 } else {
546 _from_pos = add_header ( _retu->header, _retu->data ); 436 _from_pos = add_header ( _retu->header, _retu->data + 1 );
547 } 437 }
548 438
549 /* 439 /*
@@ -562,104 +452,6 @@ RTPMessage *rtp_new_message ( RTPSession *session, const uint8_t *data, uint32_t
562} 452}
563 453
564 454
565
566/**
567 * @brief Release all messages held by session.
568 *
569 * @param session The session.
570 * @return int
571 * @retval -1 Error occurred.
572 * @retval 0 Success.
573 */
574int rtp_release_session_recv ( RTPSession *session )
575{
576 if ( !session ) {
577 LOGGER_WARNING("No session!");
578 return -1;
579 }
580
581 RTPMessage *_tmp, * _it;
582
583 pthread_mutex_lock(&session->mutex);
584
585 for ( _it = session->oldest_msg; _it; _it = _tmp ) {
586 _tmp = _it->next;
587 rtp_free_msg( session, _it);
588 }
589
590 session->last_msg = session->oldest_msg = NULL;
591 session->queue_size = 0;
592
593 pthread_mutex_unlock(&session->mutex);
594
595 return 0;
596}
597
598
599/**
600 * @brief Call this to change queue limit
601 *
602 * @param session The session
603 * @param limit new limit
604 * @return void
605 */
606void rtp_queue_adjust_limit(RTPSession *session, uint64_t limit)
607{
608 RTPMessage *_tmp, * _it;
609 pthread_mutex_lock(&session->mutex);
610
611 for ( _it = session->oldest_msg; session->queue_size > limit; _it = _tmp ) {
612 _tmp = _it->next;
613 rtp_free_msg( session, _it);
614 session->queue_size --;
615 }
616
617 session->oldest_msg = _it;
618 session->queue_limit = limit;
619
620 pthread_mutex_unlock(&session->mutex);
621}
622
623
624/**
625 * @brief Gets oldest message in the list.
626 *
627 * @param session Where the list is.
628 * @return RTPMessage* The message. You _must_ call rtp_msg_free() to free it.
629 * @retval NULL No messages in the list, or no list.
630 */
631RTPMessage *rtp_recv_msg ( RTPSession *session )
632{
633 if ( !session ) {
634 LOGGER_WARNING("No session!");
635 return NULL;
636 }
637
638 pthread_mutex_lock(&session->mutex);
639
640 if ( session->queue_size == 0 ) {
641 pthread_mutex_unlock(&session->mutex);
642 return NULL;
643 }
644
645
646 RTPMessage *_retu = session->oldest_msg;
647
648 /*if (_retu)*/
649 session->oldest_msg = _retu->next;
650
651 if ( !session->oldest_msg )
652 session->last_msg = NULL;
653
654 session->queue_size --;
655
656 pthread_mutex_unlock(&session->mutex);
657
658
659 return _retu;
660}
661
662
663/** 455/**
664 * @brief Sends data to _RTPSession::dest 456 * @brief Sends data to _RTPSession::dest
665 * 457 *
@@ -680,25 +472,7 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
680 return -1; 472 return -1;
681 } 473 }
682 474
683 uint8_t _send_data [ MAX_UDP_PACKET_SIZE ]; 475 if ( -1 == send_custom_lossy_packet(messenger, session->dest, msg->data, msg->length) ) {
684
685 _send_data[0] = session->prefix;
686
687 /* Generate the right nonce */
688 uint8_t _calculated[crypto_box_NONCEBYTES];
689 memcpy(_calculated, session->encrypt_nonce, crypto_box_NONCEBYTES);
690 increase_nonce ( _calculated, msg->header->sequnum );
691
692 /* Need to skip 2 bytes that are for sequnum */
693 int encrypted_length = encrypt_data_symmetric( /* TODO: msg->length - 2 (fix this properly)*/
694 (uint8_t *) session->encrypt_key, _calculated, msg->data + 2, msg->length, _send_data + 3 );
695
696
697 _send_data[1] = msg->data[0];
698 _send_data[2] = msg->data[1];
699
700
701 if ( -1 == send_custom_lossy_packet(messenger, session->dest, _send_data, encrypted_length + 3) ) {
702 LOGGER_WARNING("Failed to send full packet! std error: %s", strerror(errno)); 476 LOGGER_WARNING("Failed to send full packet! std error: %s", strerror(errno));
703 rtp_free_msg ( session, msg ); 477 rtp_free_msg ( session, msg );
704 return -1; 478 return -1;
@@ -706,13 +480,7 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
706 480
707 481
708 /* Set sequ number */ 482 /* Set sequ number */
709 if ( session->sequnum >= MAX_SEQU_NUM ) { 483 session->sequnum = session->sequnum >= MAX_SEQU_NUM ? 0 : session->sequnum + 1;
710 session->sequnum = 0;
711 memcpy(session->encrypt_nonce, _calculated, crypto_box_NONCEBYTES);
712 } else {
713 session->sequnum++;
714 }
715
716 rtp_free_msg ( session, msg ); 484 rtp_free_msg ( session, msg );
717 485
718 return 0; 486 return 0;
@@ -745,7 +513,6 @@ void rtp_free_msg ( RTPSession *session, RTPMessage *msg )
745 free ( msg ); 513 free ( msg );
746} 514}
747 515
748
749/** 516/**
750 * @brief Must be called before calling any other rtp function. It's used 517 * @brief Must be called before calling any other rtp function. It's used
751 * to initialize RTP control session. 518 * to initialize RTP control session.
@@ -753,26 +520,19 @@ void rtp_free_msg ( RTPSession *session, RTPMessage *msg )
753 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType 520 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType
754 * @param messenger Tox* object. 521 * @param messenger Tox* object.
755 * @param friend_num Friend id. 522 * @param friend_num Friend id.
756 * @param encrypt_key Speaks for it self.
757 * @param decrypt_key Speaks for it self.
758 * @param encrypt_nonce Speaks for it self.
759 * @param decrypt_nonce Speaks for it self.
760 * @return RTPSession* Created control session. 523 * @return RTPSession* Created control session.
761 * @retval NULL Error occurred. 524 * @retval NULL Error occurred.
762 */ 525 */
763RTPSession *rtp_init_session ( int payload_type, 526RTPSession *rtp_init_session ( int payload_type, Messenger *messenger, int friend_num )
764 Messenger *messenger,
765 int friend_num,
766 const uint8_t *encrypt_key,
767 const uint8_t *decrypt_key,
768 const uint8_t *encrypt_nonce,
769 const uint8_t *decrypt_nonce )
770{ 527{
771 RTPSession *_retu = calloc(1, sizeof(RTPSession)); 528 RTPSession *_retu = calloc(1, sizeof(RTPSession));
772 assert(_retu);
773 529
774 if ( -1 == custom_lossy_packet_registerhandler(messenger, friend_num, payload_type, rtp_handle_packet, _retu) || 530 if ( !_retu ) {
775 !encrypt_key || !decrypt_key || !encrypt_nonce || !decrypt_nonce) { 531 LOGGER_WARNING("Alloc failed! Program might misbehave!");
532 return NULL;
533 }
534
535 if ( -1 == custom_lossy_packet_registerhandler(messenger, friend_num, payload_type, rtp_handle_packet, _retu)) {
776 LOGGER_ERROR("Error setting custom register handler for rtp session"); 536 LOGGER_ERROR("Error setting custom register handler for rtp session");
777 free(_retu); 537 free(_retu);
778 return NULL; 538 return NULL;
@@ -787,7 +547,7 @@ RTPSession *rtp_init_session ( int payload_type,
787 _retu->csrc = NULL; /* Container */ 547 _retu->csrc = NULL; /* Container */
788 _retu->ssrc = random_int(); 548 _retu->ssrc = random_int();
789 _retu->marker = 0; 549 _retu->marker = 0;
790 _retu->payload_type = payload_table[payload_type]; 550 _retu->payload_type = payload_type % 128;
791 551
792 _retu->dest = friend_num; 552 _retu->dest = friend_num;
793 553
@@ -795,34 +555,18 @@ RTPSession *rtp_init_session ( int payload_type,
795 555
796 _retu->ext_header = NULL; /* When needed allocate */ 556 _retu->ext_header = NULL; /* When needed allocate */
797 557
798 _retu->encrypt_key = encrypt_key;
799 _retu->decrypt_key = decrypt_key;
800 558
801 /* Need to allocate new memory */ 559 if ( !(_retu->csrc = calloc(1, sizeof (uint32_t))) ) {
802 _retu->encrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) ); 560 LOGGER_WARNING("Alloc failed! Program might misbehave!");
803 assert(_retu->encrypt_nonce); 561 free(_retu);
804 _retu->decrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) ); 562 return NULL;
805 assert(_retu->decrypt_nonce); 563 }
806 _retu->nonce_cycle = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
807 assert(_retu->nonce_cycle);
808
809 memcpy(_retu->encrypt_nonce, encrypt_nonce, crypto_box_NONCEBYTES);
810 memcpy(_retu->decrypt_nonce, decrypt_nonce, crypto_box_NONCEBYTES);
811 memcpy(_retu->nonce_cycle , decrypt_nonce, crypto_box_NONCEBYTES);
812
813 _retu->csrc = calloc(1, sizeof (uint32_t));
814 assert(_retu->csrc);
815 564
816 _retu->csrc[0] = _retu->ssrc; /* Set my ssrc to the list receive */ 565 _retu->csrc[0] = _retu->ssrc; /* Set my ssrc to the list receive */
817 566
818 /* Also set payload type as prefix */ 567 /* Also set payload type as prefix */
819 _retu->prefix = payload_type; 568 _retu->prefix = payload_type;
820 569
821 _retu->oldest_msg = _retu->last_msg = NULL;
822 _retu->queue_limit = 100; /* Default */
823 _retu->queue_size = 0;
824
825 pthread_mutex_init(&_retu->mutex, NULL);
826 /* 570 /*
827 * 571 *
828 */ 572 */
@@ -839,31 +583,18 @@ RTPSession *rtp_init_session ( int payload_type,
839 * @retval -1 Error occurred. 583 * @retval -1 Error occurred.
840 * @retval 0 Success. 584 * @retval 0 Success.
841 */ 585 */
842int rtp_terminate_session ( RTPSession *session, Messenger *messenger ) 586void rtp_terminate_session ( RTPSession *session, Messenger *messenger )
843{ 587{
844 if ( !session ) { 588 if ( !session ) return;
845 LOGGER_WARNING("No session!");
846 return -1;
847 }
848 589
849 custom_lossy_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL); 590 custom_lossy_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL);
850 591
851 rtp_release_session_recv(session);
852
853 pthread_mutex_lock(&session->mutex);
854
855 free ( session->ext_header ); 592 free ( session->ext_header );
856 free ( session->csrc ); 593 free ( session->csrc );
857 free ( session->decrypt_nonce );
858 free ( session->encrypt_nonce );
859 free ( session->nonce_cycle );
860 594
861 pthread_mutex_unlock(&session->mutex); 595 LOGGER_DEBUG("Terminated RTP session: %p", session);
862
863 pthread_mutex_destroy(&session->mutex);
864 596
865 /* And finally free session */ 597 /* And finally free session */
866 free ( session ); 598 free ( session );
867 599
868 return 0;
869} 600}
diff --git a/toxav/rtp.h b/toxav/rtp.h
index 45cf83b6..45128285 100644
--- a/toxav/rtp.h
+++ b/toxav/rtp.h
@@ -17,8 +17,6 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 20 */
23 21
24#ifndef __TOXRTP 22#ifndef __TOXRTP
@@ -107,29 +105,12 @@ typedef struct _RTPSession {
107 */ 105 */
108 RTPExtHeader *ext_header; 106 RTPExtHeader *ext_header;
109 107
110
111 /* Since these are only references of the
112 * call structure don't allocate or free
113 */
114
115 const uint8_t *encrypt_key;
116 const uint8_t *decrypt_key;
117 uint8_t *encrypt_nonce;
118 uint8_t *decrypt_nonce;
119
120 uint8_t *nonce_cycle;
121
122 RTPMessage *oldest_msg;
123 RTPMessage *last_msg; /* tail */
124
125 uint64_t queue_limit;/* Default 100; modify per thy liking */
126 uint64_t queue_size; /* currently holding << messages */
127
128 /* Msg prefix for core to know when recving */ 108 /* Msg prefix for core to know when recving */
129 uint8_t prefix; 109 uint8_t prefix;
130 110
131 pthread_mutex_t mutex;
132 int dest; 111 int dest;
112 int32_t call_index;
113 struct _ToxAv *av;
133 114
134} RTPSession; 115} RTPSession;
135 116
@@ -186,7 +167,6 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat
186 */ 167 */
187void rtp_free_msg ( RTPSession *session, RTPMessage *msg ); 168void rtp_free_msg ( RTPSession *session, RTPMessage *msg );
188 169
189
190/** 170/**
191 * @brief Must be called before calling any other rtp function. It's used 171 * @brief Must be called before calling any other rtp function. It's used
192 * to initialize RTP control session. 172 * to initialize RTP control session.
@@ -194,20 +174,10 @@ void rtp_free_msg ( RTPSession *session, RTPMessage *msg );
194 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType 174 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType
195 * @param messenger Tox* object. 175 * @param messenger Tox* object.
196 * @param friend_num Friend id. 176 * @param friend_num Friend id.
197 * @param encrypt_key Speaks for it self.
198 * @param decrypt_key Speaks for it self.
199 * @param encrypt_nonce Speaks for it self.
200 * @param decrypt_nonce Speaks for it self.
201 * @return RTPSession* Created control session. 177 * @return RTPSession* Created control session.
202 * @retval NULL Error occurred. 178 * @retval NULL Error occurred.
203 */ 179 */
204RTPSession *rtp_init_session ( int payload_type, 180RTPSession *rtp_init_session ( int payload_type, Messenger *messenger, int friend_num );
205 Messenger *messenger,
206 int friend_num,
207 const uint8_t *encrypt_key,
208 const uint8_t *decrypt_key,
209 const uint8_t *encrypt_nonce,
210 const uint8_t *decrypt_nonce );
211 181
212 182
213/** 183/**
@@ -219,7 +189,7 @@ RTPSession *rtp_init_session ( int payload_type,
219 * @retval -1 Error occurred. 189 * @retval -1 Error occurred.
220 * @retval 0 Success. 190 * @retval 0 Success.
221 */ 191 */
222int rtp_terminate_session ( RTPSession *session, Messenger *messenger ); 192void rtp_terminate_session ( RTPSession *session, Messenger *messenger );
223 193
224 194
225 195
diff --git a/toxav/toxav.c b/toxav/toxav.c
index a042b9dd..a301e007 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -17,8 +17,6 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 20 */
23 21
24#ifdef HAVE_CONFIG_H 22#ifdef HAVE_CONFIG_H
@@ -29,19 +27,22 @@
29#define _GNU_SOURCE /* implicit declaration warning */ 27#define _GNU_SOURCE /* implicit declaration warning */
30 28
31#include "rtp.h" 29#include "rtp.h"
32#include "media.h" 30#include "codec.h"
33#include "msi.h" 31#include "msi.h"
34#include "toxav.h" 32#include "toxav.h"
35 33
36#include "../toxcore/logger.h" 34#include "../toxcore/logger.h"
37 35
38
39#include <assert.h> 36#include <assert.h>
40#include <stdlib.h> 37#include <stdlib.h>
41#include <string.h> 38#include <string.h>
42 39
43/* Assume 60 fps*/ 40/* Assume 60 fps*/
44#define MAX_ENCODE_TIME_US ((1000 / 60) * 1000) 41#define MAX_ENCODE_TIME_US ((1000 / 24) * 1000)
42
43#define MAX_VIDEOFRAME_SIZE 0x40000 /* 256KiB */
44#define VIDEOFRAME_PIECE_SIZE 0x500 /* 1.25 KiB*/
45#define VIDEOFRAME_HEADER_SIZE 0x2
45 46
46 47
47#define inline__ inline __attribute__((always_inline)) 48#define inline__ inline __attribute__((always_inline))
@@ -61,6 +62,13 @@ typedef struct _CallSpecific {
61 * reuse them really. 62 * reuse them really.
62 */ 63 */
63 JitterBuffer *j_buf; /** Jitter buffer for audio */ 64 JitterBuffer *j_buf; /** Jitter buffer for audio */
65
66 uint32_t frame_limit; /* largest address written to in frame_buf for current input frame*/
67 uint8_t frame_id, frame_outid; /* id of input and output video frame */
68 void *frame_buf; /* buffer for split video payloads */
69
70 _Bool call_active;
71 pthread_mutex_t mutex;
64} CallSpecific; 72} CallSpecific;
65 73
66 74
@@ -68,19 +76,25 @@ struct _ToxAv {
68 Messenger *messenger; 76 Messenger *messenger;
69 MSISession *msi_session; /** Main msi session */ 77 MSISession *msi_session; /** Main msi session */
70 CallSpecific *calls; /** Per-call params */ 78 CallSpecific *calls; /** Per-call params */
79
80 void (*audio_callback)(ToxAv *, int32_t, int16_t *, int);
81 void (*video_callback)(ToxAv *, int32_t, vpx_image_t *);
82
71 uint32_t max_calls; 83 uint32_t max_calls;
72}; 84};
73 85
74const ToxAvCodecSettings av_DefaultSettings = { 86const ToxAvCodecSettings av_DefaultSettings = {
75 1000000, 87 500,
76 800, 88 1280,
77 600, 89 720,
78 90
79 64000, 91 64000,
80 20, 92 20,
81 48000, 93 48000,
82 1, 94 1,
83 20 95 600,
96
97 6
84}; 98};
85 99
86 100
@@ -123,8 +137,6 @@ ToxAv *toxav_new( Tox *messenger, int32_t max_calls)
123 */ 137 */
124void toxav_kill ( ToxAv *av ) 138void toxav_kill ( ToxAv *av )
125{ 139{
126 msi_terminate_session(av->msi_session);
127
128 int i = 0; 140 int i = 0;
129 141
130 for (; i < av->max_calls; i ++) { 142 for (; i < av->max_calls; i ++) {
@@ -142,6 +154,8 @@ void toxav_kill ( ToxAv *av )
142 if ( av->calls[i].cs ) codec_terminate_session(av->calls[i].cs); 154 if ( av->calls[i].cs ) codec_terminate_session(av->calls[i].cs);
143 } 155 }
144 156
157 msi_terminate_session(av->msi_session);
158
145 free(av->calls); 159 free(av->calls);
146 free(av); 160 free(av);
147} 161}
@@ -159,6 +173,28 @@ void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID
159} 173}
160 174
161/** 175/**
176 * @brief Register callback for recieving audio data
177 *
178 * @param callback The callback
179 * @return void
180 */
181void toxav_register_audio_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, int16_t *, int))
182{
183 av->audio_callback = callback;
184}
185
186/**
187 * @brief Register callback for recieving video data
188 *
189 * @param callback The callback
190 * @return void
191 */
192void toxav_register_video_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, vpx_image_t *))
193{
194 av->video_callback = callback;
195}
196
197/**
162 * @brief Call user. Use its friend_id. 198 * @brief Call user. Use its friend_id.
163 * 199 *
164 * @param av Handler. 200 * @param av Handler.
@@ -255,6 +291,10 @@ int toxav_cancel ( ToxAv *av, int32_t call_index, int peer_id, const char *reaso
255 return ErrorNoCall; 291 return ErrorNoCall;
256 } 292 }
257 293
294 if ( av->msi_session->calls[call_index]->state != call_inviting ) {
295 return ErrorInvalidState;
296 }
297
258 return msi_cancel(av->msi_session, call_index, peer_id, reason); 298 return msi_cancel(av->msi_session, call_index, peer_id, reason);
259} 299}
260 300
@@ -285,59 +325,80 @@ int toxav_stop_call ( ToxAv *av, int32_t call_index )
285 */ 325 */
286int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video ) 326int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video )
287{ 327{
288 if ( !av->msi_session || cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) { 328 if ( !av->msi_session || cii(call_index, av->msi_session) ||
289 LOGGER_ERROR("Error while starting audio RTP session: invalid call!\n"); 329 !av->msi_session->calls[call_index] || av->calls[call_index].call_active) {
330 LOGGER_ERROR("Error while starting RTP session: invalid call!\n");
290 return ErrorInternal; 331 return ErrorInternal;
291 } 332 }
292 333
293 CallSpecific *call = &av->calls[call_index]; 334 CallSpecific *call = &av->calls[call_index];
294 335
295 call->crtps[audio_index] = 336 call->crtps[audio_index] =
296 rtp_init_session( 337 rtp_init_session(type_audio, av->messenger, av->msi_session->calls[call_index]->peers[0]);
297 type_audio,
298 av->messenger,
299 av->msi_session->calls[call_index]->peers[0],
300 av->msi_session->calls[call_index]->key_peer,
301 av->msi_session->calls[call_index]->key_local,
302 av->msi_session->calls[call_index]->nonce_peer,
303 av->msi_session->calls[call_index]->nonce_local);
304 338
305 339
306 if ( !call->crtps[audio_index] ) { 340 if ( !call->crtps[audio_index] ) {
307 LOGGER_ERROR("Error while starting audio RTP session!\n"); 341 LOGGER_ERROR("Error while starting audio RTP session!\n");
308 return ErrorStartingAudioRtp; 342 return ErrorInternal;
309 } 343 }
310 344
345 call->crtps[audio_index]->call_index = call_index;
346 call->crtps[audio_index]->av = av;
311 347
312 if ( support_video ) { 348 if ( support_video ) {
313 call->crtps[video_index] = 349 call->crtps[video_index] =
314 rtp_init_session ( 350 rtp_init_session(type_video, av->messenger, av->msi_session->calls[call_index]->peers[0]);
315 type_video,
316 av->messenger,
317 av->msi_session->calls[call_index]->peers[0],
318 av->msi_session->calls[call_index]->key_peer,
319 av->msi_session->calls[call_index]->key_local,
320 av->msi_session->calls[call_index]->nonce_peer,
321 av->msi_session->calls[call_index]->nonce_local);
322
323 351
324 if ( !call->crtps[video_index] ) { 352 if ( !call->crtps[video_index] ) {
325 LOGGER_ERROR("Error while starting video RTP session!\n"); 353 LOGGER_ERROR("Error while starting video RTP session!\n");
326 return ErrorStartingVideoRtp; 354 goto error;
355 }
356
357 call->crtps[video_index]->call_index = call_index;
358 call->crtps[video_index]->av = av;
359
360 call->frame_limit = 0;
361 call->frame_id = 0;
362 call->frame_outid = 0;
363
364 call->frame_buf = calloc(MAX_VIDEOFRAME_SIZE, 1);
365
366 if (!call->frame_buf) {
367 LOGGER_WARNING("Frame buffer allocation failed!");
368 goto error;
327 } 369 }
370
371 }
372
373 if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) {
374 LOGGER_WARNING("Jitter buffer creaton failed!");
375 goto error;
328 } 376 }
329 377
330 if ( !(call->j_buf = create_queue(codec_settings->jbuf_capacity)) ) return ErrorInternal; 378 if ( (call->cs = codec_init_session(codec_settings->audio_bitrate,
379 codec_settings->audio_frame_duration,
380 codec_settings->audio_sample_rate,
381 codec_settings->audio_channels,
382 codec_settings->audio_VAD_tolerance,
383 codec_settings->max_video_width,
384 codec_settings->max_video_height,
385 codec_settings->video_bitrate) )) {
331 386
332 call->cs = codec_init_session(codec_settings->audio_bitrate, 387 if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error;
333 codec_settings->audio_frame_duration, 388
334 codec_settings->audio_sample_rate, 389 call->call_active = 1;
335 codec_settings->audio_channels, 390
336 codec_settings->video_width, 391 return ErrorNone;
337 codec_settings->video_height, 392 }
338 codec_settings->video_bitrate);
339 393
340 return call->cs ? ErrorNone : ErrorInternal; 394error:
395 rtp_terminate_session(call->crtps[audio_index], av->messenger);
396 rtp_terminate_session(call->crtps[video_index], av->messenger);
397 free(call->frame_buf);
398 terminate_queue(call->j_buf);
399 codec_terminate_session(call->cs);
400
401 return ErrorInternal;
341} 402}
342 403
343/** 404/**
@@ -350,34 +411,35 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin
350 */ 411 */
351int toxav_kill_transmission ( ToxAv *av, int32_t call_index ) 412int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
352{ 413{
353 if (cii(call_index, av->msi_session)) return ErrorNoCall; 414 if (cii(call_index, av->msi_session)) {
415 LOGGER_WARNING("Invalid call index: %d", call_index);
416 return ErrorNoCall;
417 }
354 418
355 CallSpecific *call = &av->calls[call_index]; 419 CallSpecific *call = &av->calls[call_index];
356 420
357 if ( call->crtps[audio_index] && -1 == rtp_terminate_session(call->crtps[audio_index], av->messenger) ) { 421 pthread_mutex_lock(&call->mutex);
358 LOGGER_ERROR("Error while terminating audio RTP session!\n");
359 return ErrorTerminatingAudioRtp;
360 }
361 422
362 if ( call->crtps[video_index] && -1 == rtp_terminate_session(call->crtps[video_index], av->messenger) ) { 423 if (!call->call_active) {
363 LOGGER_ERROR("Error while terminating video RTP session!\n"); 424 pthread_mutex_unlock(&call->mutex);
364 return ErrorTerminatingVideoRtp; 425 LOGGER_WARNING("Action on inactive call: %d", call_index);
426 return ErrorNoCall;
365 } 427 }
366 428
429
430 call->call_active = 0;
431
432 rtp_terminate_session(call->crtps[audio_index], av->messenger);
367 call->crtps[audio_index] = NULL; 433 call->crtps[audio_index] = NULL;
434 rtp_terminate_session(call->crtps[video_index], av->messenger);
368 call->crtps[video_index] = NULL; 435 call->crtps[video_index] = NULL;
436 terminate_queue(call->j_buf);
437 call->j_buf = NULL;
438 codec_terminate_session(call->cs);
439 call->cs = NULL;
369 440
370 if ( call->j_buf ) { 441 pthread_mutex_unlock(&call->mutex);
371 terminate_queue(call->j_buf); 442 pthread_mutex_destroy(&call->mutex);
372 call->j_buf = NULL;
373 LOGGER_DEBUG("Terminated j queue");
374 } else LOGGER_DEBUG("No j queue");
375
376 if ( call->cs ) {
377 codec_terminate_session(call->cs);
378 call->cs = NULL;
379 LOGGER_DEBUG("Terminated codec session");
380 } else LOGGER_DEBUG("No codec session");
381 443
382 return ErrorNone; 444 return ErrorNone;
383} 445}
@@ -395,122 +457,83 @@ int toxav_kill_transmission ( ToxAv *av, int32_t call_index )
395 * @retval -1 Failure. 457 * @retval -1 Failure.
396 */ 458 */
397inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, 459inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload,
398 uint16_t length ) 460 unsigned int length )
399{ 461{
400 if (cii(call_index, av->msi_session)) return ErrorNoCall; 462 CallSpecific *call = &av->calls[call_index];
401 463
402 if ( av->calls[call_index].crtps[type - TypeAudio] ) 464 if (call->crtps[type - TypeAudio]) {
403 return rtp_send_msg ( av->calls[call_index].crtps[type - TypeAudio], av->msi_session->messenger_handle, payload,
404 length );
405 else return -1;
406}
407 465
408/** 466 if (type == TypeAudio) {
409 * @brief Receive RTP payload. 467 return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, payload, length);
410 * 468 } else {
411 * @param av Handler. 469 if (length == 0 || length > MAX_VIDEOFRAME_SIZE) {
412 * @param type Type of the payload. 470 LOGGER_ERROR("Invalid video frame size: %u\n", length);
413 * @param dest Storage. 471 return ErrorInternal;
414 * @return int 472 }
415 * @retval ToxAvError On Error.
416 * @retval >=0 Size of received payload.
417 */
418inline__ int toxav_recv_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, uint8_t *dest )
419{
420 if ( !dest ) return ErrorInternal;
421 473
422 if (cii(call_index, av->msi_session)) return ErrorNoCall; 474 /* number of pieces - 1*/
475 uint8_t numparts = (length - 1) / VIDEOFRAME_PIECE_SIZE;
423 476
424 CallSpecific *call = &av->calls[call_index]; 477 uint8_t load[2 + VIDEOFRAME_PIECE_SIZE];
478 load[0] = call->frame_outid++;
479 load[1] = 0;
425 480
426 if ( !call->crtps[type - TypeAudio] ) return ErrorNoRtpSession; 481 int i;
427 482
428 RTPMessage *message; 483 for (i = 0; i < numparts; i++) {
484 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, VIDEOFRAME_PIECE_SIZE);
485 payload += VIDEOFRAME_PIECE_SIZE;
429 486
430 if ( type == TypeAudio ) { 487 if (rtp_send_msg(call->crtps[type - TypeAudio], av->messenger,
488 load, VIDEOFRAME_HEADER_SIZE + VIDEOFRAME_PIECE_SIZE) != 0) {
431 489
432 do { 490 return ErrorInternal;
433 message = rtp_recv_msg(call->crtps[audio_index]); 491 }
434 492
435 if (message) { 493 load[1]++;
436 /* push the packet into the queue */
437 queue(call->j_buf, message);
438 } 494 }
439 } while (message);
440 495
441 int success = 0; 496 /* remainder = length % VIDEOFRAME_PIECE_SIZE, VIDEOFRAME_PIECE_SIZE if = 0 */
442 message = dequeue(call->j_buf, &success); 497 length = ((length - 1) % VIDEOFRAME_PIECE_SIZE) + 1;
498 memcpy(load + VIDEOFRAME_HEADER_SIZE, payload, length);
443 499
444 if ( success == 2) return ErrorAudioPacketLost; 500 return rtp_send_msg(call->crtps[type - TypeAudio], av->messenger, load, VIDEOFRAME_HEADER_SIZE + length);
501 }
445 } else { 502 } else {
446 message = rtp_recv_msg(call->crtps[video_index]); 503 return ErrorNoRtpSession;
447 }
448
449 if ( message ) {
450 memcpy(dest, message->data, message->length);
451
452 int length = message->length;
453
454 rtp_free_msg(NULL, message);
455
456 return length;
457 } 504 }
458
459 return 0;
460} 505}
461 506
462/** 507/**
463 * @brief Receive decoded video packet. 508 * @brief Encode and send video packet.
464 * 509 *
465 * @param av Handler. 510 * @param av Handler.
466 * @param output Storage. 511 * @param input The packet.
467 * @return int 512 * @return int
468 * @retval 0 Success. 513 * @retval 0 Success.
469 * @retval ToxAvError On Error. 514 * @retval ToxAvError On error.
470 */ 515 */
471inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **output) 516inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size)
472{ 517{
473 if ( !output ) return ErrorInternal; 518 if (cii(call_index, av->msi_session)) {
474 519 LOGGER_WARNING("Invalid call index: %d", call_index);
475 if (cii(call_index, av->msi_session)) return ErrorNoCall; 520 return ErrorNoCall;
521 }
476 522
477 uint8_t packet [RTP_PAYLOAD_SIZE];
478 int recved_size = 0;
479 int rc;
480 CallSpecific *call = &av->calls[call_index]; 523 CallSpecific *call = &av->calls[call_index];
524 pthread_mutex_lock(&call->mutex);
481 525
482 do {
483 recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet);
484
485 if (recved_size > 0 && ( rc = vpx_codec_decode(&call->cs->v_decoder, packet, recved_size, NULL, 0) ) != VPX_CODEC_OK) {
486 LOGGER_ERROR("Error decoding video: %s\n", vpx_codec_err_to_string(rc));
487 return ErrorInternal;
488 }
489
490 } while (recved_size > 0);
491 526
492 vpx_codec_iter_t iter = NULL; 527 if (!call->call_active) {
493 vpx_image_t *img; 528 pthread_mutex_unlock(&call->mutex);
494 img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); 529 LOGGER_WARNING("Action on inactive call: %d", call_index);
495 530 return ErrorNoCall;
496 *output = img; 531 }
497 return 0;
498}
499 532
500/** 533 int rc = toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size);
501 * @brief Encode and send video packet. 534 pthread_mutex_unlock(&call->mutex);
502 *
503 * @param av Handler.
504 * @param input The packet.
505 * @return int
506 * @retval 0 Success.
507 * @retval ToxAvError On error.
508 */
509inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size)
510{
511 if (cii(call_index, av->msi_session)) return ErrorNoCall;
512 535
513 return toxav_send_rtp_payload(av, call_index, TypeVideo, frame, frame_size); 536 return rc;
514} 537}
515 538
516/** 539/**
@@ -526,14 +549,31 @@ inline__ int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *fr
526 */ 549 */
527inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input) 550inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input)
528{ 551{
529 if (cii(call_index, av->msi_session)) return ErrorNoCall; 552 if (cii(call_index, av->msi_session)) {
553 LOGGER_WARNING("Invalid call index: %d", call_index);
554 return ErrorNoCall;
555 }
556
530 557
531 CallSpecific *call = &av->calls[call_index]; 558 CallSpecific *call = &av->calls[call_index];
559 pthread_mutex_lock(&call->mutex);
560
561 if (!call->call_active) {
562 pthread_mutex_unlock(&call->mutex);
563 LOGGER_WARNING("Action on inactive call: %d", call_index);
564 return ErrorNoCall;
565 }
566
567 if (reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h) != 0) {
568 pthread_mutex_unlock(&call->mutex);
569 return ErrorInternal;
570 }
532 571
533 int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); 572 int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);
534 573
535 if ( rc != VPX_CODEC_OK) { 574 if ( rc != VPX_CODEC_OK) {
536 LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc)); 575 LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc));
576 pthread_mutex_unlock(&call->mutex);
537 return ErrorInternal; 577 return ErrorInternal;
538 } 578 }
539 579
@@ -545,61 +585,21 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d
545 585
546 while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) { 586 while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) {
547 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { 587 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
548 if ( copied + pkt->data.frame.sz > dest_max ) return ErrorPacketTooLarge; 588 if ( copied + pkt->data.frame.sz > dest_max ) {
589 pthread_mutex_unlock(&call->mutex);
590 return ErrorPacketTooLarge;
591 }
549 592
550 memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz); 593 memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz);
551 copied += pkt->data.frame.sz; 594 copied += pkt->data.frame.sz;
552 } 595 }
553 } 596 }
554 597
598 pthread_mutex_unlock(&call->mutex);
555 return copied; 599 return copied;
556} 600}
557 601
558/** 602/**
559 * @brief Receive decoded audio frame.
560 *
561 * @param av Handler.
562 * @param frame_size The size of dest in frames/samples (one frame/sample is 16 bits or 2 bytes
563 * and corresponds to one sample of audio.)
564 * @param dest Destination of the raw audio (16 bit signed pcm with AUDIO_CHANNELS channels).
565 * Make sure it has enough space for frame_size frames/samples.
566 * @return int
567 * @retval >=0 Size of received data in frames/samples.
568 * @retval ToxAvError On error.
569 */
570inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, int16_t *dest )
571{
572 if ( !dest ) return ErrorInternal;
573
574 if (cii(call_index, av->msi_session)) return ErrorNoCall;
575
576 CallSpecific *call = &av->calls[call_index];
577
578 uint8_t packet [RTP_PAYLOAD_SIZE];
579
580 int recved_size = toxav_recv_rtp_payload(av, call_index, TypeAudio, packet);
581
582 if ( recved_size == ErrorAudioPacketLost ) {
583 int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
584
585 if ( dec_size < 0 ) {
586 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size));
587 return ErrorInternal;
588 } else return dec_size;
589
590 } else if ( recved_size ) {
591 int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0);
592
593 if ( dec_size < 0 ) {
594 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size));
595 return ErrorInternal;
596 } else return dec_size;
597 } else {
598 return 0; /* Nothing received */
599 }
600}
601
602/**
603 * @brief Send audio frame. 603 * @brief Send audio frame.
604 * 604 *
605 * @param av Handler. 605 * @param av Handler.
@@ -612,9 +612,25 @@ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, i
612 */ 612 */
613inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size) 613inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size)
614{ 614{
615 if (cii(call_index, av->msi_session)) return ErrorNoCall; 615 if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
616 LOGGER_WARNING("Action on inactive call: %d", call_index);
617 return ErrorNoCall;
618 }
619
620 CallSpecific *call = &av->calls[call_index];
621 pthread_mutex_lock(&call->mutex);
622
623
624 if (!call->call_active) {
625 pthread_mutex_unlock(&call->mutex);
626 LOGGER_WARNING("Action on inactive call: %d", call_index);
627 return ErrorNoCall;
628 }
616 629
617 return toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size); 630 int rc = toxav_send_rtp_payload(av, call_index, TypeAudio, frame, frame_size);
631 pthread_mutex_unlock(&call->mutex);
632
633 return rc;
618} 634}
619 635
620/** 636/**
@@ -632,9 +648,23 @@ inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *fr
632inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, 648inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max,
633 const int16_t *frame, int frame_size) 649 const int16_t *frame, int frame_size)
634{ 650{
635 if (cii(call_index, av->msi_session)) return ErrorNoCall; 651 if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
652 LOGGER_WARNING("Action on inactive call: %d", call_index);
653 return ErrorNoCall;
654 }
655
656 CallSpecific *call = &av->calls[call_index];
657 pthread_mutex_lock(&call->mutex);
636 658
637 int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); 659
660 if (!call->call_active) {
661 pthread_mutex_unlock(&call->mutex);
662 LOGGER_WARNING("Action on inactive call: %d", call_index);
663 return ErrorNoCall;
664 }
665
666 int32_t rc = opus_encode(call->cs->audio_encoder, frame, frame_size, dest, dest_max);
667 pthread_mutex_unlock(&call->mutex);
638 668
639 if (rc < 0) { 669 if (rc < 0) {
640 LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); 670 LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc));
@@ -672,8 +702,6 @@ int toxav_get_peer_transmission_type ( ToxAv *av, int32_t call_index, int peer )
672 */ 702 */
673int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer ) 703int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer )
674{ 704{
675 assert(av->msi_session);
676
677 if ( peer < 0 || cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] 705 if ( peer < 0 || cii(call_index, av->msi_session) || !av->msi_session->calls[call_index]
678 || av->msi_session->calls[call_index]->peer_count <= peer ) 706 || av->msi_session->calls[call_index]->peer_count <= peer )
679 return ErrorInternal; 707 return ErrorInternal;
@@ -682,6 +710,23 @@ int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer )
682} 710}
683 711
684/** 712/**
713 * @brief Get id of peer participating in conversation
714 *
715 * @param av Handler
716 * @param peer peer index
717 * @return int
718 * @retval ToxAvError No peer id
719 */
720ToxAvCallState toxav_get_call_state(ToxAv *av, int32_t call_index)
721{
722 if ( cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] )
723 return av_CallNonExistant;
724
725 return av->msi_session->calls[call_index]->state;
726
727}
728
729/**
685 * @brief Is certain capability supported 730 * @brief Is certain capability supported
686 * 731 *
687 * @param av Handler 732 * @param av Handler
@@ -695,43 +740,100 @@ inline__ int toxav_capability_supported ( ToxAv *av, int32_t call_index, ToxAvCa
695 /* 0 is error here */ 740 /* 0 is error here */
696} 741}
697 742
698/** 743inline__ Tox *toxav_get_tox(ToxAv *av)
699 * @brief Set queue limit
700 *
701 * @param av Handler
702 * @param call_index index
703 * @param limit the limit
704 * @return void
705 */
706inline__ int toxav_set_audio_queue_limit(ToxAv *av, int32_t call_index, uint64_t limit)
707{ 744{
708 if ( av->calls[call_index].crtps[audio_index] ) 745 return (Tox *)av->messenger;
709 rtp_queue_adjust_limit(av->calls[call_index].crtps[audio_index], limit);
710 else
711 return ErrorNoRtpSession;
712
713 return ErrorNone;
714} 746}
715 747
716/** 748int toxav_has_activity(ToxAv *av, int32_t call_index, int16_t *PCM, uint16_t frame_size, float ref_energy)
717 * @brief Set queue limit
718 *
719 * @param av Handler
720 * @param call_index index
721 * @param limit the limit
722 * @return void
723 */
724inline__ int toxav_set_video_queue_limit(ToxAv *av, int32_t call_index, uint64_t limit)
725{ 749{
726 if ( av->calls[call_index].crtps[video_index] ) 750 if ( !av->calls[call_index].cs ) return ErrorInvalidCodecState;
727 rtp_queue_adjust_limit(av->calls[call_index].crtps[video_index], limit);
728 else
729 return ErrorNoRtpSession;
730 751
731 return ErrorNone; 752 return energy_VAD(av->calls[call_index].cs, PCM, frame_size, ref_energy);
732} 753}
733 754
734inline__ Tox *toxav_get_tox(ToxAv *av) 755void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg)
735{ 756{
736 return (Tox *)av->messenger; 757 ToxAv *av = _session->av;
737} \ No newline at end of file 758 int32_t call_index = _session->call_index;
759 CallSpecific *call = &av->calls[call_index];
760
761 if (_session->payload_type == type_audio % 128) {
762 queue(call->j_buf, _msg);
763
764 int success = 0, dec_size;
765 int frame_size = 960;
766 int16_t dest[frame_size];
767
768 while ((_msg = dequeue(call->j_buf, &success)) || success == 2) {
769 if (success == 2) {
770 dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
771 } else {
772 dec_size = opus_decode(call->cs->audio_decoder, _msg->data, _msg->length, dest, frame_size, 0);
773 rtp_free_msg(NULL, _msg);
774 }
775
776 if (dec_size < 0) {
777 LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size));
778 continue;
779 }
780
781 av->audio_callback(av, call_index, dest, frame_size);
782 }
783 } else {
784 uint8_t *packet = _msg->data;
785 int recved_size = _msg->length;
786
787 if (recved_size < VIDEOFRAME_HEADER_SIZE) {
788 goto end;
789 }
790
791 uint8_t i = packet[0] - call->frame_id;
792
793 if (i == 0) {
794 /* piece of current frame */
795 } else if (i > 0 && i < 128) {
796 /* recieved a piece of a frame ahead, flush current frame and start reading this new frame */
797 int rc = vpx_codec_decode(&call->cs->v_decoder, call->frame_buf, call->frame_limit, NULL, 0);
798 call->frame_id = packet[0];
799 memset(call->frame_buf, 0, call->frame_limit);
800 call->frame_limit = 0;
801
802 if (rc != VPX_CODEC_OK) {
803 LOGGER_ERROR("Error decoding video: %u %s\n", i, vpx_codec_err_to_string(rc));
804 }
805 } else {
806 /* old packet, dont read */
807 LOGGER_DEBUG("Old packet: %u\n", i);
808 goto end;
809 }
810
811 if (packet[1] > (MAX_VIDEOFRAME_SIZE - VIDEOFRAME_PIECE_SIZE + 1) /
812 VIDEOFRAME_PIECE_SIZE) { //TODO, fix this check? not sure
813 /* packet out of buffer range */
814 goto end;
815 }
816
817 LOGGER_DEBUG("Video Packet: %u %u\n", packet[0], packet[1]);
818 memcpy(call->frame_buf + packet[1] * VIDEOFRAME_PIECE_SIZE, packet + VIDEOFRAME_HEADER_SIZE,
819 recved_size - VIDEOFRAME_HEADER_SIZE);
820 uint32_t limit = packet[1] * VIDEOFRAME_PIECE_SIZE + recved_size - VIDEOFRAME_HEADER_SIZE;
821
822 if (limit > call->frame_limit) {
823 call->frame_limit = limit;
824 LOGGER_DEBUG("Limit: %u\n", call->frame_limit);
825 }
826
827end:
828 ;
829 vpx_codec_iter_t iter = NULL;
830 vpx_image_t *img;
831 img = vpx_codec_get_frame(&call->cs->v_decoder, &iter);
832
833 if (img) {
834 av->video_callback(av, call_index, img);
835 }
836
837 rtp_free_msg(NULL, _msg);
838 }
839}
diff --git a/toxav/toxav.h b/toxav/toxav.h
index 4d988962..0ded42bd 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -17,8 +17,6 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 20 */
23 21
24 22
@@ -26,6 +24,10 @@
26#define __TOXAV 24#define __TOXAV
27#include <inttypes.h> 25#include <inttypes.h>
28 26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
29/* vpx_image_t */ 31/* vpx_image_t */
30#include <vpx/vpx_image.h> 32#include <vpx/vpx_image.h>
31 33
@@ -72,6 +74,15 @@ typedef enum {
72} ToxAvCallType; 74} ToxAvCallType;
73 75
74 76
77typedef enum {
78 av_CallNonExistant = -1,
79 av_CallInviting, /* when sending call invite */
80 av_CallStarting, /* when getting call invite */
81 av_CallActive,
82 av_CallHold,
83 av_CallHanged_up
84} ToxAvCallState;
85
75/** 86/**
76 * @brief Error indicators. 87 * @brief Error indicators.
77 */ 88 */
@@ -88,6 +99,7 @@ typedef enum {
88 ErrorTerminatingAudioRtp = -9, /* Returned in toxav_kill_transmission() */ 99 ErrorTerminatingAudioRtp = -9, /* Returned in toxav_kill_transmission() */
89 ErrorTerminatingVideoRtp = -10, /* Returned in toxav_kill_transmission() */ 100 ErrorTerminatingVideoRtp = -10, /* Returned in toxav_kill_transmission() */
90 ErrorPacketTooLarge = -11, /* Buffer exceeds size while encoding */ 101 ErrorPacketTooLarge = -11, /* Buffer exceeds size while encoding */
102 ErrorInvalidCodecState = -12, /* Codec state not initialized */
91 103
92} ToxAvError; 104} ToxAvError;
93 105
@@ -107,14 +119,15 @@ typedef enum {
107 * @brief Encoding settings. 119 * @brief Encoding settings.
108 */ 120 */
109typedef struct _ToxAvCodecSettings { 121typedef struct _ToxAvCodecSettings {
110 uint32_t video_bitrate; /* In bits/s */ 122 uint32_t video_bitrate; /* In kbits/s */
111 uint16_t video_width; /* In px */ 123 uint16_t max_video_width; /* In px */
112 uint16_t video_height; /* In px */ 124 uint16_t max_video_height; /* In px */
113 125
114 uint32_t audio_bitrate; /* In bits/s */ 126 uint32_t audio_bitrate; /* In bits/s */
115 uint16_t audio_frame_duration; /* In ms */ 127 uint16_t audio_frame_duration; /* In ms */
116 uint32_t audio_sample_rate; /* In Hz */ 128 uint32_t audio_sample_rate; /* In Hz */
117 uint32_t audio_channels; 129 uint32_t audio_channels;
130 uint32_t audio_VAD_tolerance; /* In ms */
118 131
119 uint32_t jbuf_capacity; /* Size of jitter buffer */ 132 uint32_t jbuf_capacity; /* Size of jitter buffer */
120} ToxAvCodecSettings; 133} ToxAvCodecSettings;
@@ -152,6 +165,22 @@ void toxav_kill(ToxAv *av);
152void toxav_register_callstate_callback (ToxAVCallback callback, ToxAvCallbackID id, void *userdata); 165void toxav_register_callstate_callback (ToxAVCallback callback, ToxAvCallbackID id, void *userdata);
153 166
154/** 167/**
168 * @brief Register callback for recieving audio data
169 *
170 * @param callback The callback
171 * @return void
172 */
173void toxav_register_audio_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, int16_t *, int));
174
175/**
176 * @brief Register callback for recieving video data
177 *
178 * @param callback The callback
179 * @return void
180 */
181void toxav_register_video_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, vpx_image_t *));
182
183/**
155 * @brief Call user. Use its friend_id. 184 * @brief Call user. Use its friend_id.
156 * 185 *
157 * @param av Handler. 186 * @param av Handler.
@@ -240,31 +269,6 @@ int toxav_prepare_transmission(ToxAv *av, int32_t call_index, ToxAvCodecSettings
240int toxav_kill_transmission(ToxAv *av, int32_t call_index); 269int toxav_kill_transmission(ToxAv *av, int32_t call_index);
241 270
242/** 271/**
243 * @brief Receive decoded video packet.
244 *
245 * @param av Handler.
246 * @param output Storage.
247 * @return int
248 * @retval 0 Success.
249 * @retval ToxAvError On Error.
250 */
251int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **output);
252
253/**
254 * @brief Receive decoded audio frame.
255 *
256 * @param av Handler.
257 * @param frame_size The size of dest in frames/samples (one frame/sample is 16 bits or 2 bytes
258 * and corresponds to one sample of audio.)
259 * @param dest Destination of the raw audio (16 bit signed pcm with AUDIO_CHANNELS channels).
260 * Make sure it has enough space for frame_size frames/samples.
261 * @return int
262 * @retval >=0 Size of received data in frames/samples.
263 * @retval ToxAvError On error.
264 */
265int toxav_recv_audio( ToxAv *av, int32_t call_index, int frame_size, int16_t *dest );
266
267/**
268 * @brief Encode and send video packet. 272 * @brief Encode and send video packet.
269 * 273 *
270 * @param av Handler. 274 * @param av Handler.
@@ -339,6 +343,15 @@ int toxav_get_peer_transmission_type ( ToxAv *av, int32_t call_index, int peer )
339int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer ); 343int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer );
340 344
341/** 345/**
346 * @brief Get current call state
347 *
348 * @param av Handler
349 * @param call_index What call
350 * @return int
351 * @retval ToxAvCallState State id
352 */
353ToxAvCallState toxav_get_call_state ( ToxAv *av, int32_t call_index );
354/**
342 * @brief Is certain capability supported 355 * @brief Is certain capability supported
343 * 356 *
344 * @param av Handler 357 * @param av Handler
@@ -370,4 +383,11 @@ int toxav_set_video_queue_limit ( ToxAv *av, int32_t call_index, uint64_t limit
370 383
371 384
372Tox *toxav_get_tox(ToxAv *av); 385Tox *toxav_get_tox(ToxAv *av);
373#endif /* __TOXAV */ \ No newline at end of file 386
387int toxav_has_activity ( ToxAv *av, int32_t call_index, int16_t *PCM, uint16_t frame_size, float ref_energy );
388
389#ifdef __cplusplus
390}
391#endif
392
393#endif /* __TOXAV */
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index b09ea0c9..77d126c1 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -2212,7 +2212,7 @@ static int random_node_fromlist(Client_data *list, uint16_t list_size, Node_form
2212 * 2212 *
2213 * TODO: remove the LAN stuff from this. 2213 * TODO: remove the LAN stuff from this.
2214 */ 2214 */
2215uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num) 2215uint16_t random_nodes_path(const DHT *dht, Node_format *nodes, uint16_t max_num)
2216{ 2216{
2217 if (max_num == 0) 2217 if (max_num == 0)
2218 return 0; 2218 return 0;
@@ -2221,11 +2221,11 @@ uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num)
2221 return 0; 2221 return 0;
2222 2222
2223 uint16_t count = 0; 2223 uint16_t count = 0;
2224 Client_data *list = NULL;
2225 uint16_t list_size = 0; 2224 uint16_t list_size = 0;
2226 uint32_t i; 2225 uint32_t i;
2227 2226
2228 for (i = 0; i < max_num; ++i) { 2227 for (i = 0; i < max_num; ++i) {
2228 Client_data *list = NULL;
2229 uint16_t rand_num = rand() % (dht->num_friends); 2229 uint16_t rand_num = rand() % (dht->num_friends);
2230 list = dht->friends_list[rand_num].client_list; 2230 list = dht->friends_list[rand_num].client_list;
2231 list_size = MAX_FRIEND_CLIENTS; 2231 list_size = MAX_FRIEND_CLIENTS;
diff --git a/toxcore/DHT.h b/toxcore/DHT.h
index c7fddb4f..ea94e4ca 100644
--- a/toxcore/DHT.h
+++ b/toxcore/DHT.h
@@ -306,7 +306,7 @@ uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num);
306 * 306 *
307 * NOTE:this is used to pick nodes for paths. 307 * NOTE:this is used to pick nodes for paths.
308 */ 308 */
309uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num); 309uint16_t random_nodes_path(const DHT *dht, Node_format *nodes, uint16_t max_num);
310 310
311/* Run this function at least a couple times per second (It's the main loop). */ 311/* Run this function at least a couple times per second (It's the main loop). */
312void do_DHT(DHT *dht); 312void do_DHT(DHT *dht);
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 3f913d4c..b65f09ae 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -40,10 +40,11 @@
40 40
41 41
42static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status); 42static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status);
43static int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); 43static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data,
44 uint32_t length);
44 45
45// friend_not_valid determines if the friendnumber passed is valid in the Messenger object 46// friend_not_valid determines if the friendnumber passed is valid in the Messenger object
46static uint8_t friend_not_valid(Messenger *m, int32_t friendnumber) 47static uint8_t friend_not_valid(const Messenger *m, int32_t friendnumber)
47{ 48{
48 return (unsigned int)friendnumber >= m->numfriends; 49 return (unsigned int)friendnumber >= m->numfriends;
49} 50}
@@ -109,7 +110,7 @@ int32_t getfriend_id(const Messenger *m, const uint8_t *client_id)
109 * return 0 if success. 110 * return 0 if success.
110 * return -1 if failure. 111 * return -1 if failure.
111 */ 112 */
112int getclient_id(Messenger *m, int32_t friendnumber, uint8_t *client_id) 113int getclient_id(const Messenger *m, int32_t friendnumber, uint8_t *client_id)
113{ 114{
114 if (friend_not_valid(m, friendnumber)) 115 if (friend_not_valid(m, friendnumber))
115 return -1; 116 return -1;
@@ -125,7 +126,7 @@ int getclient_id(Messenger *m, int32_t friendnumber, uint8_t *client_id)
125 * 126 *
126 * return a uint16_t that represents the checksum of address of length len. 127 * return a uint16_t that represents the checksum of address of length len.
127 */ 128 */
128static uint16_t address_checksum(uint8_t *address, uint32_t len) 129static uint16_t address_checksum(const uint8_t *address, uint32_t len)
129{ 130{
130 uint8_t checksum[2] = {0}; 131 uint8_t checksum[2] = {0};
131 uint16_t check; 132 uint16_t check;
@@ -142,7 +143,7 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len)
142 * 143 *
143 * return FRIEND_ADDRESS_SIZE byte address to give to others. 144 * return FRIEND_ADDRESS_SIZE byte address to give to others.
144 */ 145 */
145void getaddress(Messenger *m, uint8_t *address) 146void getaddress(const Messenger *m, uint8_t *address)
146{ 147{
147 id_copy(address, m->net_crypto->self_public_key); 148 id_copy(address, m->net_crypto->self_public_key);
148 uint32_t nospam = get_nospam(&(m->fr)); 149 uint32_t nospam = get_nospam(&(m->fr));
@@ -152,7 +153,7 @@ void getaddress(Messenger *m, uint8_t *address)
152} 153}
153 154
154/* callback for recv TCP relay nodes. */ 155/* callback for recv TCP relay nodes. */
155static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, uint8_t *public_key) 156static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key)
156{ 157{
157 Messenger *m = object; 158 Messenger *m = object;
158 159
@@ -183,7 +184,7 @@ static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_por
183 * (the nospam for that friend was set to the new one). 184 * (the nospam for that friend was set to the new one).
184 * return FAERR_NOMEM if increasing the friend list size fails. 185 * return FAERR_NOMEM if increasing the friend list size fails.
185 */ 186 */
186int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) 187int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, uint16_t length)
187{ 188{
188 if (length > MAX_FRIEND_REQUEST_DATA_SIZE) 189 if (length > MAX_FRIEND_REQUEST_DATA_SIZE)
189 return FAERR_TOOLONG; 190 return FAERR_TOOLONG;
@@ -346,7 +347,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
346 return 0; 347 return 0;
347} 348}
348 349
349int m_get_friend_connectionstatus(Messenger *m, int32_t friendnumber) 350int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber)
350{ 351{
351 if (friend_not_valid(m, friendnumber)) 352 if (friend_not_valid(m, friendnumber))
352 return -1; 353 return -1;
@@ -354,7 +355,7 @@ int m_get_friend_connectionstatus(Messenger *m, int32_t friendnumber)
354 return m->friendlist[friendnumber].status == FRIEND_ONLINE; 355 return m->friendlist[friendnumber].status == FRIEND_ONLINE;
355} 356}
356 357
357int m_friend_exists(Messenger *m, int32_t friendnumber) 358int m_friend_exists(const Messenger *m, int32_t friendnumber)
358{ 359{
359 if (friend_not_valid(m, friendnumber)) 360 if (friend_not_valid(m, friendnumber))
360 return 0; 361 return 0;
@@ -402,7 +403,7 @@ uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid
402 * return the message id if packet was successfully put into the send queue. 403 * return the message id if packet was successfully put into the send queue.
403 * return 0 if it was not. 404 * return 0 if it was not.
404 */ 405 */
405uint32_t m_sendaction(Messenger *m, int32_t friendnumber, uint8_t *action, uint32_t length) 406uint32_t m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length)
406{ 407{
407 if (friend_not_valid(m, friendnumber)) 408 if (friend_not_valid(m, friendnumber))
408 return 0; 409 return 0;
@@ -419,7 +420,8 @@ uint32_t m_sendaction(Messenger *m, int32_t friendnumber, uint8_t *action, uint3
419 return 0; 420 return 0;
420} 421}
421 422
422uint32_t m_sendaction_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length) 423uint32_t m_sendaction_withid(const Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *action,
424 uint32_t length)
423{ 425{
424 if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid))) 426 if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)))
425 return 0; 427 return 0;
@@ -434,7 +436,7 @@ uint32_t m_sendaction_withid(Messenger *m, int32_t friendnumber, uint32_t theid,
434/* Send a name packet to friendnumber. 436/* Send a name packet to friendnumber.
435 * length is the length with the NULL terminator. 437 * length is the length with the NULL terminator.
436 */ 438 */
437static int m_sendname(Messenger *m, int32_t friendnumber, uint8_t *name, uint16_t length) 439static int m_sendname(const Messenger *m, int32_t friendnumber, const uint8_t *name, uint16_t length)
438{ 440{
439 if (length > MAX_NAME_LENGTH || length == 0) 441 if (length > MAX_NAME_LENGTH || length == 0)
440 return 0; 442 return 0;
@@ -447,7 +449,7 @@ static int m_sendname(Messenger *m, int32_t friendnumber, uint8_t *name, uint16_
447 * return 0 if success. 449 * return 0 if success.
448 * return -1 if failure. 450 * return -1 if failure.
449 */ 451 */
450int setfriendname(Messenger *m, int32_t friendnumber, uint8_t *name, uint16_t length) 452int setfriendname(Messenger *m, int32_t friendnumber, const uint8_t *name, uint16_t length)
451{ 453{
452 if (friend_not_valid(m, friendnumber)) 454 if (friend_not_valid(m, friendnumber))
453 return -1; 455 return -1;
@@ -492,7 +494,7 @@ int setname(Messenger *m, const uint8_t *name, uint16_t length)
492 * 494 *
493 * return the length of the name. 495 * return the length of the name.
494 */ 496 */
495uint16_t getself_name(Messenger *m, uint8_t *name) 497uint16_t getself_name(const Messenger *m, uint8_t *name)
496{ 498{
497 if (name == NULL) { 499 if (name == NULL) {
498 return 0; 500 return 0;
@@ -509,7 +511,7 @@ uint16_t getself_name(Messenger *m, uint8_t *name)
509 * return length of name if success. 511 * return length of name if success.
510 * return -1 if failure. 512 * return -1 if failure.
511 */ 513 */
512int getname(Messenger *m, int32_t friendnumber, uint8_t *name) 514int getname(const Messenger *m, int32_t friendnumber, uint8_t *name)
513{ 515{
514 if (friend_not_valid(m, friendnumber)) 516 if (friend_not_valid(m, friendnumber))
515 return -1; 517 return -1;
@@ -518,7 +520,7 @@ int getname(Messenger *m, int32_t friendnumber, uint8_t *name)
518 return m->friendlist[friendnumber].name_length; 520 return m->friendlist[friendnumber].name_length;
519} 521}
520 522
521int m_get_name_size(Messenger *m, int32_t friendnumber) 523int m_get_name_size(const Messenger *m, int32_t friendnumber)
522{ 524{
523 if (friend_not_valid(m, friendnumber)) 525 if (friend_not_valid(m, friendnumber))
524 return -1; 526 return -1;
@@ -526,7 +528,7 @@ int m_get_name_size(Messenger *m, int32_t friendnumber)
526 return m->friendlist[friendnumber].name_length; 528 return m->friendlist[friendnumber].name_length;
527} 529}
528 530
529int m_get_self_name_size(Messenger *m) 531int m_get_self_name_size(const Messenger *m)
530{ 532{
531 return m->name_length; 533 return m->name_length;
532} 534}
@@ -565,7 +567,7 @@ int m_set_userstatus(Messenger *m, uint8_t status)
565/* return the size of friendnumber's user status. 567/* return the size of friendnumber's user status.
566 * Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH. 568 * Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH.
567 */ 569 */
568int m_get_statusmessage_size(Messenger *m, int32_t friendnumber) 570int m_get_statusmessage_size(const Messenger *m, int32_t friendnumber)
569{ 571{
570 if (friend_not_valid(m, friendnumber)) 572 if (friend_not_valid(m, friendnumber))
571 return -1; 573 return -1;
@@ -576,32 +578,35 @@ int m_get_statusmessage_size(Messenger *m, int32_t friendnumber)
576/* Copy the user status of friendnumber into buf, truncating if needed to maxlen 578/* Copy the user status of friendnumber into buf, truncating if needed to maxlen
577 * bytes, use m_get_statusmessage_size to find out how much you need to allocate. 579 * bytes, use m_get_statusmessage_size to find out how much you need to allocate.
578 */ 580 */
579int m_copy_statusmessage(Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen) 581int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen)
580{ 582{
581 if (friend_not_valid(m, friendnumber)) 583 if (friend_not_valid(m, friendnumber))
582 return -1; 584 return -1;
583 585
584 memset(buf, 0, maxlen); 586 int msglen = MIN(maxlen, m->friendlist[friendnumber].statusmessage_length);
585 memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, m->friendlist[friendnumber].statusmessage_length)); 587
586 return MIN(maxlen, m->friendlist[friendnumber].statusmessage_length); 588 memcpy(buf, m->friendlist[friendnumber].statusmessage, msglen);
589 memset(buf + msglen, 0, maxlen - msglen);
590 return msglen;
587} 591}
588 592
589/* return the size of friendnumber's user status. 593/* return the size of friendnumber's user status.
590 * Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH. 594 * Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH.
591 */ 595 */
592int m_get_self_statusmessage_size(Messenger *m) 596int m_get_self_statusmessage_size(const Messenger *m)
593{ 597{
594 return m->statusmessage_length; 598 return m->statusmessage_length;
595} 599}
596 600
597int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen) 601int m_copy_self_statusmessage(const Messenger *m, uint8_t *buf, uint32_t maxlen)
598{ 602{
599 memset(buf, 0, maxlen); 603 int msglen = MIN(maxlen, m->statusmessage_length);
600 memcpy(buf, m->statusmessage, MIN(maxlen, m->statusmessage_length)); 604 memcpy(buf, m->statusmessage, msglen);
601 return MIN(maxlen, m->statusmessage_length); 605 memset(buf + msglen, 0, maxlen - msglen);
606 return msglen;
602} 607}
603 608
604uint8_t m_get_userstatus(Messenger *m, int32_t friendnumber) 609uint8_t m_get_userstatus(const Messenger *m, int32_t friendnumber)
605{ 610{
606 if (friend_not_valid(m, friendnumber)) 611 if (friend_not_valid(m, friendnumber))
607 return USERSTATUS_INVALID; 612 return USERSTATUS_INVALID;
@@ -615,12 +620,12 @@ uint8_t m_get_userstatus(Messenger *m, int32_t friendnumber)
615 return status; 620 return status;
616} 621}
617 622
618uint8_t m_get_self_userstatus(Messenger *m) 623uint8_t m_get_self_userstatus(const Messenger *m)
619{ 624{
620 return m->userstatus; 625 return m->userstatus;
621} 626}
622 627
623uint64_t m_get_last_online(Messenger *m, int32_t friendnumber) 628uint64_t m_get_last_online(const Messenger *m, int32_t friendnumber)
624{ 629{
625 if (friend_not_valid(m, friendnumber)) 630 if (friend_not_valid(m, friendnumber))
626 return -1; 631 return -1;
@@ -644,7 +649,7 @@ int m_set_usertyping(Messenger *m, int32_t friendnumber, uint8_t is_typing)
644 return 0; 649 return 0;
645} 650}
646 651
647uint8_t m_get_istyping(Messenger *m, int32_t friendnumber) 652uint8_t m_get_istyping(const Messenger *m, int32_t friendnumber)
648{ 653{
649 if (friend_not_valid(m, friendnumber)) 654 if (friend_not_valid(m, friendnumber))
650 return -1; 655 return -1;
@@ -652,23 +657,23 @@ uint8_t m_get_istyping(Messenger *m, int32_t friendnumber)
652 return m->friendlist[friendnumber].is_typing; 657 return m->friendlist[friendnumber].is_typing;
653} 658}
654 659
655static int send_statusmessage(Messenger *m, int32_t friendnumber, uint8_t *status, uint16_t length) 660static int send_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length)
656{ 661{
657 return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length); 662 return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length);
658} 663}
659 664
660static int send_userstatus(Messenger *m, int32_t friendnumber, uint8_t status) 665static int send_userstatus(const Messenger *m, int32_t friendnumber, uint8_t status)
661{ 666{
662 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &status, sizeof(status)); 667 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &status, sizeof(status));
663} 668}
664 669
665static int send_user_istyping(Messenger *m, int32_t friendnumber, uint8_t is_typing) 670static int send_user_istyping(const Messenger *m, int32_t friendnumber, uint8_t is_typing)
666{ 671{
667 uint8_t typing = is_typing; 672 uint8_t typing = is_typing;
668 return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing)); 673 return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing));
669} 674}
670 675
671static int send_ping(Messenger *m, int32_t friendnumber) 676static int send_ping(const Messenger *m, int32_t friendnumber)
672{ 677{
673 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_ALIVE, 0, 0); 678 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_ALIVE, 0, 0);
674 679
@@ -678,7 +683,7 @@ static int send_ping(Messenger *m, int32_t friendnumber)
678 return ret; 683 return ret;
679} 684}
680 685
681static int send_relays(Messenger *m, int32_t friendnumber) 686static int send_relays(const Messenger *m, int32_t friendnumber)
682{ 687{
683 Node_format nodes[MAX_SHARED_RELAYS]; 688 Node_format nodes[MAX_SHARED_RELAYS];
684 uint8_t data[1024]; 689 uint8_t data[1024];
@@ -697,7 +702,7 @@ static int send_relays(Messenger *m, int32_t friendnumber)
697 702
698 703
699 704
700static int set_friend_statusmessage(Messenger *m, int32_t friendnumber, uint8_t *status, uint16_t length) 705static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length)
701{ 706{
702 if (friend_not_valid(m, friendnumber)) 707 if (friend_not_valid(m, friendnumber))
703 return -1; 708 return -1;
@@ -710,12 +715,12 @@ static int set_friend_statusmessage(Messenger *m, int32_t friendnumber, uint8_t
710 return 0; 715 return 0;
711} 716}
712 717
713static void set_friend_userstatus(Messenger *m, int32_t friendnumber, uint8_t status) 718static void set_friend_userstatus(const Messenger *m, int32_t friendnumber, uint8_t status)
714{ 719{
715 m->friendlist[friendnumber].userstatus = status; 720 m->friendlist[friendnumber].userstatus = status;
716} 721}
717 722
718static void set_friend_typing(Messenger *m, int32_t friendnumber, uint8_t is_typing) 723static void set_friend_typing(const Messenger *m, int32_t friendnumber, uint8_t is_typing)
719{ 724{
720 m->friendlist[friendnumber].is_typing = is_typing; 725 m->friendlist[friendnumber].is_typing = is_typing;
721} 726}
@@ -742,28 +747,28 @@ void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const
742} 747}
743 748
744/* Set the function that will be executed when a message from a friend is received. */ 749/* Set the function that will be executed when a message from a friend is received. */
745void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 750void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
746 void *userdata) 751 void *userdata)
747{ 752{
748 m->friend_message = function; 753 m->friend_message = function;
749 m->friend_message_userdata = userdata; 754 m->friend_message_userdata = userdata;
750} 755}
751 756
752void m_callback_action(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 757void m_callback_action(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
753 void *userdata) 758 void *userdata)
754{ 759{
755 m->friend_action = function; 760 m->friend_action = function;
756 m->friend_action_userdata = userdata; 761 m->friend_action_userdata = userdata;
757} 762}
758 763
759void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 764void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
760 void *userdata) 765 void *userdata)
761{ 766{
762 m->friend_namechange = function; 767 m->friend_namechange = function;
763 m->friend_namechange_userdata = userdata; 768 m->friend_namechange_userdata = userdata;
764} 769}
765 770
766void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 771void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
767 void *userdata) 772 void *userdata)
768{ 773{
769 m->friend_statusmessagechange = function; 774 m->friend_statusmessagechange = function;
@@ -801,7 +806,7 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess
801 m->friend_connectionstatuschange_internal_userdata = userdata; 806 m->friend_connectionstatuschange_internal_userdata = userdata;
802} 807}
803 808
804static void break_files(Messenger *m, int32_t friendnumber); 809static void break_files(const Messenger *m, int32_t friendnumber);
805static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, uint8_t status) 810static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, uint8_t status)
806{ 811{
807 if (status == NOFRIEND) 812 if (status == NOFRIEND)
@@ -837,7 +842,8 @@ void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status)
837 m->friendlist[friendnumber].status = status; 842 m->friendlist[friendnumber].status = status;
838} 843}
839 844
840int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length) 845int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data,
846 uint32_t length)
841{ 847{
842 if (friend_not_valid(m, friendnumber)) 848 if (friend_not_valid(m, friendnumber))
843 return 0; 849 return 0;
@@ -859,7 +865,7 @@ int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id,
859/* return 1 if the groupnumber is not valid. 865/* return 1 if the groupnumber is not valid.
860 * return 0 if the groupnumber is valid. 866 * return 0 if the groupnumber is valid.
861 */ 867 */
862static uint8_t groupnumber_not_valid(Messenger *m, int groupnumber) 868static uint8_t groupnumber_not_valid(const Messenger *m, int groupnumber)
863{ 869{
864 if ((unsigned int)groupnumber >= m->numchats) 870 if ((unsigned int)groupnumber >= m->numchats)
865 return 1; 871 return 1;
@@ -877,7 +883,7 @@ static uint8_t groupnumber_not_valid(Messenger *m, int groupnumber)
877/* returns valid ip port of connected friend on success 883/* returns valid ip port of connected friend on success
878 * returns zeroed out IP_Port on failure 884 * returns zeroed out IP_Port on failure
879 */ 885 */
880static IP_Port get_friend_ipport(Messenger *m, int32_t friendnumber) 886static IP_Port get_friend_ipport(const Messenger *m, int32_t friendnumber)
881{ 887{
882 IP_Port zero; 888 IP_Port zero;
883 memset(&zero, 0, sizeof(zero)); 889 memset(&zero, 0, sizeof(zero));
@@ -901,7 +907,7 @@ static IP_Port get_friend_ipport(Messenger *m, int32_t friendnumber)
901/* returns the group number of the chat with public key group_public_key. 907/* returns the group number of the chat with public key group_public_key.
902 * returns -1 on failure. 908 * returns -1 on failure.
903 */ 909 */
904static int group_num(Messenger *m, uint8_t *group_public_key) 910static int group_num(const Messenger *m, const uint8_t *group_public_key)
905{ 911{
906 uint32_t i; 912 uint32_t i;
907 913
@@ -918,7 +924,8 @@ static int group_num(Messenger *m, uint8_t *group_public_key)
918 * 924 *
919 * Function(Messenger *m, int32_t friendnumber, uint8_t *group_public_key, void *userdata) 925 * Function(Messenger *m, int32_t friendnumber, uint8_t *group_public_key, void *userdata)
920 */ 926 */
921void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, void *), void *userdata) 927void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, void *),
928 void *userdata)
922{ 929{
923 m->group_invite = function; 930 m->group_invite = function;
924 m->group_invite_userdata = userdata; 931 m->group_invite_userdata = userdata;
@@ -928,7 +935,7 @@ void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_
928 * 935 *
929 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) 936 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
930 */ 937 */
931void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t *, uint16_t, void *), 938void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *),
932 void *userdata) 939 void *userdata)
933{ 940{
934 m->group_message = function; 941 m->group_message = function;
@@ -939,7 +946,7 @@ void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int,
939 * 946 *
940 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) 947 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
941 */ 948 */
942void m_callback_group_action(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t *, uint16_t, void *), 949void m_callback_group_action(Messenger *m, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *),
943 void *userdata) 950 void *userdata)
944{ 951{
945 m->group_action = function; 952 m->group_action = function;
@@ -958,7 +965,7 @@ void m_callback_group_namelistchange(Messenger *m, void (*function)(Messenger *m
958 m->group_namelistchange_userdata = userdata; 965 m->group_namelistchange_userdata = userdata;
959} 966}
960 967
961static int get_chat_num(Messenger *m, Group_Chat *chat) 968static int get_chat_num(const Messenger *m, const Group_Chat *chat)
962{ 969{
963 uint32_t i; 970 uint32_t i;
964 971
@@ -1111,7 +1118,7 @@ int del_groupchat(Messenger *m, int groupnumber)
1111 * return length of name if success 1118 * return length of name if success
1112 * return -1 if failure 1119 * return -1 if failure
1113 */ 1120 */
1114int m_group_peername(Messenger *m, int groupnumber, int peernumber, uint8_t *name) 1121int m_group_peername(const Messenger *m, int groupnumber, int peernumber, uint8_t *name)
1115{ 1122{
1116 if ((unsigned int)groupnumber >= m->numchats) 1123 if ((unsigned int)groupnumber >= m->numchats)
1117 return -1; 1124 return -1;
@@ -1138,7 +1145,7 @@ static void group_store_friendinvite(Messenger *m, int32_t friendnumber, int gro
1138/* return 1 if that friend was invited to the group 1145/* return 1 if that friend was invited to the group
1139 * return 0 if the friend was not or error. 1146 * return 0 if the friend was not or error.
1140 */ 1147 */
1141static uint8_t group_invited(Messenger *m, int32_t friendnumber, int groupnumber) 1148static uint8_t group_invited(const Messenger *m, int32_t friendnumber, int groupnumber)
1142{ 1149{
1143 1150
1144 uint32_t i; 1151 uint32_t i;
@@ -1186,7 +1193,7 @@ int invite_friend(Messenger *m, int32_t friendnumber, int groupnumber)
1186 * returns group number on success 1193 * returns group number on success
1187 * returns -1 on failure. 1194 * returns -1 on failure.
1188 */ 1195 */
1189int join_groupchat(Messenger *m, int32_t friendnumber, uint8_t *friend_group_public_key) 1196int join_groupchat(Messenger *m, int32_t friendnumber, const uint8_t *friend_group_public_key)
1190{ 1197{
1191 if (friend_not_valid(m, friendnumber)) 1198 if (friend_not_valid(m, friendnumber))
1192 return -1; 1199 return -1;
@@ -1199,8 +1206,10 @@ int join_groupchat(Messenger *m, int32_t friendnumber, uint8_t *friend_group_pub
1199 1206
1200 IP_Port friend_ip = get_friend_ipport(m, friendnumber); 1207 IP_Port friend_ip = get_friend_ipport(m, friendnumber);
1201 1208
1202 if (friend_ip.ip.family == 0) 1209 if (friend_ip.ip.family == 0) {
1210 del_groupchat(m, groupnum);
1203 return -1; 1211 return -1;
1212 }
1204 1213
1205 id_copy(data, friend_group_public_key); 1214 id_copy(data, friend_group_public_key);
1206 id_copy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key); 1215 id_copy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key);
@@ -1211,6 +1220,7 @@ int join_groupchat(Messenger *m, int32_t friendnumber, uint8_t *friend_group_pub
1211 return groupnum; 1220 return groupnum;
1212 } 1221 }
1213 1222
1223 del_groupchat(m, groupnum);
1214 return -1; 1224 return -1;
1215} 1225}
1216 1226
@@ -1219,7 +1229,7 @@ int join_groupchat(Messenger *m, int32_t friendnumber, uint8_t *friend_group_pub
1219 * return 0 on success 1229 * return 0 on success
1220 * return -1 on failure 1230 * return -1 on failure
1221 */ 1231 */
1222int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length) 1232int group_message_send(const Messenger *m, int groupnumber, const uint8_t *message, uint32_t length)
1223{ 1233{
1224 if (groupnumber_not_valid(m, groupnumber)) 1234 if (groupnumber_not_valid(m, groupnumber))
1225 return -1; 1235 return -1;
@@ -1234,7 +1244,7 @@ int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t
1234 * return 0 on success 1244 * return 0 on success
1235 * return -1 on failure 1245 * return -1 on failure
1236 */ 1246 */
1237int group_action_send(Messenger *m, int groupnumber, uint8_t *action, uint32_t length) 1247int group_action_send(const Messenger *m, int groupnumber, const uint8_t *action, uint32_t length)
1238{ 1248{
1239 if (groupnumber_not_valid(m, groupnumber)) 1249 if (groupnumber_not_valid(m, groupnumber))
1240 return -1; 1250 return -1;
@@ -1248,7 +1258,7 @@ int group_action_send(Messenger *m, int groupnumber, uint8_t *action, uint32_t l
1248/* Return the number of peers in the group chat on success. 1258/* Return the number of peers in the group chat on success.
1249 * return -1 on failure 1259 * return -1 on failure
1250 */ 1260 */
1251int group_number_peers(Messenger *m, int groupnumber) 1261int group_number_peers(const Messenger *m, int groupnumber)
1252{ 1262{
1253 if (groupnumber_not_valid(m, groupnumber)) 1263 if (groupnumber_not_valid(m, groupnumber))
1254 return -1; 1264 return -1;
@@ -1266,7 +1276,8 @@ int group_number_peers(Messenger *m, int groupnumber)
1266 * 1276 *
1267 * return -1 on failure. 1277 * return -1 on failure.
1268 */ 1278 */
1269int group_names(Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[], uint16_t length) 1279int group_names(const Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[],
1280 uint16_t length)
1270{ 1281{
1271 if (groupnumber_not_valid(m, groupnumber)) 1282 if (groupnumber_not_valid(m, groupnumber))
1272 return -1; 1283 return -1;
@@ -1312,7 +1323,7 @@ static void do_allgroupchats(Messenger *m)
1312 * 1323 *
1313 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata) 1324 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata)
1314 */ 1325 */
1315void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint64_t, uint8_t *, 1326void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint64_t, const uint8_t *,
1316 uint16_t, void *), void *userdata) 1327 uint16_t, void *), void *userdata)
1317{ 1328{
1318 m->file_sendrequest = function; 1329 m->file_sendrequest = function;
@@ -1324,8 +1335,8 @@ void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int3
1324 * Function(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata) 1335 * Function(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata)
1325 * 1336 *
1326 */ 1337 */
1327void callback_file_control(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, 1338void callback_file_control(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t, uint8_t,
1328 uint16_t, void *), void *userdata) 1339 const uint8_t *, uint16_t, void *), void *userdata)
1329{ 1340{
1330 m->file_filecontrol = function; 1341 m->file_filecontrol = function;
1331 m->file_filecontrol_userdata = userdata; 1342 m->file_filecontrol_userdata = userdata;
@@ -1336,7 +1347,7 @@ void callback_file_control(Messenger *m, void (*function)(Messenger *m, int32_t,
1336 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) 1347 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata)
1337 * 1348 *
1338 */ 1349 */
1339void callback_file_data(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t *, uint16_t length, 1350void callback_file_data(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, const uint8_t *, uint16_t length,
1340 void *), void *userdata) 1351 void *), void *userdata)
1341{ 1352{
1342 m->file_filedata = function; 1353 m->file_filedata = function;
@@ -1350,8 +1361,8 @@ void callback_file_data(Messenger *m, void (*function)(Messenger *m, int32_t, ui
1350 * return 1 on success 1361 * return 1 on success
1351 * return 0 on failure 1362 * return 0 on failure
1352 */ 1363 */
1353int file_sendrequest(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, 1364int file_sendrequest(const Messenger *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize,
1354 uint16_t filename_length) 1365 const uint8_t *filename, uint16_t filename_length)
1355{ 1366{
1356 if (friend_not_valid(m, friendnumber)) 1367 if (friend_not_valid(m, friendnumber))
1357 return 0; 1368 return 0;
@@ -1373,7 +1384,8 @@ int file_sendrequest(Messenger *m, int32_t friendnumber, uint8_t filenumber, uin
1373 * return file number on success 1384 * return file number on success
1374 * return -1 on failure 1385 * return -1 on failure
1375 */ 1386 */
1376int new_filesender(Messenger *m, int32_t friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length) 1387int new_filesender(const Messenger *m, int32_t friendnumber, uint64_t filesize, const uint8_t *filename,
1388 uint16_t filename_length)
1377{ 1389{
1378 if (friend_not_valid(m, friendnumber)) 1390 if (friend_not_valid(m, friendnumber))
1379 return -1; 1391 return -1;
@@ -1403,8 +1415,8 @@ int new_filesender(Messenger *m, int32_t friendnumber, uint64_t filesize, uint8_
1403 * return 0 on success 1415 * return 0 on success
1404 * return -1 on failure 1416 * return -1 on failure
1405 */ 1417 */
1406int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, 1418int file_control(const Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id,
1407 uint8_t *data, uint16_t length) 1419 const uint8_t *data, uint16_t length)
1408{ 1420{
1409 if (length > MAX_CRYPTO_DATA_SIZE - 3) 1421 if (length > MAX_CRYPTO_DATA_SIZE - 3)
1410 return -1; 1422 return -1;
@@ -1485,13 +1497,13 @@ int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8
1485 } 1497 }
1486} 1498}
1487 1499
1488#define MIN_SLOTS_FREE 4 1500#define MIN_SLOTS_FREE (CRYPTO_MIN_QUEUE_LENGTH / 2)
1489/* Send file data. 1501/* Send file data.
1490 * 1502 *
1491 * return 0 on success 1503 * return 0 on success
1492 * return -1 on failure 1504 * return -1 on failure
1493 */ 1505 */
1494int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length) 1506int file_data(const Messenger *m, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length)
1495{ 1507{
1496 if (length > MAX_CRYPTO_DATA_SIZE - 1) 1508 if (length > MAX_CRYPTO_DATA_SIZE - 1)
1497 return -1; 1509 return -1;
@@ -1526,7 +1538,7 @@ int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *d
1526 * return number of bytes remaining to be sent/received on success 1538 * return number of bytes remaining to be sent/received on success
1527 * return 0 on failure 1539 * return 0 on failure
1528 */ 1540 */
1529uint64_t file_dataremaining(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive) 1541uint64_t file_dataremaining(const Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive)
1530{ 1542{
1531 if (friend_not_valid(m, friendnumber)) 1543 if (friend_not_valid(m, friendnumber))
1532 return 0; 1544 return 0;
@@ -1549,7 +1561,7 @@ uint64_t file_dataremaining(Messenger *m, int32_t friendnumber, uint8_t filenumb
1549/* Run this when the friend disconnects. 1561/* Run this when the friend disconnects.
1550 * Sets all current file transfers to broken. 1562 * Sets all current file transfers to broken.
1551 */ 1563 */
1552static void break_files(Messenger *m, int32_t friendnumber) 1564static void break_files(const Messenger *m, int32_t friendnumber)
1553{ 1565{
1554 uint32_t i; 1566 uint32_t i;
1555 1567
@@ -1562,7 +1574,7 @@ static void break_files(Messenger *m, int32_t friendnumber)
1562 } 1574 }
1563} 1575}
1564 1576
1565static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, 1577static int handle_filecontrol(const Messenger *m, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber,
1566 uint8_t message_id, uint8_t *data, 1578 uint8_t message_id, uint8_t *data,
1567 uint16_t length) 1579 uint16_t length)
1568{ 1580{
@@ -1652,7 +1664,7 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv
1652 * 1664 *
1653 * Function(Messenger *m, int friendnumber, uint8_t *data, uint16_t length, void *userdata) 1665 * Function(Messenger *m, int friendnumber, uint8_t *data, uint16_t length, void *userdata)
1654 */ 1666 */
1655void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 1667void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
1656 void *userdata) 1668 void *userdata)
1657{ 1669{
1658 m->msi_packet = function; 1670 m->msi_packet = function;
@@ -1664,12 +1676,12 @@ void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, int32_t,
1664 * return 1 on success 1676 * return 1 on success
1665 * return 0 on failure 1677 * return 0 on failure
1666 */ 1678 */
1667int m_msi_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length) 1679int m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length)
1668{ 1680{
1669 return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length); 1681 return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length);
1670} 1682}
1671 1683
1672static int handle_custom_lossy_packet(void *object, int friend_num, uint8_t *packet, uint16_t length) 1684static int handle_custom_lossy_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length)
1673{ 1685{
1674 Messenger *m = object; 1686 Messenger *m = object;
1675 1687
@@ -1684,7 +1696,7 @@ static int handle_custom_lossy_packet(void *object, int friend_num, uint8_t *pac
1684} 1696}
1685 1697
1686int custom_lossy_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, 1698int custom_lossy_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte,
1687 int (*packet_handler_callback)(void *object, uint8_t *data, uint32_t len), void *object) 1699 int (*packet_handler_callback)(void *object, const uint8_t *data, uint32_t len), void *object)
1688{ 1700{
1689 if (friend_not_valid(m, friendnumber)) 1701 if (friend_not_valid(m, friendnumber))
1690 return -1; 1702 return -1;
@@ -1700,7 +1712,7 @@ int custom_lossy_packet_registerhandler(Messenger *m, int32_t friendnumber, uint
1700 return 0; 1712 return 0;
1701} 1713}
1702 1714
1703int send_custom_lossy_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint32_t length) 1715int send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length)
1704{ 1716{
1705 if (friend_not_valid(m, friendnumber)) 1717 if (friend_not_valid(m, friendnumber))
1706 return -1; 1718 return -1;
@@ -1714,7 +1726,7 @@ int send_custom_lossy_packet(Messenger *m, int32_t friendnumber, uint8_t *data,
1714 return send_lossy_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, data, length); 1726 return send_lossy_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, data, length);
1715} 1727}
1716 1728
1717static int handle_custom_lossless_packet(void *object, int friend_num, uint8_t *packet, uint16_t length) 1729static int handle_custom_lossless_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length)
1718{ 1730{
1719 Messenger *m = object; 1731 Messenger *m = object;
1720 1732
@@ -1735,7 +1747,7 @@ static int handle_custom_lossless_packet(void *object, int friend_num, uint8_t *
1735} 1747}
1736 1748
1737int custom_lossless_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, 1749int custom_lossless_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte,
1738 int (*packet_handler_callback)(void *object, uint8_t *data, uint32_t len), void *object) 1750 int (*packet_handler_callback)(void *object, const uint8_t *data, uint32_t len), void *object)
1739{ 1751{
1740 if (friend_not_valid(m, friendnumber)) 1752 if (friend_not_valid(m, friendnumber))
1741 return -1; 1753 return -1;
@@ -1752,7 +1764,7 @@ int custom_lossless_packet_registerhandler(Messenger *m, int32_t friendnumber, u
1752 return 0; 1764 return 0;
1753} 1765}
1754 1766
1755int send_custom_lossless_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint32_t length) 1767int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length)
1756{ 1768{
1757 if (friend_not_valid(m, friendnumber)) 1769 if (friend_not_valid(m, friendnumber))
1758 return -1; 1770 return -1;
@@ -1769,7 +1781,7 @@ int send_custom_lossless_packet(Messenger *m, int32_t friendnumber, uint8_t *dat
1769/* Function to filter out some friend requests*/ 1781/* Function to filter out some friend requests*/
1770static int friend_already_added(const uint8_t *client_id, void *data) 1782static int friend_already_added(const uint8_t *client_id, void *data)
1771{ 1783{
1772 Messenger *m = data; 1784 const Messenger *m = data;
1773 1785
1774 if (getfriend_id(m, client_id) == -1) 1786 if (getfriend_id(m, client_id) == -1)
1775 return 0; 1787 return 0;
@@ -2026,13 +2038,13 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2026 } 2038 }
2027 2039
2028 case PACKET_ID_MESSAGE: { 2040 case PACKET_ID_MESSAGE: {
2029 uint8_t *message_id = data; 2041 const uint8_t *message_id = data;
2030 uint8_t message_id_length = 4; 2042 uint8_t message_id_length = 4;
2031 2043
2032 if (data_length <= message_id_length) 2044 if (data_length <= message_id_length)
2033 break; 2045 break;
2034 2046
2035 uint8_t *message = data + message_id_length; 2047 const uint8_t *message = data + message_id_length;
2036 uint16_t message_length = data_length - message_id_length; 2048 uint16_t message_length = data_length - message_id_length;
2037 2049
2038 /* Make sure the NULL terminator is present. */ 2050 /* Make sure the NULL terminator is present. */
@@ -2051,13 +2063,13 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2051 } 2063 }
2052 2064
2053 case PACKET_ID_ACTION: { 2065 case PACKET_ID_ACTION: {
2054 uint8_t *message_id = data; 2066 const uint8_t *message_id = data;
2055 uint8_t message_id_length = 4; 2067 uint8_t message_id_length = 4;
2056 2068
2057 if (data_length <= message_id_length) 2069 if (data_length <= message_id_length)
2058 break; 2070 break;
2059 2071
2060 uint8_t *action = data + message_id_length; 2072 const uint8_t *action = data + message_id_length;
2061 uint16_t action_length = data_length - message_id_length; 2073 uint16_t action_length = data_length - message_id_length;
2062 2074
2063 /* Make sure the NULL terminator is present. */ 2075 /* Make sure the NULL terminator is present. */
@@ -2125,8 +2137,8 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2125 2137
2126 uint8_t filenumber = data[0]; 2138 uint8_t filenumber = data[0];
2127 uint64_t filesize; 2139 uint64_t filesize;
2128 net_to_host(data + 1, sizeof(filesize));
2129 memcpy(&filesize, data + 1, sizeof(filesize)); 2140 memcpy(&filesize, data + 1, sizeof(filesize));
2141 net_to_host((uint8_t *) &filesize, sizeof(filesize));
2130 m->friendlist[i].file_receiving[filenumber].status = FILESTATUS_NOT_ACCEPTED; 2142 m->friendlist[i].file_receiving[filenumber].status = FILESTATUS_NOT_ACCEPTED;
2131 m->friendlist[i].file_receiving[filenumber].size = filesize; 2143 m->friendlist[i].file_receiving[filenumber].size = filesize;
2132 m->friendlist[i].file_receiving[filenumber].transferred = 0; 2144 m->friendlist[i].file_receiving[filenumber].transferred = 0;
@@ -2213,7 +2225,7 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2213 return 0; 2225 return 0;
2214} 2226}
2215 2227
2216static int friend_new_connection(Messenger *m, int32_t friendnumber, uint8_t *real_public_key) 2228static int friend_new_connection(Messenger *m, int32_t friendnumber, const uint8_t *real_public_key)
2217{ 2229{
2218 if (friend_not_valid(m, friendnumber)) 2230 if (friend_not_valid(m, friendnumber))
2219 return -1; 2231 return -1;
@@ -2334,7 +2346,7 @@ void do_friends(Messenger *m)
2334#define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60UL 2346#define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60UL
2335static time_t lastdump = 0; 2347static time_t lastdump = 0;
2336static char IDString[CLIENT_ID_SIZE * 2 + 1]; 2348static char IDString[CLIENT_ID_SIZE * 2 + 1];
2337static char *ID2String(uint8_t *client_id) 2349static char *ID2String(const uint8_t *client_id)
2338{ 2350{
2339 uint32_t i; 2351 uint32_t i;
2340 2352
@@ -2346,8 +2358,9 @@ static char *ID2String(uint8_t *client_id)
2346} 2358}
2347#endif 2359#endif
2348 2360
2349/* Minimum messenger run interval in ms */ 2361/* Minimum messenger run interval in ms
2350#define MIN_RUN_INTERVAL 1000 2362 TODO: A/V */
2363#define MIN_RUN_INTERVAL 50
2351 2364
2352/* Return the time in milliseconds before do_messenger() should be called again 2365/* Return the time in milliseconds before do_messenger() should be called again
2353 * for optimal performance. 2366 * for optimal performance.
@@ -2526,12 +2539,12 @@ struct SAVED_FRIEND {
2526 uint64_t ping_lastrecv; 2539 uint64_t ping_lastrecv;
2527}; 2540};
2528 2541
2529static uint32_t saved_friendslist_size(Messenger *m) 2542static uint32_t saved_friendslist_size(const Messenger *m)
2530{ 2543{
2531 return count_friendlist(m) * sizeof(struct SAVED_FRIEND); 2544 return count_friendlist(m) * sizeof(struct SAVED_FRIEND);
2532} 2545}
2533 2546
2534static uint32_t friends_list_save(Messenger *m, uint8_t *data) 2547static uint32_t friends_list_save(const Messenger *m, uint8_t *data)
2535{ 2548{
2536 uint32_t i; 2549 uint32_t i;
2537 uint32_t num = 0; 2550 uint32_t num = 0;
@@ -2588,6 +2601,10 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length)
2588 2601
2589 if (temp.status >= 3) { 2602 if (temp.status >= 3) {
2590 int fnum = m_addfriend_norequest(m, temp.client_id); 2603 int fnum = m_addfriend_norequest(m, temp.client_id);
2604
2605 if (fnum < 0)
2606 continue;
2607
2591 setfriendname(m, fnum, temp.name, ntohs(temp.name_length)); 2608 setfriendname(m, fnum, temp.name, ntohs(temp.name_length));
2592 set_friend_statusmessage(m, fnum, temp.statusmessage, ntohs(temp.statusmessage_length)); 2609 set_friend_statusmessage(m, fnum, temp.statusmessage, ntohs(temp.statusmessage_length));
2593 set_friend_userstatus(m, fnum, temp.userstatus); 2610 set_friend_userstatus(m, fnum, temp.userstatus);
@@ -2610,7 +2627,7 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length)
2610} 2627}
2611 2628
2612/* return size of the messenger data (for saving) */ 2629/* return size of the messenger data (for saving) */
2613uint32_t messenger_size(Messenger *m) 2630uint32_t messenger_size(const Messenger *m)
2614{ 2631{
2615 uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2; 2632 uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2;
2616 return size32 * 2 // global cookie 2633 return size32 * 2 // global cookie
@@ -2635,7 +2652,7 @@ static uint8_t *z_state_save_subheader(uint8_t *data, uint32_t len, uint16_t typ
2635 2652
2636 2653
2637/* Save the messenger in data of size Messenger_size(). */ 2654/* Save the messenger in data of size Messenger_size(). */
2638void messenger_save(Messenger *m, uint8_t *data) 2655void messenger_save(const Messenger *m, uint8_t *data)
2639{ 2656{
2640 uint32_t len; 2657 uint32_t len;
2641 uint16_t type; 2658 uint16_t type;
@@ -2693,7 +2710,6 @@ void messenger_save(Messenger *m, uint8_t *data)
2693 memset(relays, 0, len); 2710 memset(relays, 0, len);
2694 copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS); 2711 copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS);
2695 memcpy(data, relays, len); 2712 memcpy(data, relays, len);
2696 data += len;
2697} 2713}
2698 2714
2699static int messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) 2715static int messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type)
@@ -2773,7 +2789,7 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3
2773} 2789}
2774 2790
2775/* Load the messenger from data of size length. */ 2791/* Load the messenger from data of size length. */
2776int messenger_load(Messenger *m, uint8_t *data, uint32_t length) 2792int messenger_load(Messenger *m, const uint8_t *data, uint32_t length)
2777{ 2793{
2778 uint32_t data32[2]; 2794 uint32_t data32[2];
2779 uint32_t cookie_len = sizeof(data32); 2795 uint32_t cookie_len = sizeof(data32);
@@ -2793,7 +2809,7 @@ int messenger_load(Messenger *m, uint8_t *data, uint32_t length)
2793/* Return the number of friends in the instance m. 2809/* Return the number of friends in the instance m.
2794 * You should use this to determine how much memory to allocate 2810 * You should use this to determine how much memory to allocate
2795 * for copy_friendlist. */ 2811 * for copy_friendlist. */
2796uint32_t count_friendlist(Messenger *m) 2812uint32_t count_friendlist(const Messenger *m)
2797{ 2813{
2798 uint32_t ret = 0; 2814 uint32_t ret = 0;
2799 uint32_t i; 2815 uint32_t i;
@@ -2808,7 +2824,7 @@ uint32_t count_friendlist(Messenger *m)
2808} 2824}
2809 2825
2810/* Return the number of online friends in the instance m. */ 2826/* Return the number of online friends in the instance m. */
2811uint32_t get_num_online_friends(Messenger *m) 2827uint32_t get_num_online_friends(const Messenger *m)
2812{ 2828{
2813 return m->numonline_friends; 2829 return m->numonline_friends;
2814} 2830}
@@ -2818,7 +2834,7 @@ uint32_t get_num_online_friends(Messenger *m)
2818 * Otherwise, returns the number of elements copied. 2834 * Otherwise, returns the number of elements copied.
2819 * If the array was too small, the contents 2835 * If the array was too small, the contents
2820 * of out_list will be truncated to list_size. */ 2836 * of out_list will be truncated to list_size. */
2821uint32_t copy_friendlist(Messenger *m, int32_t *out_list, uint32_t list_size) 2837uint32_t copy_friendlist(Messenger const *m, int32_t *out_list, uint32_t list_size)
2822{ 2838{
2823 if (!out_list) 2839 if (!out_list)
2824 return 0; 2840 return 0;
@@ -2850,7 +2866,7 @@ uint32_t copy_friendlist(Messenger *m, int32_t *out_list, uint32_t list_size)
2850 * retun 0 if success. 2866 * retun 0 if success.
2851 * return -1 if failure. 2867 * return -1 if failure.
2852 */ 2868 */
2853int get_friendlist(Messenger *m, int32_t **out_list, uint32_t *out_list_length) 2869int get_friendlist(const Messenger *m, int32_t **out_list, uint32_t *out_list_length)
2854{ 2870{
2855 uint32_t i; 2871 uint32_t i;
2856 2872
@@ -2880,7 +2896,7 @@ int get_friendlist(Messenger *m, int32_t **out_list, uint32_t *out_list_length)
2880/* Return the number of chats in the instance m. 2896/* Return the number of chats in the instance m.
2881 * You should use this to determine how much memory to allocate 2897 * You should use this to determine how much memory to allocate
2882 * for copy_chatlist. */ 2898 * for copy_chatlist. */
2883uint32_t count_chatlist(Messenger *m) 2899uint32_t count_chatlist(const Messenger *m)
2884{ 2900{
2885 uint32_t ret = 0; 2901 uint32_t ret = 0;
2886 uint32_t i; 2902 uint32_t i;
@@ -2899,7 +2915,7 @@ uint32_t count_chatlist(Messenger *m)
2899 * Otherwise, returns the number of elements copied. 2915 * Otherwise, returns the number of elements copied.
2900 * If the array was too small, the contents 2916 * If the array was too small, the contents
2901 * of out_list will be truncated to list_size. */ 2917 * of out_list will be truncated to list_size. */
2902uint32_t copy_chatlist(Messenger *m, int *out_list, uint32_t list_size) 2918uint32_t copy_chatlist(const Messenger *m, int *out_list, uint32_t list_size)
2903{ 2919{
2904 if (!out_list) 2920 if (!out_list)
2905 return 0; 2921 return 0;
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index e6ea59c1..ce0e5825 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -172,12 +172,12 @@ typedef struct {
172 uint16_t invited_groups_num; 172 uint16_t invited_groups_num;
173 173
174 struct { 174 struct {
175 int (*function)(void *object, uint8_t *data, uint32_t len); 175 int (*function)(void *object, const uint8_t *data, uint32_t len);
176 void *object; 176 void *object;
177 } lossy_packethandlers[PACKET_ID_LOSSY_RANGE_SIZE]; 177 } lossy_packethandlers[PACKET_ID_LOSSY_RANGE_SIZE];
178 178
179 struct { 179 struct {
180 int (*function)(void *object, uint8_t *data, uint32_t len); 180 int (*function)(void *object, const uint8_t *data, uint32_t len);
181 void *object; 181 void *object;
182 } lossless_packethandlers[PACKET_ID_LOSSLESS_RANGE_SIZE]; 182 } lossless_packethandlers[PACKET_ID_LOSSLESS_RANGE_SIZE];
183} Friend; 183} Friend;
@@ -212,13 +212,13 @@ typedef struct Messenger {
212 212
213 uint64_t last_LANdiscovery; 213 uint64_t last_LANdiscovery;
214 214
215 void (*friend_message)(struct Messenger *m, int32_t, uint8_t *, uint16_t, void *); 215 void (*friend_message)(struct Messenger *m, int32_t, const uint8_t *, uint16_t, void *);
216 void *friend_message_userdata; 216 void *friend_message_userdata;
217 void (*friend_action)(struct Messenger *m, int32_t, uint8_t *, uint16_t, void *); 217 void (*friend_action)(struct Messenger *m, int32_t, const uint8_t *, uint16_t, void *);
218 void *friend_action_userdata; 218 void *friend_action_userdata;
219 void (*friend_namechange)(struct Messenger *m, int32_t, uint8_t *, uint16_t, void *); 219 void (*friend_namechange)(struct Messenger *m, int32_t, const uint8_t *, uint16_t, void *);
220 void *friend_namechange_userdata; 220 void *friend_namechange_userdata;
221 void (*friend_statusmessagechange)(struct Messenger *m, int32_t, uint8_t *, uint16_t, void *); 221 void (*friend_statusmessagechange)(struct Messenger *m, int32_t, const uint8_t *, uint16_t, void *);
222 void *friend_statusmessagechange_userdata; 222 void *friend_statusmessagechange_userdata;
223 void (*friend_userstatuschange)(struct Messenger *m, int32_t, uint8_t, void *); 223 void (*friend_userstatuschange)(struct Messenger *m, int32_t, uint8_t, void *);
224 void *friend_userstatuschange_userdata; 224 void *friend_userstatuschange_userdata;
@@ -233,23 +233,23 @@ typedef struct Messenger {
233 void (*friend_connectionstatuschange_internal)(struct Messenger *m, int32_t, uint8_t, void *); 233 void (*friend_connectionstatuschange_internal)(struct Messenger *m, int32_t, uint8_t, void *);
234 void *friend_connectionstatuschange_internal_userdata; 234 void *friend_connectionstatuschange_internal_userdata;
235 235
236 void (*group_invite)(struct Messenger *m, int32_t, uint8_t *, void *); 236 void (*group_invite)(struct Messenger *m, int32_t, const uint8_t *, void *);
237 void *group_invite_userdata; 237 void *group_invite_userdata;
238 void (*group_message)(struct Messenger *m, int, int, uint8_t *, uint16_t, void *); 238 void (*group_message)(struct Messenger *m, int, int, const uint8_t *, uint16_t, void *);
239 void *group_message_userdata; 239 void *group_message_userdata;
240 void (*group_action)(struct Messenger *m, int, int, uint8_t *, uint16_t, void *); 240 void (*group_action)(struct Messenger *m, int, int, const uint8_t *, uint16_t, void *);
241 void *group_action_userdata; 241 void *group_action_userdata;
242 void (*group_namelistchange)(struct Messenger *m, int, int, uint8_t, void *); 242 void (*group_namelistchange)(struct Messenger *m, int, int, uint8_t, void *);
243 void *group_namelistchange_userdata; 243 void *group_namelistchange_userdata;
244 244
245 void (*file_sendrequest)(struct Messenger *m, int32_t, uint8_t, uint64_t, uint8_t *, uint16_t, void *); 245 void (*file_sendrequest)(struct Messenger *m, int32_t, uint8_t, uint64_t, const uint8_t *, uint16_t, void *);
246 void *file_sendrequest_userdata; 246 void *file_sendrequest_userdata;
247 void (*file_filecontrol)(struct Messenger *m, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, uint16_t, void *); 247 void (*file_filecontrol)(struct Messenger *m, int32_t, uint8_t, uint8_t, uint8_t, const uint8_t *, uint16_t, void *);
248 void *file_filecontrol_userdata; 248 void *file_filecontrol_userdata;
249 void (*file_filedata)(struct Messenger *m, int32_t, uint8_t, uint8_t *, uint16_t length, void *); 249 void (*file_filedata)(struct Messenger *m, int32_t, uint8_t, const uint8_t *, uint16_t length, void *);
250 void *file_filedata_userdata; 250 void *file_filedata_userdata;
251 251
252 void (*msi_packet)(struct Messenger *m, int32_t, uint8_t *, uint16_t, void *); 252 void (*msi_packet)(struct Messenger *m, int32_t, const uint8_t *, uint16_t, void *);
253 void *msi_packet_userdata; 253 void *msi_packet_userdata;
254 254
255} Messenger; 255} Messenger;
@@ -258,7 +258,7 @@ typedef struct Messenger {
258 * 258 *
259 * return FRIEND_ADDRESS_SIZE byte address to give to others. 259 * return FRIEND_ADDRESS_SIZE byte address to give to others.
260 */ 260 */
261void getaddress(Messenger *m, uint8_t *address); 261void getaddress(const Messenger *m, uint8_t *address);
262 262
263/* Add a friend. 263/* Add a friend.
264 * Set the data that will be sent along with friend request. 264 * Set the data that will be sent along with friend request.
@@ -276,7 +276,7 @@ void getaddress(Messenger *m, uint8_t *address);
276 * (the nospam for that friend was set to the new one). 276 * (the nospam for that friend was set to the new one).
277 * return -8 if increasing the friend list size fails. 277 * return -8 if increasing the friend list size fails.
278 */ 278 */
279int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length); 279int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, uint16_t length);
280 280
281 281
282/* Add a friend without sending a friendrequest. 282/* Add a friend without sending a friendrequest.
@@ -296,7 +296,7 @@ int32_t getfriend_id(const Messenger *m, const uint8_t *client_id);
296 * return 0 if success 296 * return 0 if success
297 * return -1 if failure 297 * return -1 if failure
298 */ 298 */
299int getclient_id(Messenger *m, int32_t friendnumber, uint8_t *client_id); 299int getclient_id(const Messenger *m, int32_t friendnumber, uint8_t *client_id);
300 300
301/* Remove a friend. 301/* Remove a friend.
302 * 302 *
@@ -311,14 +311,14 @@ int m_delfriend(Messenger *m, int32_t friendnumber);
311 * return 0 if friend is not connected to us (Offline). 311 * return 0 if friend is not connected to us (Offline).
312 * return -1 on failure. 312 * return -1 on failure.
313 */ 313 */
314int m_get_friend_connectionstatus(Messenger *m, int32_t friendnumber); 314int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber);
315 315
316/* Checks if there exists a friend with given friendnumber. 316/* Checks if there exists a friend with given friendnumber.
317 * 317 *
318 * return 1 if friend exists. 318 * return 1 if friend exists.
319 * return 0 if friend doesn't exist. 319 * return 0 if friend doesn't exist.
320 */ 320 */
321int m_friend_exists(Messenger *m, int32_t friendnumber); 321int m_friend_exists(const Messenger *m, int32_t friendnumber);
322 322
323/* Send a text chat message to an online friend. 323/* Send a text chat message to an online friend.
324 * 324 *
@@ -344,8 +344,9 @@ uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid
344 * m_sendaction_withid will send an action message with the id of your choosing, 344 * m_sendaction_withid will send an action message with the id of your choosing,
345 * however we can generate an id for you by calling plain m_sendaction. 345 * however we can generate an id for you by calling plain m_sendaction.
346 */ 346 */
347uint32_t m_sendaction(Messenger *m, int32_t friendnumber, uint8_t *action, uint32_t length); 347uint32_t m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length);
348uint32_t m_sendaction_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length); 348uint32_t m_sendaction_withid(const Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *action,
349 uint32_t length);
349 350
350/* Set the name and name_length of a friend. 351/* Set the name and name_length of a friend.
351 * name must be a string of maximum MAX_NAME_LENGTH length. 352 * name must be a string of maximum MAX_NAME_LENGTH length.
@@ -355,7 +356,7 @@ uint32_t m_sendaction_withid(Messenger *m, int32_t friendnumber, uint32_t theid,
355 * return 0 if success. 356 * return 0 if success.
356 * return -1 if failure. 357 * return -1 if failure.
357 */ 358 */
358int setfriendname(Messenger *m, int32_t friendnumber, uint8_t *name, uint16_t length); 359int setfriendname(Messenger *m, int32_t friendnumber, const uint8_t *name, uint16_t length);
359 360
360/* Set our nickname. 361/* Set our nickname.
361 * name must be a string of maximum MAX_NAME_LENGTH length. 362 * name must be a string of maximum MAX_NAME_LENGTH length.
@@ -375,7 +376,7 @@ int setname(Messenger *m, const uint8_t *name, uint16_t length);
375 * return length of the name. 376 * return length of the name.
376 * return 0 on error. 377 * return 0 on error.
377 */ 378 */
378uint16_t getself_name(Messenger *m, uint8_t *name); 379uint16_t getself_name(const Messenger *m, uint8_t *name);
379 380
380/* Get name of friendnumber and put it in name. 381/* Get name of friendnumber and put it in name.
381 * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. 382 * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
@@ -383,13 +384,13 @@ uint16_t getself_name(Messenger *m, uint8_t *name);
383 * return length of name if success. 384 * return length of name if success.
384 * return -1 if failure. 385 * return -1 if failure.
385 */ 386 */
386int getname(Messenger *m, int32_t friendnumber, uint8_t *name); 387int getname(const Messenger *m, int32_t friendnumber, uint8_t *name);
387 388
388/* return the length of name, including null on success. 389/* return the length of name, including null on success.
389 * return -1 on failure. 390 * return -1 on failure.
390 */ 391 */
391int m_get_name_size(Messenger *m, int32_t friendnumber); 392int m_get_name_size(const Messenger *m, int32_t friendnumber);
392int m_get_self_name_size(Messenger *m); 393int m_get_self_name_size(const Messenger *m);
393 394
394/* Set our user status. 395/* Set our user status.
395 * You are responsible for freeing status after. 396 * You are responsible for freeing status after.
@@ -403,8 +404,8 @@ int m_set_userstatus(Messenger *m, uint8_t status);
403/* return the length of friendnumber's status message, including null on success. 404/* return the length of friendnumber's status message, including null on success.
404 * return -1 on failure. 405 * return -1 on failure.
405 */ 406 */
406int m_get_statusmessage_size(Messenger *m, int32_t friendnumber); 407int m_get_statusmessage_size(const Messenger *m, int32_t friendnumber);
407int m_get_self_statusmessage_size(Messenger *m); 408int m_get_self_statusmessage_size(const Messenger *m);
408 409
409/* Copy friendnumber's status message into buf, truncating if size is over maxlen. 410/* Copy friendnumber's status message into buf, truncating if size is over maxlen.
410 * Get the size you need to allocate from m_get_statusmessage_size. 411 * Get the size you need to allocate from m_get_statusmessage_size.
@@ -413,21 +414,21 @@ int m_get_self_statusmessage_size(Messenger *m);
413 * returns the length of the copied data on success 414 * returns the length of the copied data on success
414 * retruns -1 on failure. 415 * retruns -1 on failure.
415 */ 416 */
416int m_copy_statusmessage(Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen); 417int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen);
417int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen); 418int m_copy_self_statusmessage(const Messenger *m, uint8_t *buf, uint32_t maxlen);
418 419
419/* return one of USERSTATUS values. 420/* return one of USERSTATUS values.
420 * Values unknown to your application should be represented as USERSTATUS_NONE. 421 * Values unknown to your application should be represented as USERSTATUS_NONE.
421 * As above, the self variant will return our own USERSTATUS. 422 * As above, the self variant will return our own USERSTATUS.
422 * If friendnumber is invalid, this shall return USERSTATUS_INVALID. 423 * If friendnumber is invalid, this shall return USERSTATUS_INVALID.
423 */ 424 */
424uint8_t m_get_userstatus(Messenger *m, int32_t friendnumber); 425uint8_t m_get_userstatus(const Messenger *m, int32_t friendnumber);
425uint8_t m_get_self_userstatus(Messenger *m); 426uint8_t m_get_self_userstatus(const Messenger *m);
426 427
427/* returns timestamp of last time friendnumber was seen online, or 0 if never seen. 428/* returns timestamp of last time friendnumber was seen online, or 0 if never seen.
428 * returns -1 on error. 429 * returns -1 on error.
429 */ 430 */
430uint64_t m_get_last_online(Messenger *m, int32_t friendnumber); 431uint64_t m_get_last_online(const Messenger *m, int32_t friendnumber);
431 432
432/* Set our typing status for a friend. 433/* Set our typing status for a friend.
433 * You are responsible for turning it on or off. 434 * You are responsible for turning it on or off.
@@ -442,7 +443,7 @@ int m_set_usertyping(Messenger *m, int32_t friendnumber, uint8_t is_typing);
442 * returns 0 if friend is not typing. 443 * returns 0 if friend is not typing.
443 * returns 1 if friend is typing. 444 * returns 1 if friend is typing.
444 */ 445 */
445uint8_t m_get_istyping(Messenger *m, int32_t friendnumber); 446uint8_t m_get_istyping(const Messenger *m, int32_t friendnumber);
446 447
447/* Sets whether we send read receipts for friendnumber. 448/* Sets whether we send read receipts for friendnumber.
448 * This function is not lazy, and it will fail if yesno is not (0 or 1). 449 * This function is not lazy, and it will fail if yesno is not (0 or 1).
@@ -458,20 +459,20 @@ void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const
458/* Set the function that will be executed when a message from a friend is received. 459/* Set the function that will be executed when a message from a friend is received.
459 * Function format is: function(int32_t friendnumber, uint8_t * message, uint32_t length) 460 * Function format is: function(int32_t friendnumber, uint8_t * message, uint32_t length)
460 */ 461 */
461void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 462void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
462 void *userdata); 463 void *userdata);
463 464
464/* Set the function that will be executed when an action from a friend is received. 465/* Set the function that will be executed when an action from a friend is received.
465 * Function format is: function(int32_t friendnumber, uint8_t * action, uint32_t length) 466 * Function format is: function(int32_t friendnumber, uint8_t * action, uint32_t length)
466 */ 467 */
467void m_callback_action(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 468void m_callback_action(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
468 void *userdata); 469 void *userdata);
469 470
470/* Set the callback for name changes. 471/* Set the callback for name changes.
471 * Function(int32_t friendnumber, uint8_t *newname, uint16_t length) 472 * Function(int32_t friendnumber, uint8_t *newname, uint16_t length)
472 * You are not responsible for freeing newname. 473 * You are not responsible for freeing newname.
473 */ 474 */
474void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 475void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
475 void *userdata); 476 void *userdata);
476 477
477/* Set the callback for status message changes. 478/* Set the callback for status message changes.
@@ -479,7 +480,7 @@ void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int32_t,
479 * 480 *
480 * You are not responsible for freeing newstatus 481 * You are not responsible for freeing newstatus
481 */ 482 */
482void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 483void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
483 void *userdata); 484 void *userdata);
484 485
485/* Set the callback for status type changes. 486/* Set the callback for status type changes.
@@ -526,20 +527,21 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess
526 * 527 *
527 * Function(Messenger *m, int32_t friendnumber, uint8_t *group_public_key, void *userdata) 528 * Function(Messenger *m, int32_t friendnumber, uint8_t *group_public_key, void *userdata)
528 */ 529 */
529void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, void *), void *userdata); 530void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, void *),
531 void *userdata);
530 532
531/* Set the callback for group messages. 533/* Set the callback for group messages.
532 * 534 *
533 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) 535 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
534 */ 536 */
535void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t *, uint16_t, void *), 537void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *),
536 void *userdata); 538 void *userdata);
537 539
538/* Set the callback for group actions. 540/* Set the callback for group actions.
539 * 541 *
540 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) 542 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
541 */ 543 */
542void m_callback_group_action(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t *, uint16_t, void *), 544void m_callback_group_action(Messenger *m, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *),
543 void *userdata); 545 void *userdata);
544 546
545/* Set callback function for peer name list changes. 547/* Set callback function for peer name list changes.
@@ -570,7 +572,7 @@ int del_groupchat(Messenger *m, int groupnumber);
570 * return length of name if success 572 * return length of name if success
571 * return -1 if failure 573 * return -1 if failure
572 */ 574 */
573int m_group_peername(Messenger *m, int groupnumber, int peernumber, uint8_t *name); 575int m_group_peername(const Messenger *m, int groupnumber, int peernumber, uint8_t *name);
574 576
575/* invite friendnumber to groupnumber 577/* invite friendnumber to groupnumber
576 * return 0 on success 578 * return 0 on success
@@ -583,24 +585,24 @@ int invite_friend(Messenger *m, int32_t friendnumber, int groupnumber);
583 * returns group number on success 585 * returns group number on success
584 * returns -1 on failure. 586 * returns -1 on failure.
585 */ 587 */
586int join_groupchat(Messenger *m, int32_t friendnumber, uint8_t *friend_group_public_key); 588int join_groupchat(Messenger *m, int32_t friendnumber, const uint8_t *friend_group_public_key);
587 589
588/* send a group message 590/* send a group message
589 * return 0 on success 591 * return 0 on success
590 * return -1 on failure 592 * return -1 on failure
591 */ 593 */
592int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length); 594int group_message_send(const Messenger *m, int groupnumber, const uint8_t *message, uint32_t length);
593 595
594/* send a group action 596/* send a group action
595 * return 0 on success 597 * return 0 on success
596 * return -1 on failure 598 * return -1 on failure
597 */ 599 */
598int group_action_send(Messenger *m, int groupnumber, uint8_t *action, uint32_t length); 600int group_action_send(const Messenger *m, int groupnumber, const uint8_t *action, uint32_t length);
599 601
600/* Return the number of peers in the group chat on success. 602/* Return the number of peers in the group chat on success.
601 * return -1 on failure 603 * return -1 on failure
602 */ 604 */
603int group_number_peers(Messenger *m, int groupnumber); 605int group_number_peers(const Messenger *m, int groupnumber);
604 606
605/* List all the peers in the group chat. 607/* List all the peers in the group chat.
606 * 608 *
@@ -612,7 +614,8 @@ int group_number_peers(Messenger *m, int groupnumber);
612 * 614 *
613 * return -1 on failure. 615 * return -1 on failure.
614 */ 616 */
615int group_names(Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[], uint16_t length); 617int group_names(const Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[],
618 uint16_t length);
616 619
617/****************FILE SENDING*****************/ 620/****************FILE SENDING*****************/
618 621
@@ -621,7 +624,7 @@ int group_names(Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES],
621 * 624 *
622 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata) 625 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata)
623 */ 626 */
624void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint64_t, uint8_t *, 627void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint64_t, const uint8_t *,
625 uint16_t, void *), void *userdata); 628 uint16_t, void *), void *userdata);
626 629
627/* Set the callback for file control requests. 630/* Set the callback for file control requests.
@@ -629,15 +632,15 @@ void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int3
629 * Function(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata) 632 * Function(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata)
630 * 633 *
631 */ 634 */
632void callback_file_control(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, 635void callback_file_control(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t, uint8_t,
633 uint16_t, void *), void *userdata); 636 const uint8_t *, uint16_t, void *), void *userdata);
634 637
635/* Set the callback for file data. 638/* Set the callback for file data.
636 * 639 *
637 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) 640 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata)
638 * 641 *
639 */ 642 */
640void callback_file_data(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t *, uint16_t length, 643void callback_file_data(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, const uint8_t *, uint16_t length,
641 void *), void *userdata); 644 void *), void *userdata);
642 645
643/* Send a file send request. 646/* Send a file send request.
@@ -645,15 +648,16 @@ void callback_file_data(Messenger *m, void (*function)(Messenger *m, int32_t, ui
645 * return 1 on success 648 * return 1 on success
646 * return 0 on failure 649 * return 0 on failure
647 */ 650 */
648int file_sendrequest(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, 651int file_sendrequest(const Messenger *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize,
649 uint16_t filename_length); 652 const uint8_t *filename, uint16_t filename_length);
650 653
651/* Send a file send request. 654/* Send a file send request.
652 * Maximum filename length is 255 bytes. 655 * Maximum filename length is 255 bytes.
653 * return file number on success 656 * return file number on success
654 * return -1 on failure 657 * return -1 on failure
655 */ 658 */
656int new_filesender(Messenger *m, int32_t friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length); 659int new_filesender(const Messenger *m, int32_t friendnumber, uint64_t filesize, const uint8_t *filename,
660 uint16_t filename_length);
657 661
658/* Send a file control request. 662/* Send a file control request.
659 * send_receive is 0 if we want the control packet to target a sending file, 1 if it targets a receiving file. 663 * send_receive is 0 if we want the control packet to target a sending file, 1 if it targets a receiving file.
@@ -661,15 +665,15 @@ int new_filesender(Messenger *m, int32_t friendnumber, uint64_t filesize, uint8_
661 * return 1 on success 665 * return 1 on success
662 * return 0 on failure 666 * return 0 on failure
663 */ 667 */
664int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, 668int file_control(const Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id,
665 uint8_t *data, uint16_t length); 669 const uint8_t *data, uint16_t length);
666 670
667/* Send file data. 671/* Send file data.
668 * 672 *
669 * return 1 on success 673 * return 1 on success
670 * return 0 on failure 674 * return 0 on failure
671 */ 675 */
672int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length); 676int file_data(const Messenger *m, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length);
673 677
674/* Give the number of bytes left to be sent/received. 678/* Give the number of bytes left to be sent/received.
675 * 679 *
@@ -678,7 +682,7 @@ int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *d
678 * return number of bytes remaining to be sent/received on success 682 * return number of bytes remaining to be sent/received on success
679 * return 0 on failure 683 * return 0 on failure
680 */ 684 */
681uint64_t file_dataremaining(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive); 685uint64_t file_dataremaining(const Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive);
682 686
683/*************** A/V related ******************/ 687/*************** A/V related ******************/
684 688
@@ -686,7 +690,7 @@ uint64_t file_dataremaining(Messenger *m, int32_t friendnumber, uint8_t filenumb
686 * 690 *
687 * Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) 691 * Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, void *userdata)
688 */ 692 */
689void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), 693void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *),
690 void *userdata); 694 void *userdata);
691 695
692/* Send an msi packet. 696/* Send an msi packet.
@@ -694,7 +698,7 @@ void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, int32_t,
694 * return 1 on success 698 * return 1 on success
695 * return 0 on failure 699 * return 0 on failure
696 */ 700 */
697int m_msi_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length); 701int m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length);
698 702
699/**********************************************/ 703/**********************************************/
700 704
@@ -704,14 +708,14 @@ int m_msi_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t len
704 * return 0 on success. 708 * return 0 on success.
705 */ 709 */
706int custom_lossy_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, 710int custom_lossy_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte,
707 int (*packet_handler_callback)(void *object, uint8_t *data, uint32_t len), void *object); 711 int (*packet_handler_callback)(void *object, const uint8_t *data, uint32_t len), void *object);
708 712
709/* High level function to send custom lossy packets. 713/* High level function to send custom lossy packets.
710 * 714 *
711 * return -1 on failure. 715 * return -1 on failure.
712 * return 0 on success. 716 * return 0 on success.
713 */ 717 */
714int send_custom_lossy_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint32_t length); 718int send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length);
715 719
716 720
717/* Set handlers for custom lossless packets. 721/* Set handlers for custom lossless packets.
@@ -722,14 +726,14 @@ int send_custom_lossy_packet(Messenger *m, int32_t friendnumber, uint8_t *data,
722 * return 0 on success. 726 * return 0 on success.
723 */ 727 */
724int custom_lossless_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, 728int custom_lossless_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte,
725 int (*packet_handler_callback)(void *object, uint8_t *data, uint32_t len), void *object); 729 int (*packet_handler_callback)(void *object, const uint8_t *data, uint32_t len), void *object);
726 730
727/* High level function to send custom lossless packets. 731/* High level function to send custom lossless packets.
728 * 732 *
729 * return -1 on failure. 733 * return -1 on failure.
730 * return 0 on success. 734 * return 0 on success.
731 */ 735 */
732int send_custom_lossless_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint32_t length); 736int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length);
733 737
734/**********************************************/ 738/**********************************************/
735/* Run this at startup. 739/* Run this at startup.
@@ -756,28 +760,28 @@ uint32_t messenger_run_interval(Messenger *m);
756/* SAVING AND LOADING FUNCTIONS: */ 760/* SAVING AND LOADING FUNCTIONS: */
757 761
758/* return size of the messenger data (for saving). */ 762/* return size of the messenger data (for saving). */
759uint32_t messenger_size(Messenger *m); 763uint32_t messenger_size(const Messenger *m);
760 764
761/* Save the messenger in data (must be allocated memory of size Messenger_size()) */ 765/* Save the messenger in data (must be allocated memory of size Messenger_size()) */
762void messenger_save(Messenger *m, uint8_t *data); 766void messenger_save(const Messenger *m, uint8_t *data);
763 767
764/* Load the messenger from data of size length. */ 768/* Load the messenger from data of size length. */
765int messenger_load(Messenger *m, uint8_t *data, uint32_t length); 769int messenger_load(Messenger *m, const uint8_t *data, uint32_t length);
766 770
767/* Return the number of friends in the instance m. 771/* Return the number of friends in the instance m.
768 * You should use this to determine how much memory to allocate 772 * You should use this to determine how much memory to allocate
769 * for copy_friendlist. */ 773 * for copy_friendlist. */
770uint32_t count_friendlist(Messenger *m); 774uint32_t count_friendlist(const Messenger *m);
771 775
772/* Return the number of online friends in the instance m. */ 776/* Return the number of online friends in the instance m. */
773uint32_t get_num_online_friends(Messenger *m); 777uint32_t get_num_online_friends(const Messenger *m);
774 778
775/* Copy a list of valid friend IDs into the array out_list. 779/* Copy a list of valid friend IDs into the array out_list.
776 * If out_list is NULL, returns 0. 780 * If out_list is NULL, returns 0.
777 * Otherwise, returns the number of elements copied. 781 * Otherwise, returns the number of elements copied.
778 * If the array was too small, the contents 782 * If the array was too small, the contents
779 * of out_list will be truncated to list_size. */ 783 * of out_list will be truncated to list_size. */
780uint32_t copy_friendlist(Messenger *m, int32_t *out_list, uint32_t list_size); 784uint32_t copy_friendlist(const Messenger *m, int32_t *out_list, uint32_t list_size);
781 785
782/* Allocate and return a list of valid friend id's. List must be freed by the 786/* Allocate and return a list of valid friend id's. List must be freed by the
783 * caller. 787 * caller.
@@ -785,18 +789,18 @@ uint32_t copy_friendlist(Messenger *m, int32_t *out_list, uint32_t list_size);
785 * retun 0 if success. 789 * retun 0 if success.
786 * return -1 if failure. 790 * return -1 if failure.
787 */ 791 */
788int get_friendlist(Messenger *m, int **out_list, uint32_t *out_list_length); 792int get_friendlist(const Messenger *m, int **out_list, uint32_t *out_list_length);
789 793
790/* Return the number of chats in the instance m. 794/* Return the number of chats in the instance m.
791 * You should use this to determine how much memory to allocate 795 * You should use this to determine how much memory to allocate
792 * for copy_chatlist. */ 796 * for copy_chatlist. */
793uint32_t count_chatlist(Messenger *m); 797uint32_t count_chatlist(const Messenger *m);
794 798
795/* Copy a list of valid chat IDs into the array out_list. 799/* Copy a list of valid chat IDs into the array out_list.
796 * If out_list is NULL, returns 0. 800 * If out_list is NULL, returns 0.
797 * Otherwise, returns the number of elements copied. 801 * Otherwise, returns the number of elements copied.
798 * If the array was too small, the contents 802 * If the array was too small, the contents
799 * of out_list will be truncated to list_size. */ 803 * of out_list will be truncated to list_size. */
800uint32_t copy_chatlist(Messenger *m, int *out_list, uint32_t list_size); 804uint32_t copy_chatlist(const Messenger *m, int *out_list, uint32_t list_size);
801 805
802#endif 806#endif
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index e4845852..82720ae8 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -65,7 +65,8 @@ static int connect_sock_to(sock_t sock, IP_Port ip_port)
65/* return 0 on success. 65/* return 0 on success.
66 * return -1 on failure. 66 * return -1 on failure.
67 */ 67 */
68static int generate_handshake(TCP_Client_Connection *TCP_conn, uint8_t *self_public_key, uint8_t *self_secret_key) 68static int generate_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *self_public_key,
69 const uint8_t *self_secret_key)
69{ 70{
70 uint8_t plain[crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES]; 71 uint8_t plain[crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES];
71 crypto_box_keypair(plain, TCP_conn->temp_secret_key); 72 crypto_box_keypair(plain, TCP_conn->temp_secret_key);
@@ -90,7 +91,7 @@ static int generate_handshake(TCP_Client_Connection *TCP_conn, uint8_t *self_pub
90 * return 0 on success. 91 * return 0 on success.
91 * return -1 on failure. 92 * return -1 on failure.
92 */ 93 */
93static int handle_handshake(TCP_Client_Connection *TCP_conn, uint8_t *data) 94static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data)
94{ 95{
95 uint8_t plain[crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES]; 96 uint8_t plain[crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES];
96 int len = decrypt_data_symmetric(TCP_conn->shared_key, data, data + crypto_box_NONCEBYTES, 97 int len = decrypt_data_symmetric(TCP_conn->shared_key, data, data + crypto_box_NONCEBYTES,
@@ -137,7 +138,7 @@ static int send_pending_data(TCP_Client_Connection *con)
137 * return 0 if could not send packet. 138 * return 0 if could not send packet.
138 * return -1 on failure (connection must be killed). 139 * return -1 on failure (connection must be killed).
139 */ 140 */
140static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, uint8_t *data, uint16_t length) 141static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length)
141{ 142{
142 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) 143 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
143 return -1; 144 return -1;
@@ -183,7 +184,7 @@ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key)
183} 184}
184 185
185void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, 186void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id,
186 uint8_t *public_key), void *object) 187 const uint8_t *public_key), void *object)
187{ 188{
188 con->response_callback = response_callback; 189 con->response_callback = response_callback;
189 con->response_callback_object = object; 190 con->response_callback_object = object;
@@ -196,11 +197,13 @@ void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(v
196 con->status_callback_object = object; 197 con->status_callback_object = object;
197} 198}
198 199
200static int send_ping_response(TCP_Client_Connection *con);
201
199/* return 1 on success. 202/* return 1 on success.
200 * return 0 if could not send packet. 203 * return 0 if could not send packet.
201 * return -1 on failure. 204 * return -1 on failure.
202 */ 205 */
203int send_data(TCP_Client_Connection *con, uint8_t con_id, uint8_t *data, uint16_t length) 206int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length)
204{ 207{
205 if (con_id >= NUM_CLIENT_CONNECTIONS) 208 if (con_id >= NUM_CLIENT_CONNECTIONS)
206 return -1; 209 return -1;
@@ -208,6 +211,9 @@ int send_data(TCP_Client_Connection *con, uint8_t con_id, uint8_t *data, uint16_
208 if (con->connections[con_id].status != 2) 211 if (con->connections[con_id].status != 2)
209 return -1; 212 return -1;
210 213
214 if (send_ping_response(con) == 0)
215 return 0;
216
211 uint8_t packet[1 + length]; 217 uint8_t packet[1 + length];
212 packet[0] = con_id + NUM_RESERVED_PORTS; 218 packet[0] = con_id + NUM_RESERVED_PORTS;
213 memcpy(packet + 1, data, length); 219 memcpy(packet + 1, data, length);
@@ -218,7 +224,7 @@ int send_data(TCP_Client_Connection *con, uint8_t con_id, uint8_t *data, uint16_
218 * return 0 if could not send packet. 224 * return 0 if could not send packet.
219 * return -1 on failure. 225 * return -1 on failure.
220 */ 226 */
221int send_oob_packet(TCP_Client_Connection *con, uint8_t *public_key, uint8_t *data, uint16_t length) 227int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length)
222{ 228{
223 if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) 229 if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH)
224 return -1; 230 return -1;
@@ -251,14 +257,14 @@ int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32
251} 257}
252 258
253void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, 259void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number,
254 uint8_t connection_id, uint8_t *data, uint16_t length), void *object) 260 uint8_t connection_id, const uint8_t *data, uint16_t length), void *object)
255{ 261{
256 con->data_callback = data_callback; 262 con->data_callback = data_callback;
257 con->data_callback_object = object; 263 con->data_callback_object = object;
258} 264}
259 265
260void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, uint8_t *public_key, 266void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, const uint8_t *public_key,
261 uint8_t *data, uint16_t length), void *object) 267 const uint8_t *data, uint16_t length), void *object)
262{ 268{
263 con->oob_data_callback = oob_data_callback; 269 con->oob_data_callback = oob_data_callback;
264 con->oob_data_callback_object = object; 270 con->oob_data_callback_object = object;
@@ -292,12 +298,21 @@ static int send_ping_request(TCP_Client_Connection *con, uint64_t ping_id)
292 * return 0 if could not send packet. 298 * return 0 if could not send packet.
293 * return -1 on failure (connection must be killed). 299 * return -1 on failure (connection must be killed).
294 */ 300 */
295static int send_ping_response(TCP_Client_Connection *con, uint64_t ping_id) 301static int send_ping_response(TCP_Client_Connection *con)
296{ 302{
303 if (!con->ping_response_id)
304 return 1;
305
297 uint8_t packet[1 + sizeof(uint64_t)]; 306 uint8_t packet[1 + sizeof(uint64_t)];
298 packet[0] = TCP_PACKET_PONG; 307 packet[0] = TCP_PACKET_PONG;
299 memcpy(packet + 1, &ping_id, sizeof(uint64_t)); 308 memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t));
300 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 309 int ret;
310
311 if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet))) == 1) {
312 con->ping_response_id = 0;
313 }
314
315 return ret;
301} 316}
302 317
303/* return 1 on success. 318/* return 1 on success.
@@ -318,7 +333,7 @@ int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id)
318 * return 0 if could not send packet. 333 * return 0 if could not send packet.
319 * return -1 on failure (connection must be killed). 334 * return -1 on failure (connection must be killed).
320 */ 335 */
321int send_onion_request(TCP_Client_Connection *con, uint8_t *data, uint16_t length) 336int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length)
322{ 337{
323 uint8_t packet[1 + length]; 338 uint8_t packet[1 + length];
324 packet[0] = TCP_PACKET_ONION_REQUEST; 339 packet[0] = TCP_PACKET_ONION_REQUEST;
@@ -326,7 +341,7 @@ int send_onion_request(TCP_Client_Connection *con, uint8_t *data, uint16_t lengt
326 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 341 return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
327} 342}
328 343
329void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, uint8_t *data, 344void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data,
330 uint16_t length), void *object) 345 uint16_t length), void *object)
331{ 346{
332 con->onion_callback = onion_callback; 347 con->onion_callback = onion_callback;
@@ -335,8 +350,8 @@ void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(vo
335 350
336/* Create new TCP connection to ip_port/public_key 351/* Create new TCP connection to ip_port/public_key
337 */ 352 */
338TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key, uint8_t *self_public_key, 353TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public_key, const uint8_t *self_public_key,
339 uint8_t *self_secret_key) 354 const uint8_t *self_secret_key)
340{ 355{
341 if (networking_at_startup() != 0) { 356 if (networking_at_startup() != 0) {
342 return NULL; 357 return NULL;
@@ -388,7 +403,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key,
388/* return 0 on success 403/* return 0 on success
389 * return -1 on failure 404 * return -1 on failure
390 */ 405 */
391static int handle_TCP_packet(TCP_Client_Connection *conn, uint8_t *data, uint16_t length) 406static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
392{ 407{
393 if (length <= 1) 408 if (length <= 1)
394 return -1; 409 return -1;
@@ -467,7 +482,8 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, uint8_t *data, uint16_
467 482
468 uint64_t ping_id; 483 uint64_t ping_id;
469 memcpy(&ping_id, data + 1, sizeof(uint64_t)); 484 memcpy(&ping_id, data + 1, sizeof(uint64_t));
470 send_ping_response(conn, ping_id); 485 conn->ping_response_id = ping_id;
486 send_ping_response(conn);
471 return 0; 487 return 0;
472 } 488 }
473 489
@@ -522,6 +538,7 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, uint8_t *data, uint16_
522static int do_confirmed_TCP(TCP_Client_Connection *conn) 538static int do_confirmed_TCP(TCP_Client_Connection *conn)
523{ 539{
524 send_pending_data(conn); 540 send_pending_data(conn);
541 send_ping_response(conn);
525 uint8_t packet[MAX_PACKET_SIZE]; 542 uint8_t packet[MAX_PACKET_SIZE];
526 int len; 543 int len;
527 544
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h
index afb95392..e6d232ed 100644
--- a/toxcore/TCP_client.h
+++ b/toxcore/TCP_client.h
@@ -57,6 +57,7 @@ typedef struct {
57 uint64_t last_pinged; 57 uint64_t last_pinged;
58 uint64_t ping_id; 58 uint64_t ping_id;
59 59
60 uint64_t ping_response_id;
60 void *net_crypto_pointer; 61 void *net_crypto_pointer;
61 uint32_t net_crypto_location; 62 uint32_t net_crypto_location;
62 struct { 63 struct {
@@ -64,23 +65,23 @@ typedef struct {
64 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 65 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
65 uint32_t number; 66 uint32_t number;
66 } connections[NUM_CLIENT_CONNECTIONS]; 67 } connections[NUM_CLIENT_CONNECTIONS];
67 int (*response_callback)(void *object, uint8_t connection_id, uint8_t *public_key); 68 int (*response_callback)(void *object, uint8_t connection_id, const uint8_t *public_key);
68 void *response_callback_object; 69 void *response_callback_object;
69 int (*status_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t status); 70 int (*status_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t status);
70 void *status_callback_object; 71 void *status_callback_object;
71 int (*data_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length); 72 int (*data_callback)(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length);
72 void *data_callback_object; 73 void *data_callback_object;
73 int (*oob_data_callback)(void *object, uint8_t *public_key, uint8_t *data, uint16_t length); 74 int (*oob_data_callback)(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length);
74 void *oob_data_callback_object; 75 void *oob_data_callback_object;
75 76
76 int (*onion_callback)(void *object, uint8_t *data, uint16_t length); 77 int (*onion_callback)(void *object, const uint8_t *data, uint16_t length);
77 void *onion_callback_object; 78 void *onion_callback_object;
78} TCP_Client_Connection; 79} TCP_Client_Connection;
79 80
80/* Create new TCP connection to ip_port/public_key 81/* Create new TCP connection to ip_port/public_key
81 */ 82 */
82TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key, uint8_t *self_public_key, 83TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public_key, const uint8_t *self_public_key,
83 uint8_t *self_secret_key); 84 const uint8_t *self_secret_key);
84 85
85/* Run the TCP connection 86/* Run the TCP connection
86 */ 87 */
@@ -94,8 +95,8 @@ void kill_TCP_connection(TCP_Client_Connection *TCP_connection);
94 * return 0 if could not send packet. 95 * return 0 if could not send packet.
95 * return -1 on failure (connection must be killed). 96 * return -1 on failure (connection must be killed).
96 */ 97 */
97int send_onion_request(TCP_Client_Connection *con, uint8_t *data, uint16_t length); 98int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length);
98void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, uint8_t *data, 99void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data,
99 uint16_t length), void *object); 100 uint16_t length), void *object);
100 101
101/* return 1 on success. 102/* return 1 on success.
@@ -104,7 +105,7 @@ void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(vo
104 */ 105 */
105int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key); 106int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key);
106void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, 107void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id,
107 uint8_t *public_key), void *object); 108 const uint8_t *public_key), void *object);
108void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number, 109void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number,
109 uint8_t connection_id, uint8_t status), void *object); 110 uint8_t connection_id, uint8_t status), void *object);
110 111
@@ -127,17 +128,17 @@ int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32
127 * return 0 if could not send packet. 128 * return 0 if could not send packet.
128 * return -1 on failure. 129 * return -1 on failure.
129 */ 130 */
130int send_data(TCP_Client_Connection *con, uint8_t con_id, uint8_t *data, uint16_t length); 131int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length);
131void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, 132void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number,
132 uint8_t connection_id, uint8_t *data, uint16_t length), void *object); 133 uint8_t connection_id, const uint8_t *data, uint16_t length), void *object);
133 134
134/* return 1 on success. 135/* return 1 on success.
135 * return 0 if could not send packet. 136 * return 0 if could not send packet.
136 * return -1 on failure. 137 * return -1 on failure.
137 */ 138 */
138int send_oob_packet(TCP_Client_Connection *con, uint8_t *public_key, uint8_t *data, uint16_t length); 139int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length);
139void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, uint8_t *public_key, 140void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, const uint8_t *public_key,
140 uint8_t *data, uint16_t length), void *object); 141 const uint8_t *data, uint16_t length), void *object);
141 142
142 143
143#endif 144#endif
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c
index b900db6b..7487ad4f 100644
--- a/toxcore/TCP_server.c
+++ b/toxcore/TCP_server.c
@@ -97,7 +97,7 @@ static int realloc_connection(TCP_Server *TCP_server, uint32_t num)
97/* return index corresponding to connection with peer on success 97/* return index corresponding to connection with peer on success
98 * return -1 on failure. 98 * return -1 on failure.
99 */ 99 */
100static int get_TCP_connection_index(TCP_Server *TCP_server, uint8_t *public_key) 100static int get_TCP_connection_index(const TCP_Server *TCP_server, const uint8_t *public_key)
101{ 101{
102 return bs_list_find(&TCP_server->accepted_key_list, public_key); 102 return bs_list_find(&TCP_server->accepted_key_list, public_key);
103} 103}
@@ -110,7 +110,7 @@ static int kill_accepted(TCP_Server *TCP_server, int index);
110 * return index on success 110 * return index on success
111 * return -1 on failure 111 * return -1 on failure
112 */ 112 */
113static int add_accepted(TCP_Server *TCP_server, TCP_Secure_Connection *con) 113static int add_accepted(TCP_Server *TCP_server, const TCP_Secure_Connection *con)
114{ 114{
115 int index = get_TCP_connection_index(TCP_server, con->public_key); 115 int index = get_TCP_connection_index(TCP_server, con->public_key);
116 116
@@ -249,7 +249,7 @@ int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length)
249 * return 0 if could not read any packet. 249 * return 0 if could not read any packet.
250 * return -1 on failure (connection must be killed). 250 * return -1 on failure (connection must be killed).
251 */ 251 */
252int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, uint8_t *shared_key, 252int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, const uint8_t *shared_key,
253 uint8_t *recv_nonce, uint8_t *data, uint16_t max_len) 253 uint8_t *recv_nonce, uint8_t *data, uint16_t max_len)
254{ 254{
255 if (*next_packet_length == 0) { 255 if (*next_packet_length == 0) {
@@ -318,7 +318,7 @@ static int send_pending_data(TCP_Secure_Connection *con)
318 * return 0 if could not send packet. 318 * return 0 if could not send packet.
319 * return -1 on failure (connection must be killed). 319 * return -1 on failure (connection must be killed).
320 */ 320 */
321static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t *data, uint16_t length) 321static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length)
322{ 322{
323 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) 323 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
324 return -1; 324 return -1;
@@ -389,7 +389,8 @@ static int kill_accepted(TCP_Server *TCP_server, int index)
389/* return 1 if everything went well. 389/* return 1 if everything went well.
390 * return -1 if the connection must be killed. 390 * return -1 if the connection must be killed.
391 */ 391 */
392static int handle_TCP_handshake(TCP_Secure_Connection *con, uint8_t *data, uint16_t length, uint8_t *self_secret_key) 392static int handle_TCP_handshake(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
393 const uint8_t *self_secret_key)
393{ 394{
394 if (length != TCP_CLIENT_HANDSHAKE_SIZE) 395 if (length != TCP_CLIENT_HANDSHAKE_SIZE)
395 return -1; 396 return -1;
@@ -435,7 +436,7 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, uint8_t *data, uint1
435 * return 0 if we didn't get it yet. 436 * return 0 if we didn't get it yet.
436 * return -1 if the connection must be killed. 437 * return -1 if the connection must be killed.
437 */ 438 */
438static int read_connection_handshake(TCP_Secure_Connection *con, uint8_t *self_secret_key) 439static int read_connection_handshake(TCP_Secure_Connection *con, const uint8_t *self_secret_key)
439{ 440{
440 uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE]; 441 uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE];
441 int len = 0; 442 int len = 0;
@@ -451,7 +452,7 @@ static int read_connection_handshake(TCP_Secure_Connection *con, uint8_t *self_s
451 * return 0 if could not send packet. 452 * return 0 if could not send packet.
452 * return -1 on failure (connection must be killed). 453 * return -1 on failure (connection must be killed).
453 */ 454 */
454static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, uint8_t *public_key) 455static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, const uint8_t *public_key)
455{ 456{
456 uint8_t data[1 + 1 + crypto_box_PUBLICKEYBYTES]; 457 uint8_t data[1 + 1 + crypto_box_PUBLICKEYBYTES];
457 data[0] = TCP_PACKET_ROUTING_RESPONSE; 458 data[0] = TCP_PACKET_ROUTING_RESPONSE;
@@ -484,7 +485,7 @@ static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id)
484/* return 0 on success. 485/* return 0 on success.
485 * return -1 on failure (connection must be killed). 486 * return -1 on failure (connection must be killed).
486 */ 487 */
487static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, uint8_t *public_key) 488static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *public_key)
488{ 489{
489 uint32_t i; 490 uint32_t i;
490 uint32_t index = ~0; 491 uint32_t index = ~0;
@@ -562,7 +563,7 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, uint8
562/* return 0 on success. 563/* return 0 on success.
563 * return -1 on failure (connection must be killed). 564 * return -1 on failure (connection must be killed).
564 */ 565 */
565static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, uint8_t *public_key, uint8_t *data, 566static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data,
566 uint16_t length) 567 uint16_t length)
567{ 568{
568 if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) 569 if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH)
@@ -645,7 +646,7 @@ static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data,
645/* return 0 on success 646/* return 0 on success
646 * return -1 on failure 647 * return -1 on failure
647 */ 648 */
648static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, uint8_t *data, uint16_t length) 649static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *data, uint16_t length)
649{ 650{
650 if (length == 0) 651 if (length == 0)
651 return -1; 652 return -1;
@@ -764,7 +765,8 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, uint8_t *d
764} 765}
765 766
766 767
767static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t *data, uint16_t length) 768static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection *con, const uint8_t *data,
769 uint16_t length)
768{ 770{
769 int index = add_accepted(TCP_server, con); 771 int index = add_accepted(TCP_server, con);
770 772
@@ -818,9 +820,10 @@ static sock_t new_listening_TCP_socket(int family, uint16_t port)
818 return ~0; 820 return ~0;
819 } 821 }
820 822
821 int ok = 1;
822#ifndef TCP_SERVER_USE_EPOLL 823#ifndef TCP_SERVER_USE_EPOLL
823 ok = set_socket_nonblock(sock); 824 int ok = set_socket_nonblock(sock);
825#else
826 int ok = 1;
824#endif 827#endif
825 828
826 if (ok && family == AF_INET6) { 829 if (ok && family == AF_INET6) {
@@ -837,8 +840,8 @@ static sock_t new_listening_TCP_socket(int family, uint16_t port)
837 return sock; 840 return sock;
838} 841}
839 842
840TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, uint16_t *ports, uint8_t *public_key, 843TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uint16_t *ports, const uint8_t *public_key,
841 uint8_t *secret_key, Onion *onion) 844 const uint8_t *secret_key, Onion *onion)
842{ 845{
843 if (num_sockets == 0 || ports == NULL) 846 if (num_sockets == 0 || ports == NULL)
844 return NULL; 847 return NULL;
@@ -914,7 +917,7 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, uint16_t
914 memcpy(temp->public_key, public_key, crypto_box_PUBLICKEYBYTES); 917 memcpy(temp->public_key, public_key, crypto_box_PUBLICKEYBYTES);
915 memcpy(temp->secret_key, secret_key, crypto_box_SECRETKEYBYTES); 918 memcpy(temp->secret_key, secret_key, crypto_box_SECRETKEYBYTES);
916 919
917 bs_list_init(&temp->accepted_key_list, crypto_box_PUBLICKEYBYTES); 920 bs_list_init(&temp->accepted_key_list, crypto_box_PUBLICKEYBYTES, 8);
918 921
919 return temp; 922 return temp;
920} 923}
diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h
index 40984778..def0a978 100644
--- a/toxcore/TCP_server.h
+++ b/toxcore/TCP_server.h
@@ -133,8 +133,8 @@ typedef struct {
133 133
134/* Create new TCP server instance. 134/* Create new TCP server instance.
135 */ 135 */
136TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, uint16_t *ports, uint8_t *public_key, 136TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uint16_t *ports, const uint8_t *public_key,
137 uint8_t *secret_key, Onion *onion); 137 const uint8_t *secret_key, Onion *onion);
138 138
139/* Run the TCP_server 139/* Run the TCP_server
140 */ 140 */
@@ -164,7 +164,7 @@ int read_TCP_packet(sock_t sock, uint8_t *data, uint16_t length);
164 * return 0 if could not read any packet. 164 * return 0 if could not read any packet.
165 * return -1 on failure (connection must be killed). 165 * return -1 on failure (connection must be killed).
166 */ 166 */
167int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, uint8_t *shared_key, 167int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, const uint8_t *shared_key,
168 uint8_t *recv_nonce, uint8_t *data, uint16_t max_len); 168 uint8_t *recv_nonce, uint8_t *data, uint16_t max_len);
169 169
170 170
diff --git a/toxcore/assoc.c b/toxcore/assoc.c
index 5ea67965..4d837aa3 100644
--- a/toxcore/assoc.c
+++ b/toxcore/assoc.c
@@ -886,7 +886,7 @@ void do_Assoc(Assoc *assoc, DHT *dht)
886 * send getnode() requests to both */ 886 * send getnode() requests to both */
887 uint8_t *target_id = NULL; 887 uint8_t *target_id = NULL;
888 Client_entry *heard = NULL, *seen = NULL; 888 Client_entry *heard = NULL, *seen = NULL;
889 size_t i, k, m, bckt; 889 size_t i, k, m;
890 890
891 for (i = 1; i < assoc->candidates_bucket_count; i++) { 891 for (i = 1; i < assoc->candidates_bucket_count; i++) {
892 if (i % 2) 892 if (i % 2)
@@ -894,7 +894,7 @@ void do_Assoc(Assoc *assoc, DHT *dht)
894 else 894 else
895 k = i >> 1; 895 k = i >> 1;
896 896
897 bckt = (candidate + k) % assoc->candidates_bucket_count; 897 size_t bckt = (candidate + k) % assoc->candidates_bucket_count;
898 898
899 for (m = 0; m < assoc->candidates_bucket_size; m++) 899 for (m = 0; m < assoc->candidates_bucket_size; m++)
900 if (assoc->candidates[bckt].list[m].hash) { 900 if (assoc->candidates[bckt].list[m].hash) {
diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c
index 1f76878b..53ef69d3 100644
--- a/toxcore/group_chats.c
+++ b/toxcore/group_chats.c
@@ -471,16 +471,6 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, const
471 471
472 int ok = add_closepeer(chat, chat->group[peernum].client_id, source); 472 int ok = add_closepeer(chat, chat->group[peernum].client_id, source);
473 473
474 if (chat->assoc) {
475 ippts_send.ip_port = chat->group[peernum].ping_via;
476 ippts_send.timestamp = chat->group[peernum].last_pinged;
477
478 IP_Port ipp_recv;
479 ipp_recv = source;
480
481 Assoc_add_entry(chat->assoc, contents.nodes[i].client_id, &ippts_send, &ipp_recv, ok == 0 ? 1 : 0);
482 }
483
484 return 0; 474 return 0;
485} 475}
486 476
diff --git a/toxcore/list.c b/toxcore/list.c
index c513afab..301e56f8 100644
--- a/toxcore/list.c
+++ b/toxcore/list.c
@@ -63,7 +63,7 @@ static int find(const BS_LIST *list, const void *data)
63 //closest match is found if we move back to where we have already been 63 //closest match is found if we move back to where we have already been
64 64
65 while (1) { 65 while (1) {
66 int r = memcmp(data, list->data + list->size * i, list->size); 66 int r = memcmp(data, list->data + list->element_size * i, list->element_size);
67 67
68 if (r == 0) { 68 if (r == 0) {
69 return i; 69 return i;
@@ -105,14 +105,54 @@ static int find(const BS_LIST *list, const void *data)
105 } 105 }
106} 106}
107 107
108/* Resized the list list
109 *
110 * return value:
111 * 1 : success
112 * 0 : failure
113 */
114static int resize(BS_LIST *list, uint32_t new_size)
115{
116 void *p;
117
118 p = realloc(list->data, list->element_size * new_size);
119
120 if (!p) {
121 return 0;
122 } else {
123 list->data = p;
124 }
125
126 p = realloc(list->ids, sizeof(int) * new_size);
108 127
109void bs_list_init(BS_LIST *list, uint32_t element_size) 128 if (!p) {
129 return 0;
130 } else {
131 list->ids = p;
132 }
133
134 return 1;
135}
136
137
138int bs_list_init(BS_LIST *list, uint32_t element_size, uint32_t initial_capacity)
110{ 139{
111 //set initial values 140 //set initial values
112 list->n = 0; 141 list->n = 0;
113 list->size = element_size; 142 list->element_size = element_size;
143 list->capacity = 0;
114 list->data = NULL; 144 list->data = NULL;
115 list->ids = NULL; 145 list->ids = NULL;
146
147 if (initial_capacity != 0) {
148 if (!resize(list, initial_capacity)) {
149 return 0;
150 }
151 }
152
153 list->capacity = initial_capacity;
154
155 return 1;
116} 156}
117 157
118void bs_list_free(BS_LIST *list) 158void bs_list_free(BS_LIST *list)
@@ -147,28 +187,22 @@ int bs_list_add(BS_LIST *list, const void *data, int id)
147 187
148 i = ~i; 188 i = ~i;
149 189
150 //increase the size of the arrays by one 190 //increase the size of the arrays if needed
151 void *p; 191 if (list->n == list->capacity) {
152 192 // 1.5 * n + 1
153 p = realloc(list->data, list->size * (list->n + 1)); 193 const uint32_t new_capacity = list->n + list->n / 2 + 1;
154 194
155 if (!p) { 195 if (!resize(list, new_capacity)) {
156 return 0; 196 return 0;
157 } else { 197 }
158 list->data = p;
159 }
160
161 p = realloc(list->ids, sizeof(int) * (list->n + 1));
162 198
163 if (!p) { 199 list->capacity = new_capacity;
164 return 0;
165 } else {
166 list->ids = p;
167 } 200 }
168 201
169 //insert data to element array 202 //insert data to element array
170 memmove(list->data + (i + 1) * list->size, list->data + i * list->size, (list->n - i) * list->size); 203 memmove(list->data + (i + 1) * list->element_size, list->data + i * list->element_size,
171 memcpy(list->data + i * list->size, data, list->size); 204 (list->n - i) * list->element_size);
205 memcpy(list->data + i * list->element_size, data, list->element_size);
172 206
173 //insert id to id array 207 //insert id to id array
174 memmove(&list->ids[i + 1], &list->ids[i], (list->n - i) * sizeof(int)); 208 memmove(&list->ids[i + 1], &list->ids[i], (list->n - i) * sizeof(int));
@@ -193,10 +227,30 @@ int bs_list_remove(BS_LIST *list, const void *data, int id)
193 return 0; 227 return 0;
194 } 228 }
195 229
230 //decrease the size of the arrays if needed
231 if (list->n < list->capacity / 2) {
232 const uint32_t new_capacity = list->capacity / 2;
233
234 if (resize(list, new_capacity)) {
235 list->capacity = new_capacity;
236 }
237 }
238
196 list->n--; 239 list->n--;
197 240
198 memmove(list->data + i * list->size, list->data + (i + 1) * list->size, (list->n - i) * list->size); 241 memmove(list->data + i * list->element_size, list->data + (i + 1) * list->element_size,
242 (list->n - i) * list->element_size);
199 memmove(&list->ids[i], &list->ids[i + 1], (list->n - i) * sizeof(int)); 243 memmove(&list->ids[i], &list->ids[i + 1], (list->n - i) * sizeof(int));
200 244
201 return 1; 245 return 1;
202} 246}
247
248int bs_list_trim(BS_LIST *list)
249{
250 if (!resize(list, list->n)) {
251 return 0;
252 }
253
254 list->capacity = list->n;
255 return 1;
256}
diff --git a/toxcore/list.h b/toxcore/list.h
index 1a1fe57d..03ac04dd 100644
--- a/toxcore/list.h
+++ b/toxcore/list.h
@@ -32,13 +32,20 @@
32 32
33typedef struct { 33typedef struct {
34 uint32_t n; //number of elements 34 uint32_t n; //number of elements
35 uint32_t size; //size of the elements 35 uint32_t capacity; //number of elements memory is allocated for
36 uint32_t element_size; //size of the elements
36 void *data; //array of elements 37 void *data; //array of elements
37 int *ids; //array of element ids 38 int *ids; //array of element ids
38} BS_LIST; 39} BS_LIST;
39 40
40/* Initialize a list, element_size is the size of the elements in the list */ 41/* Initialize a list, element_size is the size of the elements in the list and
41void bs_list_init(BS_LIST *list, uint32_t element_size); 42 * initial_capacity is the number of elements the memory will be initially allocated for
43 *
44 * return value:
45 * 1 : success
46 * 0 : failure
47 */
48int bs_list_init(BS_LIST *list, uint32_t element_size, uint32_t initial_capacity);
42 49
43/* Free a list initiated with list_init */ 50/* Free a list initiated with list_init */
44void bs_list_free(BS_LIST *list); 51void bs_list_free(BS_LIST *list);
@@ -67,4 +74,12 @@ int bs_list_add(BS_LIST *list, const void *data, int id);
67 */ 74 */
68int bs_list_remove(BS_LIST *list, const void *data, int id); 75int bs_list_remove(BS_LIST *list, const void *data, int id);
69 76
77/* Removes the memory overhead
78 *
79 * return value:
80 * 1 : success
81 * 0 : failure
82 */
83int bs_list_trim(BS_LIST *list);
84
70#endif 85#endif
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 0e88c86c..e0319f34 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -32,7 +32,7 @@
32#include "util.h" 32#include "util.h"
33#include "math.h" 33#include "math.h"
34 34
35static uint8_t crypt_connection_id_not_valid(Net_Crypto *c, int crypt_connection_id) 35static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id)
36{ 36{
37 return (uint32_t)crypt_connection_id >= c->crypto_connections_length; 37 return (uint32_t)crypt_connection_id >= c->crypto_connections_length;
38} 38}
@@ -70,7 +70,7 @@ static int is_alive(uint8_t status)
70 * return -1 on failure. 70 * return -1 on failure.
71 * return COOKIE_REQUEST_LENGTH on success. 71 * return COOKIE_REQUEST_LENGTH on success.
72 */ 72 */
73static int create_cookie_request(Net_Crypto *c, uint8_t *packet, uint8_t *dht_public_key, uint64_t number, 73static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, uint8_t *dht_public_key, uint64_t number,
74 uint8_t *shared_key) 74 uint8_t *shared_key)
75{ 75{
76 uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH]; 76 uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH];
@@ -100,7 +100,7 @@ static int create_cookie_request(Net_Crypto *c, uint8_t *packet, uint8_t *dht_pu
100 * return -1 on failure. 100 * return -1 on failure.
101 * return 0 on success. 101 * return 0 on success.
102 */ 102 */
103static int create_cookie(uint8_t *cookie, uint8_t *bytes, uint8_t *encryption_key) 103static int create_cookie(uint8_t *cookie, const uint8_t *bytes, const uint8_t *encryption_key)
104{ 104{
105 uint8_t contents[COOKIE_CONTENTS_LENGTH]; 105 uint8_t contents[COOKIE_CONTENTS_LENGTH];
106 uint64_t temp_time = unix_time(); 106 uint64_t temp_time = unix_time();
@@ -148,8 +148,8 @@ static int open_cookie(uint8_t *bytes, const uint8_t *cookie, const uint8_t *enc
148 * return -1 on failure. 148 * return -1 on failure.
149 * return COOKIE_RESPONSE_LENGTH on success. 149 * return COOKIE_RESPONSE_LENGTH on success.
150 */ 150 */
151static int create_cookie_response(Net_Crypto *c, uint8_t *packet, uint8_t *request_plain, uint8_t *shared_key, 151static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const uint8_t *request_plain,
152 uint8_t *dht_public_key) 152 const uint8_t *shared_key, const uint8_t *dht_public_key)
153{ 153{
154 uint8_t cookie_plain[COOKIE_DATA_LENGTH]; 154 uint8_t cookie_plain[COOKIE_DATA_LENGTH];
155 memcpy(cookie_plain, request_plain, crypto_box_PUBLICKEYBYTES); 155 memcpy(cookie_plain, request_plain, crypto_box_PUBLICKEYBYTES);
@@ -177,8 +177,8 @@ static int create_cookie_response(Net_Crypto *c, uint8_t *packet, uint8_t *reque
177 * return -1 on failure. 177 * return -1 on failure.
178 * return 0 on success. 178 * return 0 on success.
179 */ 179 */
180static int handle_cookie_request(Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key, uint8_t *dht_public_key, 180static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key,
181 const uint8_t *packet, uint16_t length) 181 uint8_t *dht_public_key, const uint8_t *packet, uint16_t length)
182{ 182{
183 if (length != COOKIE_REQUEST_LENGTH) 183 if (length != COOKIE_REQUEST_LENGTH)
184 return -1; 184 return -1;
@@ -220,8 +220,8 @@ static int udp_handle_cookie_request(void *object, IP_Port source, const uint8_t
220 220
221/* Handle the cookie request packet (for TCP) 221/* Handle the cookie request packet (for TCP)
222 */ 222 */
223static int tcp_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id, uint8_t *packet, 223static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id,
224 uint32_t length) 224 const uint8_t *packet, uint32_t length)
225{ 225{
226 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; 226 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
227 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 227 uint8_t shared_key[crypto_box_BEFORENMBYTES];
@@ -243,8 +243,8 @@ static int tcp_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_c
243 243
244/* Handle the cookie request packet (for TCP oob packets) 244/* Handle the cookie request packet (for TCP oob packets)
245 */ 245 */
246static int tcp_oob_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t *dht_public_key, 246static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con,
247 uint8_t *packet, uint32_t length) 247 const uint8_t *dht_public_key, const uint8_t *packet, uint32_t length)
248{ 248{
249 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; 249 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
250 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 250 uint8_t shared_key[crypto_box_BEFORENMBYTES];
@@ -302,8 +302,8 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, const uint8
302 * return -1 on failure. 302 * return -1 on failure.
303 * return HANDSHAKE_PACKET_LENGTH on success. 303 * return HANDSHAKE_PACKET_LENGTH on success.
304 */ 304 */
305static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cookie, uint8_t *nonce, uint8_t *session_pk, 305static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const uint8_t *cookie, const uint8_t *nonce,
306 uint8_t *peer_real_pk, uint8_t *peer_dht_pubkey) 306 const uint8_t *session_pk, const uint8_t *peer_real_pk, const uint8_t *peer_dht_pubkey)
307{ 307{
308 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH]; 308 uint8_t plain[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_hash_sha512_BYTES + COOKIE_LENGTH];
309 memcpy(plain, nonce, crypto_box_NONCEBYTES); 309 memcpy(plain, nonce, crypto_box_NONCEBYTES);
@@ -348,8 +348,8 @@ static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cook
348 * return -1 on failure. 348 * return -1 on failure.
349 * return 0 on success. 349 * return 0 on success.
350 */ 350 */
351static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, 351static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk,
352 uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint32_t length, uint8_t *expected_real_pk) 352 uint8_t *dht_public_key, uint8_t *cookie, const uint8_t *packet, uint32_t length, const uint8_t *expected_real_pk)
353{ 353{
354 if (length != HANDSHAKE_PACKET_LENGTH) 354 if (length != HANDSHAKE_PACKET_LENGTH)
355 return -1; 355 return -1;
@@ -386,7 +386,7 @@ static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *sessi
386} 386}
387 387
388 388
389static Crypto_Connection *get_crypto_connection(Net_Crypto *c, int crypt_connection_id) 389static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_connection_id)
390{ 390{
391 if (crypt_connection_id_not_valid(c, crypt_connection_id)) 391 if (crypt_connection_id_not_valid(c, crypt_connection_id))
392 return 0; 392 return 0;
@@ -400,7 +400,7 @@ static Crypto_Connection *get_crypto_connection(Net_Crypto *c, int crypt_connect
400 * return -1 on failure. 400 * return -1 on failure.
401 * return 0 on success. 401 * return 0 on success.
402 */ 402 */
403static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) 403static int send_packet_to(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
404{ 404{
405//TODO TCP, etc... 405//TODO TCP, etc...
406 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 406 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -456,7 +456,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data,
456/* Return number of packets in array 456/* Return number of packets in array
457 * Note that holes are counted too. 457 * Note that holes are counted too.
458 */ 458 */
459static uint32_t num_packets_array(Packets_Array *array) 459static uint32_t num_packets_array(const Packets_Array *array)
460{ 460{
461 return array->buffer_end - array->buffer_start; 461 return array->buffer_end - array->buffer_start;
462} 462}
@@ -466,7 +466,7 @@ static uint32_t num_packets_array(Packets_Array *array)
466 * return -1 on failure. 466 * return -1 on failure.
467 * return 0 on success. 467 * return 0 on success.
468 */ 468 */
469static int add_data_to_buffer(Packets_Array *array, uint32_t number, Packet_Data *data) 469static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packet_Data *data)
470{ 470{
471 if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE) 471 if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE)
472 return -1; 472 return -1;
@@ -496,7 +496,7 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, Packet_Data
496 * return 0 if data at number is empty. 496 * return 0 if data at number is empty.
497 * return 1 if data pointer was put in data. 497 * return 1 if data pointer was put in data.
498 */ 498 */
499static int get_data_pointer(Packets_Array *array, Packet_Data **data, uint32_t number) 499static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint32_t number)
500{ 500{
501 uint32_t num_spots = array->buffer_end - array->buffer_start; 501 uint32_t num_spots = array->buffer_end - array->buffer_start;
502 502
@@ -517,7 +517,7 @@ static int get_data_pointer(Packets_Array *array, Packet_Data **data, uint32_t n
517 * return -1 on failure. 517 * return -1 on failure.
518 * return packet number on success. 518 * return packet number on success.
519 */ 519 */
520static int64_t add_data_end_of_buffer(Packets_Array *array, Packet_Data *data) 520static int64_t add_data_end_of_buffer(Packets_Array *array, const Packet_Data *data)
521{ 521{
522 if (num_packets_array(array) >= CRYPTO_PACKET_BUFFER_SIZE) 522 if (num_packets_array(array) >= CRYPTO_PACKET_BUFFER_SIZE)
523 return -1; 523 return -1;
@@ -607,7 +607,7 @@ static int set_buffer_end(Packets_Array *array, uint32_t number)
607 * return -1 on failure. 607 * return -1 on failure.
608 * return length of packet on success. 608 * return length of packet on success.
609 */ 609 */
610static int generate_request_packet(uint8_t *data, uint16_t length, Packets_Array *recv_array) 610static int generate_request_packet(uint8_t *data, uint16_t length, const Packets_Array *recv_array)
611{ 611{
612 if (length == 0) 612 if (length == 0)
613 return -1; 613 return -1;
@@ -656,7 +656,7 @@ static int generate_request_packet(uint8_t *data, uint16_t length, Packets_Array
656 * return -1 on failure. 656 * return -1 on failure.
657 * return number of requested packets on success. 657 * return number of requested packets on success.
658 */ 658 */
659static int handle_request_packet(Packets_Array *send_array, uint8_t *data, uint16_t length) 659static int handle_request_packet(Packets_Array *send_array, const uint8_t *data, uint16_t length)
660{ 660{
661 if (length < 1) 661 if (length < 1)
662 return -1; 662 return -1;
@@ -718,7 +718,7 @@ static int handle_request_packet(Packets_Array *send_array, uint8_t *data, uint1
718 * return -1 on failure. 718 * return -1 on failure.
719 * return 0 on success. 719 * return 0 on success.
720 */ 720 */
721static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) 721static int send_data_packet(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
722{ 722{
723 if (length == 0 || length + (1 + sizeof(uint16_t) + crypto_box_MACBYTES) > MAX_CRYPTO_PACKET_SIZE) 723 if (length == 0 || length + (1 + sizeof(uint16_t) + crypto_box_MACBYTES) > MAX_CRYPTO_PACKET_SIZE)
724 return -1; 724 return -1;
@@ -750,8 +750,8 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *dat
750 * return -1 on failure. 750 * return -1 on failure.
751 * return 0 on success. 751 * return 0 on success.
752 */ 752 */
753static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num, 753static int send_data_packet_helper(const Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num,
754 uint8_t *data, uint32_t length) 754 const uint8_t *data, uint32_t length)
755{ 755{
756 if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) 756 if (length == 0 || length > MAX_CRYPTO_DATA_SIZE)
757 return -1; 757 return -1;
@@ -771,7 +771,7 @@ static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint3
771/* return -1 if data could not be put in packet queue. 771/* return -1 if data could not be put in packet queue.
772 * return positive packet number if data was put into the queue. 772 * return positive packet number if data was put into the queue.
773 */ 773 */
774static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) 774static int64_t send_lossless_packet(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint32_t length)
775{ 775{
776 if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) 776 if (length == 0 || length > MAX_CRYPTO_DATA_SIZE)
777 return -1; 777 return -1;
@@ -781,8 +781,29 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, uint
781 if (conn == 0) 781 if (conn == 0)
782 return -1; 782 return -1;
783 783
784 uint64_t temp_time = current_time_monotonic();
785
786 /* If last packet send failed, try to send packet again.
787 If sending it fails we won't be able to send the new packet. */
788 if (conn->maximum_speed_reached) {
789 Packet_Data *dt = NULL;
790 uint32_t packet_num = conn->send_array.buffer_end - 1;
791 int ret = get_data_pointer(&conn->send_array, &dt, packet_num);
792
793 if (ret == 1) {
794 if (!dt->time) {
795 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data,
796 dt->length) != 0) {
797 return -1;
798 }
799
800 dt->time = temp_time;
801 }
802 }
803 }
804
784 Packet_Data dt; 805 Packet_Data dt;
785 dt.time = current_time_monotonic(); 806 dt.time = temp_time;
786 dt.length = length; 807 dt.length = length;
787 memcpy(dt.data, data, length); 808 memcpy(dt.data, data, length);
788 int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt); 809 int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt);
@@ -790,8 +811,15 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, uint
790 if (packet_num == -1) 811 if (packet_num == -1)
791 return -1; 812 return -1;
792 813
793 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) != 0) 814 conn->maximum_speed_reached = 0;
815
816 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) != 0) {
817 Packet_Data *dt1 = NULL;
818 get_data_pointer(&conn->send_array, &dt1, packet_num);
819 dt1->time = 0;
820 conn->maximum_speed_reached = 1;
794 fprintf(stderr, "send_data_packet failed\n"); 821 fprintf(stderr, "send_data_packet failed\n");
822 }
795 823
796 return packet_num; 824 return packet_num;
797} 825}
@@ -799,7 +827,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, uint
799/* Get the lowest 2 bytes from the nonce and convert 827/* Get the lowest 2 bytes from the nonce and convert
800 * them to host byte format before returning them. 828 * them to host byte format before returning them.
801 */ 829 */
802static uint16_t get_nonce_uint16(uint8_t *nonce) 830static uint16_t get_nonce_uint16(const uint8_t *nonce)
803{ 831{
804 uint16_t num; 832 uint16_t num;
805 memcpy(&num, nonce + (crypto_box_NONCEBYTES - sizeof(uint16_t)), sizeof(uint16_t)); 833 memcpy(&num, nonce + (crypto_box_NONCEBYTES - sizeof(uint16_t)), sizeof(uint16_t));
@@ -815,7 +843,7 @@ static uint16_t get_nonce_uint16(uint8_t *nonce)
815 * return -1 on failure. 843 * return -1 on failure.
816 * return length of data on success. 844 * return length of data on success.
817 */ 845 */
818static int handle_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, const uint8_t *packet, 846static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint8_t *data, const uint8_t *packet,
819 uint16_t length) 847 uint16_t length)
820{ 848{
821 if (length <= (1 + sizeof(uint16_t) + crypto_box_MACBYTES) || length > MAX_CRYPTO_PACKET_SIZE) 849 if (length <= (1 + sizeof(uint16_t) + crypto_box_MACBYTES) || length > MAX_CRYPTO_PACKET_SIZE)
@@ -852,7 +880,7 @@ static int handle_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *d
852 * return -1 on failure. 880 * return -1 on failure.
853 * return 0 on success. 881 * return 0 on success.
854 */ 882 */
855static int send_request_packet(Net_Crypto *c, int crypt_connection_id) 883static int send_request_packet(const Net_Crypto *c, int crypt_connection_id)
856{ 884{
857 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 885 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
858 886
@@ -874,7 +902,7 @@ static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
874 * return -1 on failure. 902 * return -1 on failure.
875 * return number of packets sent on success. 903 * return number of packets sent on success.
876 */ 904 */
877static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num) 905static int send_requested_packets(const Net_Crypto *c, int crypt_connection_id, uint16_t max_num)
878{ 906{
879 if (max_num == 0) 907 if (max_num == 0)
880 return -1; 908 return -1;
@@ -920,7 +948,7 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16
920 * return -1 on failure. 948 * return -1 on failure.
921 * return 0 on success. 949 * return 0 on success.
922 */ 950 */
923static int new_temp_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length) 951static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
924{ 952{
925 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) 953 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
926 return -1; 954 return -1;
@@ -951,7 +979,7 @@ static int new_temp_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *pack
951 * return -1 on failure. 979 * return -1 on failure.
952 * return 0 on success. 980 * return 0 on success.
953 */ 981 */
954static int clear_temp_packet(Net_Crypto *c, int crypt_connection_id) 982static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id)
955{ 983{
956 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 984 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
957 985
@@ -974,7 +1002,7 @@ static int clear_temp_packet(Net_Crypto *c, int crypt_connection_id)
974 * return -1 on failure. 1002 * return -1 on failure.
975 * return 0 on success. 1003 * return 0 on success.
976 */ 1004 */
977static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) 1005static int send_temp_packet(const Net_Crypto *c, int crypt_connection_id)
978{ 1006{
979 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1007 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
980 1008
@@ -998,7 +1026,8 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
998 * return -1 on failure. 1026 * return -1 on failure.
999 * return 0 on success. 1027 * return 0 on success.
1000 */ 1028 */
1001static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, uint8_t *cookie, uint8_t *dht_public_key) 1029static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie,
1030 const uint8_t *dht_public_key)
1002{ 1031{
1003 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1032 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1004 1033
@@ -1023,7 +1052,7 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, uint8_t
1023 * return -1 on failure. 1052 * return -1 on failure.
1024 * return 0 on success. 1053 * return 0 on success.
1025 */ 1054 */
1026static int send_kill_packet(Net_Crypto *c, int crypt_connection_id) 1055static int send_kill_packet(const Net_Crypto *c, int crypt_connection_id)
1027{ 1056{
1028 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1057 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1029 1058
@@ -1040,7 +1069,8 @@ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
1040 * return -1 on failure. 1069 * return -1 on failure.
1041 * return 0 on success. 1070 * return 0 on success.
1042 */ 1071 */
1043static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length) 1072static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet,
1073 uint16_t length)
1044{ 1074{
1045 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) 1075 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE)
1046 return -1; 1076 return -1;
@@ -1289,7 +1319,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
1289 * return -1 if there are no connections like we are looking for. 1319 * return -1 if there are no connections like we are looking for.
1290 * return id if it found it. 1320 * return id if it found it.
1291 */ 1321 */
1292static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key) 1322static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key)
1293{ 1323{
1294 uint32_t i; 1324 uint32_t i;
1295 1325
@@ -1307,7 +1337,7 @@ static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key)
1307 * return -1 if there are no connections like we are looking for. 1337 * return -1 if there are no connections like we are looking for.
1308 * return id if it found it. 1338 * return id if it found it.
1309 */ 1339 */
1310static int getcryptconnection_id_dht_pubkey(Net_Crypto *c, uint8_t *dht_public_key) 1340static int getcryptconnection_id_dht_pubkey(const Net_Crypto *c, const uint8_t *dht_public_key)
1311{ 1341{
1312 uint32_t i; 1342 uint32_t i;
1313 1343
@@ -1465,7 +1495,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1465 * return -1 on failure. 1495 * return -1 on failure.
1466 * return connection id on success. 1496 * return connection id on success.
1467 */ 1497 */
1468int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key) 1498int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key)
1469{ 1499{
1470 int crypt_connection_id = getcryptconnection_id(c, real_public_key); 1500 int crypt_connection_id = getcryptconnection_id(c, real_public_key);
1471 1501
@@ -1495,7 +1525,7 @@ int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key)
1495 * return -1 on failure. 1525 * return -1 on failure.
1496 * return 0 on success. 1526 * return 0 on success.
1497 */ 1527 */
1498static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id) 1528static int disconnect_peer_tcp(const Net_Crypto *c, int crypt_connection_id)
1499{ 1529{
1500 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1530 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1501 1531
@@ -1520,7 +1550,7 @@ static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1520 * return -1 on failure. 1550 * return -1 on failure.
1521 * return 0 on success. 1551 * return 0 on success.
1522 */ 1552 */
1523static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id) 1553static int connect_peer_tcp(const Net_Crypto *c, int crypt_connection_id)
1524{ 1554{
1525 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1555 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1526 1556
@@ -1545,7 +1575,7 @@ static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1545 * return 0 on failure (no key copied). 1575 * return 0 on failure (no key copied).
1546 * return timestamp on success (key copied). 1576 * return timestamp on success (key copied).
1547 */ 1577 */
1548uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key) 1578uint64_t get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key)
1549{ 1579{
1550 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1580 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1551 1581
@@ -1567,7 +1597,8 @@ uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t
1567 * return -1 on failure. 1597 * return -1 on failure.
1568 * return 0 on success. 1598 * return 0 on success.
1569 */ 1599 */
1570int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp) 1600int set_connection_dht_public_key(const Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key,
1601 uint64_t timestamp)
1571{ 1602{
1572 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1603 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1573 1604
@@ -1628,7 +1659,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1628 return -1; 1659 return -1;
1629} 1660}
1630 1661
1631static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *public_key) 1662static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key)
1632{ 1663{
1633 TCP_Client_Connection *TCP_con = object; 1664 TCP_Client_Connection *TCP_con = object;
1634 Net_Crypto *c = TCP_con->net_crypto_pointer; 1665 Net_Crypto *c = TCP_con->net_crypto_pointer;
@@ -1695,7 +1726,7 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection
1695 return 0; 1726 return 0;
1696} 1727}
1697 1728
1698static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length) 1729static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length)
1699{ 1730{
1700 1731
1701 if (length == 0) 1732 if (length == 0)
@@ -1720,7 +1751,7 @@ static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_i
1720 return 0; 1751 return 0;
1721} 1752}
1722 1753
1723static int tcp_oob_callback(void *object, uint8_t *public_key, uint8_t *data, uint16_t length) 1754static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length)
1724{ 1755{
1725 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) 1756 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1726 return -1; 1757 return -1;
@@ -1762,7 +1793,7 @@ static int tcp_oob_callback(void *object, uint8_t *public_key, uint8_t *data, ui
1762 * return -1 if it can't. 1793 * return -1 if it can't.
1763 * return 0 if it can. 1794 * return 0 if it can.
1764 */ 1795 */
1765static int tcp_connection_check(Net_Crypto *c, uint8_t *public_key) 1796static int tcp_connection_check(const Net_Crypto *c, const uint8_t *public_key)
1766{ 1797{
1767 uint32_t i; 1798 uint32_t i;
1768 1799
@@ -1797,7 +1828,7 @@ static int tcp_connection_check(Net_Crypto *c, uint8_t *public_key)
1797 * return 0 if it was added. 1828 * return 0 if it was added.
1798 * return -1 if it wasn't. 1829 * return -1 if it wasn't.
1799 */ 1830 */
1800int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key) 1831int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, const uint8_t *public_key)
1801{ 1832{
1802 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1833 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1803 1834
@@ -1850,7 +1881,7 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
1850 * return 0 if it was added. 1881 * return 0 if it was added.
1851 * return -1 if it wasn't. 1882 * return -1 if it wasn't.
1852 */ 1883 */
1853int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key) 1884int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
1854{ 1885{
1855 if (ip_port.ip.family == TCP_INET) { 1886 if (ip_port.ip.family == TCP_INET) {
1856 ip_port.ip.family = AF_INET; 1887 ip_port.ip.family = AF_INET;
@@ -1882,7 +1913,7 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key)
1882 * return number of relays copied to tcp_relays on success. 1913 * return number of relays copied to tcp_relays on success.
1883 * return 0 on failure. 1914 * return 0 on failure.
1884 */ 1915 */
1885unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num) 1916unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
1886{ 1917{
1887 if (num == 0) 1918 if (num == 0)
1888 return 0; 1919 return 0;
@@ -2046,8 +2077,8 @@ static void clear_disconnected_tcp(Net_Crypto *c)
2046 * return -1 on failure. 2077 * return -1 on failure.
2047 * return 0 on success. 2078 * return 0 on success.
2048 */ 2079 */
2049int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object, 2080int connection_status_handler(const Net_Crypto *c, int crypt_connection_id,
2050 int id, uint8_t status), void *object, int id) 2081 int (*connection_status_callback)(void *object, int id, uint8_t status), void *object, int id)
2051{ 2082{
2052 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 2083 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2053 2084
@@ -2068,7 +2099,7 @@ int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*conn
2068 * return -1 on failure. 2099 * return -1 on failure.
2069 * return 0 on success. 2100 * return 0 on success.
2070 */ 2101 */
2071int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object, 2102int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object,
2072 int id, uint8_t *data, uint16_t length), void *object, int id) 2103 int id, uint8_t *data, uint16_t length), void *object, int id)
2073{ 2104{
2074 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 2105 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -2091,7 +2122,7 @@ int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connec
2091 * return 0 on success. 2122 * return 0 on success.
2092 */ 2123 */
2093int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, 2124int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
2094 int (*connection_lossy_data_callback)(void *object, int id, uint8_t *data, uint16_t length), void *object, int id) 2125 int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object, int id)
2095{ 2126{
2096 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 2127 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2097 2128
@@ -2109,7 +2140,7 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
2109 * return -1 on failure. 2140 * return -1 on failure.
2110 * return connection id on success. 2141 * return connection id on success.
2111 */ 2142 */
2112static int crypto_id_ip_port(Net_Crypto *c, IP_Port ip_port) 2143static int crypto_id_ip_port(const Net_Crypto *c, IP_Port ip_port)
2113{ 2144{
2114 return bs_list_find(&c->ip_port_list, &ip_port); 2145 return bs_list_find(&c->ip_port_list, &ip_port);
2115} 2146}
@@ -2159,7 +2190,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
2159 2190
2160/* The dT for the average packet recieving rate calculations. 2191/* The dT for the average packet recieving rate calculations.
2161 Also used as the */ 2192 Also used as the */
2162#define PACKET_COUNTER_AVERAGE_INTERVAL 200 2193#define PACKET_COUNTER_AVERAGE_INTERVAL 100
2163 2194
2164/* Ratio of recv queue size / recv packet rate (in seconds) times 2195/* Ratio of recv queue size / recv packet rate (in seconds) times
2165 * the number of ms between request packets to send at that ratio 2196 * the number of ms between request packets to send at that ratio
@@ -2225,13 +2256,13 @@ static void send_crypto_packets(Net_Crypto *c)
2225 } 2256 }
2226 2257
2227 //new "dropped" value: weighted average of previous value and packet drop rate measured by the number of packets which were resends of previous packets 2258 //new "dropped" value: weighted average of previous value and packet drop rate measured by the number of packets which were resends of previous packets
2228 double dropped = (conn->dropped) * 0.5 + (conn->packets_resent / dt) * 0.5; 2259 double dropped = (conn->dropped) * 0.30 + ((double)conn->packets_resent / dt) * 0.70;
2229 2260
2230 //since the "dropped" packets measure is delayed in time from the actual # of dropped packets, 2261 //since the "dropped" packets measure is delayed in time from the actual # of dropped packets,
2231 // ignore dropped packet measure for a second after it becomes high and the send rate is lowered as a result 2262 // ignore dropped packet measure for 2 seconds after it becomes high and the send rate is lowered as a result
2232 double drop_ignore_new; 2263 double drop_ignore_new;
2233 2264
2234 if (conn->drop_ignore_start + 1000 < temp_time) { 2265 if (conn->drop_ignore_start + 2000 < temp_time) {
2235 drop_ignore_new = 0.0; 2266 drop_ignore_new = 0.0;
2236 2267
2237 if ((dropped * 1000.0) / conn->packet_send_rate >= 0.10) { 2268 if ((dropped * 1000.0) / conn->packet_send_rate >= 0.10) {
@@ -2249,7 +2280,6 @@ static void send_crypto_packets(Net_Crypto *c)
2249 realrate = r; 2280 realrate = r;
2250 } 2281 }
2251 2282
2252
2253 //calculate exponential increase in rate, triggered when drop rate is below 5% for 5 seconds 2283 //calculate exponential increase in rate, triggered when drop rate is below 5% for 5 seconds
2254 if ((dropped * 1000.0) / conn->packet_send_rate >= 0.05) { 2284 if ((dropped * 1000.0) / conn->packet_send_rate >= 0.05) {
2255 conn->rate_increase_stop_start = temp_time; 2285 conn->rate_increase_stop_start = temp_time;
@@ -2290,7 +2320,7 @@ static void send_crypto_packets(Net_Crypto *c)
2290 2320
2291 if (conn->last_packets_left_set == 0) { 2321 if (conn->last_packets_left_set == 0) {
2292 conn->last_packets_left_set = temp_time; 2322 conn->last_packets_left_set = temp_time;
2293 conn->packets_left = conn->packet_send_rate; 2323 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
2294 } else if (((1000.0 / conn->packet_send_rate) + conn->last_packets_left_set) < temp_time) { 2324 } else if (((1000.0 / conn->packet_send_rate) + conn->last_packets_left_set) < temp_time) {
2295 uint32_t num_packets = conn->packet_send_rate * ((double)(temp_time - conn->last_packets_left_set) / 1000.0) + 0.5; 2325 uint32_t num_packets = conn->packet_send_rate * ((double)(temp_time - conn->last_packets_left_set) / 1000.0) + 0.5;
2296 2326
@@ -2346,7 +2376,7 @@ static void send_crypto_packets(Net_Crypto *c)
2346/* returns the number of packet slots left in the sendbuffer. 2376/* returns the number of packet slots left in the sendbuffer.
2347 * return 0 if failure. 2377 * return 0 if failure.
2348 */ 2378 */
2349uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) 2379uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connection_id)
2350{ 2380{
2351 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 2381 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2352 2382
@@ -2363,7 +2393,7 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
2363 * 2393 *
2364 * The first byte of data must be in the CRYPTO_RESERVED_PACKETS to PACKET_ID_LOSSY_RANGE_START range. 2394 * The first byte of data must be in the CRYPTO_RESERVED_PACKETS to PACKET_ID_LOSSY_RANGE_START range.
2365 */ 2395 */
2366int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) 2396int64_t write_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint32_t length)
2367{ 2397{
2368 if (length == 0) 2398 if (length == 0)
2369 return -1; 2399 return -1;
@@ -2400,7 +2430,7 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data,
2400 * 2430 *
2401 * Sends a lossy cryptopacket. (first byte must in the PACKET_ID_LOSSY_RANGE_*) 2431 * Sends a lossy cryptopacket. (first byte must in the PACKET_ID_LOSSY_RANGE_*)
2402 */ 2432 */
2403int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) 2433int send_lossy_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint32_t length)
2404{ 2434{
2405 if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) 2435 if (length == 0 || length > MAX_CRYPTO_DATA_SIZE)
2406 return -1; 2436 return -1;
@@ -2442,7 +2472,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2442 * 2472 *
2443 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. 2473 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
2444 */ 2474 */
2445unsigned int crypto_connection_status(Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected) 2475unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected)
2446{ 2476{
2447 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 2477 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2448 2478
@@ -2465,7 +2495,7 @@ void new_keys(Net_Crypto *c)
2465/* Save the public and private keys to the keys array. 2495/* Save the public and private keys to the keys array.
2466 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. 2496 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES.
2467 */ 2497 */
2468void save_keys(Net_Crypto *c, uint8_t *keys) 2498void save_keys(const Net_Crypto *c, uint8_t *keys)
2469{ 2499{
2470 memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES); 2500 memcpy(keys, c->self_public_key, crypto_box_PUBLICKEYBYTES);
2471 memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES); 2501 memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES);
@@ -2507,7 +2537,7 @@ Net_Crypto *new_net_crypto(DHT *dht)
2507 networking_registerhandler(dht->net, NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp); 2537 networking_registerhandler(dht->net, NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp);
2508 networking_registerhandler(dht->net, NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp); 2538 networking_registerhandler(dht->net, NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp);
2509 2539
2510 bs_list_init(&temp->ip_port_list, sizeof(IP_Port)); 2540 bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8);
2511 return temp; 2541 return temp;
2512} 2542}
2513 2543
@@ -2553,7 +2583,7 @@ static void kill_timedout(Net_Crypto *c)
2553 2583
2554/* return the optimal interval in ms for running do_net_crypto. 2584/* return the optimal interval in ms for running do_net_crypto.
2555 */ 2585 */
2556uint32_t crypto_run_interval(Net_Crypto *c) 2586uint32_t crypto_run_interval(const Net_Crypto *c)
2557{ 2587{
2558 return c->current_sleep_time; 2588 return c->current_sleep_time;
2559} 2589}
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index ee790f24..4fed0000 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -41,7 +41,7 @@
41#define CRYPTO_PACKET_MIN_RATE 16.0 41#define CRYPTO_PACKET_MIN_RATE 16.0
42 42
43/* Minimum packet queue max length. */ 43/* Minimum packet queue max length. */
44#define CRYPTO_MIN_QUEUE_LENGTH 8 44#define CRYPTO_MIN_QUEUE_LENGTH 16
45 45
46#define MAX_CRYPTO_PACKET_SIZE 1400 46#define MAX_CRYPTO_PACKET_SIZE 1400
47 47
@@ -129,7 +129,7 @@ typedef struct {
129 void *connection_data_callback_object; 129 void *connection_data_callback_object;
130 int connection_data_callback_id; 130 int connection_data_callback_id;
131 131
132 int (*connection_lossy_data_callback)(void *object, int id, uint8_t *data, uint16_t length); 132 int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length);
133 void *connection_lossy_data_callback_object; 133 void *connection_lossy_data_callback_object;
134 int connection_lossy_data_callback_id; 134 int connection_lossy_data_callback_id;
135 135
@@ -157,6 +157,8 @@ typedef struct {
157 Node_format tcp_relays[MAX_TCP_RELAYS_PEER]; 157 Node_format tcp_relays[MAX_TCP_RELAYS_PEER];
158 uint16_t num_tcp_relays; 158 uint16_t num_tcp_relays;
159 159
160 uint8_t maximum_speed_reached;
161
160 pthread_mutex_t mutex; 162 pthread_mutex_t mutex;
161} Crypto_Connection; 163} Crypto_Connection;
162 164
@@ -218,14 +220,14 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
218 * return -1 on failure. 220 * return -1 on failure.
219 * return connection id on success. 221 * return connection id on success.
220 */ 222 */
221int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key); 223int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key);
222 224
223/* Copy friends DHT public key into dht_key. 225/* Copy friends DHT public key into dht_key.
224 * 226 *
225 * return 0 on failure (no key copied). 227 * return 0 on failure (no key copied).
226 * return timestamp on success (key copied). 228 * return timestamp on success (key copied).
227 */ 229 */
228uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key); 230uint64_t get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key);
229 231
230/* Set the DHT public key of the crypto connection. 232/* Set the DHT public key of the crypto connection.
231 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to 233 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
@@ -234,7 +236,8 @@ uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t
234 * return -1 on failure. 236 * return -1 on failure.
235 * return 0 on success. 237 * return 0 on success.
236 */ 238 */
237int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp); 239int set_connection_dht_public_key(const Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key,
240 uint64_t timestamp);
238 241
239/* Set the direct ip of the crypto connection. 242/* Set the direct ip of the crypto connection.
240 * 243 *
@@ -253,8 +256,8 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port);
253 * return -1 on failure. 256 * return -1 on failure.
254 * return 0 on success. 257 * return 0 on success.
255 */ 258 */
256int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object, 259int connection_status_handler(const Net_Crypto *c, int crypt_connection_id,
257 int id, uint8_t status), void *object, int id); 260 int (*connection_status_callback)(void *object, int id, uint8_t status), void *object, int id);
258 261
259/* Set function to be called when connection with crypt_connection_id receives a lossless data packet of length. 262/* Set function to be called when connection with crypt_connection_id receives a lossless data packet of length.
260 * 263 *
@@ -264,7 +267,7 @@ int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*conn
264 * return -1 on failure. 267 * return -1 on failure.
265 * return 0 on success. 268 * return 0 on success.
266 */ 269 */
267int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object, 270int connection_data_handler(const Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object,
268 int id, uint8_t *data, uint16_t length), void *object, int id); 271 int id, uint8_t *data, uint16_t length), void *object, int id);
269 272
270 273
@@ -277,12 +280,13 @@ int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connec
277 * return 0 on success. 280 * return 0 on success.
278 */ 281 */
279int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, 282int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
280 int (*connection_lossy_data_callback)(void *object, int id, uint8_t *data, uint16_t length), void *object, int id); 283 int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object,
284 int id);
281 285
282/* returns the number of packet slots left in the sendbuffer. 286/* returns the number of packet slots left in the sendbuffer.
283 * return 0 if failure. 287 * return 0 if failure.
284 */ 288 */
285uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id); 289uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connection_id);
286 290
287/* Sends a lossless cryptopacket. 291/* Sends a lossless cryptopacket.
288 * 292 *
@@ -291,28 +295,28 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
291 * 295 *
292 * The first byte of data must be in the CRYPTO_RESERVED_PACKETS to PACKET_ID_LOSSY_RANGE_START range. 296 * The first byte of data must be in the CRYPTO_RESERVED_PACKETS to PACKET_ID_LOSSY_RANGE_START range.
293 */ 297 */
294int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); 298int64_t write_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint32_t length);
295 299
296/* return -1 on failure. 300/* return -1 on failure.
297 * return 0 on success. 301 * return 0 on success.
298 * 302 *
299 * Sends a lossy cryptopacket. (first byte must in the PACKET_ID_LOSSY_RANGE_*) 303 * Sends a lossy cryptopacket. (first byte must in the PACKET_ID_LOSSY_RANGE_*)
300 */ 304 */
301int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); 305int send_lossy_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint32_t length);
302 306
303/* Add a tcp relay, associating it to a crypt_connection_id. 307/* Add a tcp relay, associating it to a crypt_connection_id.
304 * 308 *
305 * return 0 if it was added. 309 * return 0 if it was added.
306 * return -1 if it wasn't. 310 * return -1 if it wasn't.
307 */ 311 */
308int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key); 312int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, const uint8_t *public_key);
309 313
310/* Add a tcp relay to the array. 314/* Add a tcp relay to the array.
311 * 315 *
312 * return 0 if it was added. 316 * return 0 if it was added.
313 * return -1 if it wasn't. 317 * return -1 if it wasn't.
314 */ 318 */
315int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key); 319int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key);
316 320
317/* Copy a maximum of num TCP relays we are connected to to tcp_relays. 321/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
318 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. 322 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
@@ -320,7 +324,7 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key);
320 * return number of relays copied to tcp_relays on success. 324 * return number of relays copied to tcp_relays on success.
321 * return 0 on failure. 325 * return 0 on failure.
322 */ 326 */
323unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num); 327unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
324 328
325/* Kill a crypto connection. 329/* Kill a crypto connection.
326 * 330 *
@@ -334,7 +338,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id);
334 * 338 *
335 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. 339 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
336 */ 340 */
337unsigned int crypto_connection_status(Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected); 341unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected);
338 342
339 343
340/* Generate our public and private keys. 344/* Generate our public and private keys.
@@ -345,7 +349,7 @@ void new_keys(Net_Crypto *c);
345/* Save the public and private keys to the keys array. 349/* Save the public and private keys to the keys array.
346 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. 350 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES.
347 */ 351 */
348void save_keys(Net_Crypto *c, uint8_t *keys); 352void save_keys(const Net_Crypto *c, uint8_t *keys);
349 353
350/* Load the public and private keys from the keys array. 354/* Load the public and private keys from the keys array.
351 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. 355 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES.
@@ -359,7 +363,7 @@ Net_Crypto *new_net_crypto(DHT *dht);
359 363
360/* return the optimal interval in ms for running do_net_crypto. 364/* return the optimal interval in ms for running do_net_crypto.
361 */ 365 */
362uint32_t crypto_run_interval(Net_Crypto *c); 366uint32_t crypto_run_interval(const Net_Crypto *c);
363 367
364/* Main loop. */ 368/* Main loop. */
365void do_net_crypto(Net_Crypto *c); 369void do_net_crypto(Net_Crypto *c);
diff --git a/toxcore/network.c b/toxcore/network.c
index 68359016..0009a558 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -181,13 +181,13 @@ int set_socket_dualstack(sock_t sock)
181{ 181{
182 int ipv6only = 0; 182 int ipv6only = 0;
183 socklen_t optsize = sizeof(ipv6only); 183 socklen_t optsize = sizeof(ipv6only);
184 int res = getsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &optsize); 184 int res = getsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&ipv6only, &optsize);
185 185
186 if ((res == 0) && (ipv6only == 0)) 186 if ((res == 0) && (ipv6only == 0))
187 return 1; 187 return 1;
188 188
189 ipv6only = 0; 189 ipv6only = 0;
190 return (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only)) == 0); 190 return (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&ipv6only, sizeof(ipv6only)) == 0);
191} 191}
192 192
193 193
@@ -596,10 +596,10 @@ Networking_Core *new_networking(IP ip, uint16_t port)
596 */ 596 */
597 uint16_t port_to_try = port; 597 uint16_t port_to_try = port;
598 *portptr = htons(port_to_try); 598 *portptr = htons(port_to_try);
599 int tries, res; 599 int tries;
600 600
601 for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) { 601 for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) {
602 res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); 602 int res = bind(temp->sock, (struct sockaddr *)&addr, addrsize);
603 603
604 if (!res) { 604 if (!res) {
605 temp->port = *portptr; 605 temp->port = *portptr;
diff --git a/toxcore/onion.c b/toxcore/onion.c
index 194178f3..1915324f 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -54,7 +54,7 @@ static void change_symmetric_key(Onion *onion)
54 * return -1 on failure. 54 * return -1 on failure.
55 * return 0 on success. 55 * return 0 on success.
56 */ 56 */
57int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes) 57int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *nodes)
58{ 58{
59 if (!new_path || !nodes) 59 if (!new_path || !nodes)
60 return -1; 60 return -1;
@@ -84,17 +84,19 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes)
84 return 0; 84 return 0;
85} 85}
86 86
87/* Create and send a onion packet. 87/* Create a onion packet.
88 * 88 *
89 * Use Onion_Path path to send data of length to dest. 89 * Use Onion_Path path to create packet for data of length to dest.
90 * Maximum length of data is ONION_MAX_DATA_SIZE. 90 * Maximum length of data is ONION_MAX_DATA_SIZE.
91 * packet should be at least ONION_MAX_PACKET_SIZE big.
91 * 92 *
92 * return -1 on failure. 93 * return -1 on failure.
93 * return 0 on success. 94 * return length of created packet on success.
94 */ 95 */
95int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length) 96int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
97 const uint8_t *data, uint32_t length)
96{ 98{
97 if (1 + length + SEND_1 > ONION_MAX_PACKET_SIZE || length == 0) 99 if (1 + length + SEND_1 > max_packet_length || length == 0)
98 return -1; 100 return -1;
99 101
100 to_net_family(&dest.ip); 102 to_net_family(&dest.ip);
@@ -126,7 +128,6 @@ int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint
126 if ((uint32_t)len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES) 128 if ((uint32_t)len != SIZE_IPPORT + SEND_BASE + length + crypto_box_MACBYTES)
127 return -1; 129 return -1;
128 130
129 uint8_t packet[1 + length + SEND_1];
130 packet[0] = NET_PACKET_ONION_SEND_INITIAL; 131 packet[0] = NET_PACKET_ONION_SEND_INITIAL;
131 memcpy(packet + 1, nonce, crypto_box_NONCEBYTES); 132 memcpy(packet + 1, nonce, crypto_box_NONCEBYTES);
132 memcpy(packet + 1 + crypto_box_NONCEBYTES, path->public_key1, crypto_box_PUBLICKEYBYTES); 133 memcpy(packet + 1 + crypto_box_NONCEBYTES, path->public_key1, crypto_box_PUBLICKEYBYTES);
@@ -137,7 +138,26 @@ int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint
137 if ((uint32_t)len != SIZE_IPPORT + SEND_BASE * 2 + length + crypto_box_MACBYTES) 138 if ((uint32_t)len != SIZE_IPPORT + SEND_BASE * 2 + length + crypto_box_MACBYTES)
138 return -1; 139 return -1;
139 140
140 if ((uint32_t)sendpacket(net, path->ip_port1, packet, sizeof(packet)) != sizeof(packet)) 141 return 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + len;
142}
143
144/* Create and send a onion packet.
145 *
146 * Use Onion_Path path to send data of length to dest.
147 * Maximum length of data is ONION_MAX_DATA_SIZE.
148 *
149 * return -1 on failure.
150 * return 0 on success.
151 */
152int send_onion_packet(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *data, uint32_t length)
153{
154 uint8_t packet[ONION_MAX_PACKET_SIZE];
155 int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length);
156
157 if (len == -1)
158 return -1;
159
160 if (sendpacket(net, path->ip_port1, packet, len) != len)
141 return -1; 161 return -1;
142 162
143 return 0; 163 return 0;
@@ -189,7 +209,7 @@ static int handle_send_initial(void *object, IP_Port source, const uint8_t *pack
189 return onion_send_1(onion, plain, len, source, packet + 1); 209 return onion_send_1(onion, plain, len, source, packet + 1);
190} 210}
191 211
192int onion_send_1(Onion *onion, uint8_t *plain, uint32_t len, IP_Port source, const uint8_t *nonce) 212int onion_send_1(const Onion *onion, const uint8_t *plain, uint32_t len, IP_Port source, const uint8_t *nonce)
193{ 213{
194 IP_Port send_to; 214 IP_Port send_to;
195 ipport_unpack(&send_to, plain); 215 ipport_unpack(&send_to, plain);
diff --git a/toxcore/onion.h b/toxcore/onion.h
index 7ee630e6..527f5c60 100644
--- a/toxcore/onion.h
+++ b/toxcore/onion.h
@@ -76,7 +76,19 @@ typedef struct {
76 * return -1 on failure. 76 * return -1 on failure.
77 * return 0 on success. 77 * return 0 on success.
78 */ 78 */
79int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes); 79int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *nodes);
80
81/* Create a onion packet.
82 *
83 * Use Onion_Path path to create packet for data of length to dest.
84 * Maximum length of data is ONION_MAX_DATA_SIZE.
85 * packet should be at least ONION_MAX_PACKET_SIZE big.
86 *
87 * return -1 on failure.
88 * return length of created packet on success.
89 */
90int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
91 const uint8_t *data, uint32_t length);
80 92
81/* Create and send a onion packet. 93/* Create and send a onion packet.
82 * 94 *
@@ -86,7 +98,7 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes);
86 * return -1 on failure. 98 * return -1 on failure.
87 * return 0 on success. 99 * return 0 on success.
88 */ 100 */
89int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length); 101int send_onion_packet(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *data, uint32_t length);
90 102
91/* Create and send a onion response sent initially to dest with. 103/* Create and send a onion response sent initially to dest with.
92 * Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE. 104 * Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE.
@@ -106,7 +118,7 @@ int send_onion_response(Networking_Core *net, IP_Port dest, const uint8_t *data,
106 * Source family must be set to something else than AF_INET6 or AF_INET so that the callback gets called 118 * Source family must be set to something else than AF_INET6 or AF_INET so that the callback gets called
107 * when the response is received. 119 * when the response is received.
108 */ 120 */
109int onion_send_1(Onion *onion, uint8_t *plain, uint32_t len, IP_Port source, const uint8_t *nonce); 121int onion_send_1(const Onion *onion, const uint8_t *plain, uint32_t len, IP_Port source, const uint8_t *nonce);
110 122
111/* Set the callback to be called when the dest ip_port doesn't have AF_INET6 or AF_INET as the family. 123/* Set the callback to be called when the dest ip_port doesn't have AF_INET6 or AF_INET as the family.
112 * 124 *
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c
index 27d13a8f..dff05135 100644
--- a/toxcore/onion_announce.c
+++ b/toxcore/onion_announce.c
@@ -35,7 +35,7 @@
35#define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE 35#define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE
36#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3) 36#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3)
37 37
38/* Create and send an onion announce request packet. 38/* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
39 * 39 *
40 * path is the path the request will take before it is sent to dest. 40 * path is the path the request will take before it is sent to dest.
41 * 41 *
@@ -47,10 +47,11 @@
47 * receive back in the response. 47 * receive back in the response.
48 * 48 *
49 * return -1 on failure. 49 * return -1 on failure.
50 * return 0 on success. 50 * return packet length on success.
51 */ 51 */
52int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key, 52int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, Node_format dest,
53 uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint64_t sendback_data) 53 const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
54 const uint8_t *data_public_key, uint64_t sendback_data)
54{ 55{
55 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + 56 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES +
56 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 57 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
@@ -59,22 +60,22 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
59 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES); 60 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES);
60 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, &sendback_data, 61 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, &sendback_data,
61 sizeof(sendback_data)); 62 sizeof(sendback_data));
62 uint8_t packet[ANNOUNCE_REQUEST_SIZE]; 63 uint8_t temp[ANNOUNCE_REQUEST_SIZE];
63 packet[0] = NET_PACKET_ANNOUNCE_REQUEST; 64 temp[0] = NET_PACKET_ANNOUNCE_REQUEST;
64 random_nonce(packet + 1); 65 random_nonce(temp + 1);
65 66
66 int len = encrypt_data(dest.client_id, secret_key, packet + 1, plain, sizeof(plain), 67 int len = encrypt_data(dest.client_id, secret_key, temp + 1, plain, sizeof(plain),
67 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); 68 temp + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES);
68 69
69 if ((uint32_t)len + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES != ANNOUNCE_REQUEST_SIZE) 70 if ((uint32_t)len + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES != ANNOUNCE_REQUEST_SIZE)
70 return -1; 71 return -1;
71 72
72 memcpy(packet + 1 + crypto_box_NONCEBYTES, public_key, crypto_box_PUBLICKEYBYTES); 73 memcpy(temp + 1 + crypto_box_NONCEBYTES, public_key, crypto_box_PUBLICKEYBYTES);
73 74
74 return send_onion_packet(net, path, dest.ip_port, packet, sizeof(packet)); 75 return create_onion_packet(packet, max_packet_length, path, dest.ip_port, temp, sizeof(temp));
75} 76}
76 77
77/* Create and send an onion data request packet. 78/* Create an onion data request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
78 * 79 *
79 * path is the path the request will take before it is sent to dest. 80 * path is the path the request will take before it is sent to dest.
80 * (if dest knows the person with the public_key they should 81 * (if dest knows the person with the public_key they should
@@ -88,35 +89,96 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
88 * return -1 on failure. 89 * return -1 on failure.
89 * return 0 on success. 90 * return 0 on success.
90 */ 91 */
91int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key, 92int create_data_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
92 uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length) 93 const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data,
94 uint16_t length)
93{ 95{
94 if ((unsigned int)DATA_REQUEST_MIN_SIZE + length > ONION_MAX_DATA_SIZE) 96 if ((unsigned int)DATA_REQUEST_MIN_SIZE + length > ONION_MAX_DATA_SIZE)
95 return -1; 97 return -1;
96 98
97 uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; 99 uint8_t temp[DATA_REQUEST_MIN_SIZE + length];
98 packet[0] = NET_PACKET_ONION_DATA_REQUEST; 100 temp[0] = NET_PACKET_ONION_DATA_REQUEST;
99 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 101 memcpy(temp + 1, public_key, crypto_box_PUBLICKEYBYTES);
100 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); 102 memcpy(temp + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
101 103
102 uint8_t random_public_key[crypto_box_PUBLICKEYBYTES]; 104 uint8_t random_public_key[crypto_box_PUBLICKEYBYTES];
103 uint8_t random_secret_key[crypto_box_SECRETKEYBYTES]; 105 uint8_t random_secret_key[crypto_box_SECRETKEYBYTES];
104 crypto_box_keypair(random_public_key, random_secret_key); 106 crypto_box_keypair(random_public_key, random_secret_key);
105 107
106 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES); 108 memcpy(temp + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES);
109
110 int len = encrypt_data(encrypt_public_key, random_secret_key, temp + 1 + crypto_box_PUBLICKEYBYTES,
111 data, length, temp + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES);
107 112
108 int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + crypto_box_PUBLICKEYBYTES, 113 if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(temp))
109 data, length, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); 114 return -1;
115
116 return create_onion_packet(packet, max_packet_length, path, dest, temp, sizeof(temp));
117}
118
119/* Create and send an onion announce request packet.
120 *
121 * path is the path the request will take before it is sent to dest.
122 *
123 * public_key and secret_key is the kepair which will be used to encrypt the request.
124 * ping_id is the ping id that will be sent in the request.
125 * client_id is the client id of the node we are searching for.
126 * data_public_key is the public key we want others to encrypt their data packets with.
127 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
128 * receive back in the response.
129 *
130 * return -1 on failure.
131 * return 0 on success.
132 */
133int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_format dest, const uint8_t *public_key,
134 const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key,
135 uint64_t sendback_data)
136{
137 uint8_t packet[ONION_MAX_PACKET_SIZE];
138 int len = create_announce_request(packet, sizeof(packet), path, dest, public_key, secret_key, ping_id, client_id,
139 data_public_key, sendback_data);
140
141 if (len == -1)
142 return -1;
110 143
111 if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet)) 144 if (sendpacket(net, path->ip_port1, packet, len) != len)
112 return -1; 145 return -1;
113 146
114 return send_onion_packet(net, path, dest, packet, sizeof(packet)); 147 return 0;
148}
149
150/* Create and send an onion data request packet.
151 *
152 * path is the path the request will take before it is sent to dest.
153 * (if dest knows the person with the public_key they should
154 * send the packet to that person in the form of a response)
155 *
156 * public_key is the real public key of the node which we want to send the data of length length to.
157 * encrypt_public_key is the public key used to encrypt the data packet.
158 *
159 * nonce is the nonce to encrypt this packet with
160 *
161 * return -1 on failure.
162 * return 0 on success.
163 */
164int send_data_request(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *public_key,
165 const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length)
166{
167 uint8_t packet[ONION_MAX_PACKET_SIZE];
168 int len = create_data_request(packet, sizeof(packet), path, dest, public_key, encrypt_public_key, nonce, data, length);
169
170 if (len == -1)
171 return -1;
172
173 if (sendpacket(net, path->ip_port1, packet, len) != len)
174 return -1;
175
176 return 0;
115} 177}
116 178
117/* Generate a ping_id and put it in ping_id */ 179/* Generate a ping_id and put it in ping_id */
118static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, const uint8_t *public_key, IP_Port ret_ip_port, 180static void generate_ping_id(const Onion_Announce *onion_a, uint64_t time, const uint8_t *public_key,
119 uint8_t *ping_id) 181 IP_Port ret_ip_port, uint8_t *ping_id)
120{ 182{
121 time /= PING_ID_TIMEOUT; 183 time /= PING_ID_TIMEOUT;
122 uint8_t data[crypto_box_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES + sizeof(ret_ip_port)]; 184 uint8_t data[crypto_box_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES + sizeof(ret_ip_port)];
diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h
index ea320998..d31355e5 100644
--- a/toxcore/onion_announce.h
+++ b/toxcore/onion_announce.h
@@ -61,6 +61,42 @@ typedef struct {
61 Shared_Keys shared_keys_recv; 61 Shared_Keys shared_keys_recv;
62} Onion_Announce; 62} Onion_Announce;
63 63
64/* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
65 *
66 * path is the path the request will take before it is sent to dest.
67 *
68 * public_key and secret_key is the kepair which will be used to encrypt the request.
69 * ping_id is the ping id that will be sent in the request.
70 * client_id is the client id of the node we are searching for.
71 * data_public_key is the public key we want others to encrypt their data packets with.
72 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
73 * receive back in the response.
74 *
75 * return -1 on failure.
76 * return packet length on success.
77 */
78int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, Node_format dest,
79 const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
80 const uint8_t *data_public_key, uint64_t sendback_data);
81
82/* Create an onion data request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
83 *
84 * path is the path the request will take before it is sent to dest.
85 * (if dest knows the person with the public_key they should
86 * send the packet to that person in the form of a response)
87 *
88 * public_key is the real public key of the node which we want to send the data of length length to.
89 * encrypt_public_key is the public key used to encrypt the data packet.
90 *
91 * nonce is the nonce to encrypt this packet with
92 *
93 * return -1 on failure.
94 * return 0 on success.
95 */
96int create_data_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
97 const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data,
98 uint16_t length);
99
64/* Create and send an onion announce request packet. 100/* Create and send an onion announce request packet.
65 * 101 *
66 * path is the path the request will take before it is sent to dest. 102 * path is the path the request will take before it is sent to dest.
@@ -75,8 +111,9 @@ typedef struct {
75 * return -1 on failure. 111 * return -1 on failure.
76 * return 0 on success. 112 * return 0 on success.
77 */ 113 */
78int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key, 114int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_format dest, const uint8_t *public_key,
79 uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint64_t sendback_data); 115 const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key,
116 uint64_t sendback_data);
80 117
81/* Create and send an onion data request packet. 118/* Create and send an onion data request packet.
82 * 119 *
@@ -94,8 +131,8 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
94 * return -1 on failure. 131 * return -1 on failure.
95 * return 0 on success. 132 * return 0 on success.
96 */ 133 */
97int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key, 134int send_data_request(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *public_key,
98 uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length); 135 const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length);
99 136
100 137
101Onion_Announce *new_onion_announce(DHT *dht); 138Onion_Announce *new_onion_announce(DHT *dht);
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 644a7c5b..42982ea8 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -38,7 +38,7 @@
38 * return -1 if nodes are suitable for creating a new path. 38 * return -1 if nodes are suitable for creating a new path.
39 * return path number of already existing similar path if one already exists. 39 * return path number of already existing similar path if one already exists.
40 */ 40 */
41static int is_path_used(Onion_Client_Paths *onion_paths, Node_format *nodes) 41static int is_path_used(const Onion_Client_Paths *onion_paths, const Node_format *nodes)
42{ 42{
43 uint32_t i; 43 uint32_t i;
44 44
@@ -68,7 +68,7 @@ static int is_path_used(Onion_Client_Paths *onion_paths, Node_format *nodes)
68 * TODO: Make this function better, it currently probably is vulnerable to some attacks that 68 * TODO: Make this function better, it currently probably is vulnerable to some attacks that
69 * could de anonimize us. 69 * could de anonimize us.
70 */ 70 */
71static int random_path(DHT *dht, Onion_Client_Paths *onion_paths, uint32_t pathnum, Onion_Path *path) 71static int random_path(const DHT *dht, Onion_Client_Paths *onion_paths, uint32_t pathnum, Onion_Path *path)
72{ 72{
73 if (pathnum >= NUMBER_ONION_PATHS) 73 if (pathnum >= NUMBER_ONION_PATHS)
74 pathnum = rand() % NUMBER_ONION_PATHS; 74 pathnum = rand() % NUMBER_ONION_PATHS;
@@ -125,6 +125,23 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, IP_Port s
125 return ~0; 125 return ~0;
126} 126}
127 127
128/* Function to send onion packet via TCP and UDP.
129 *
130 * return -1 on failure.
131 * return 0 on success.
132 */
133static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, IP_Port ip_port, const uint8_t *data, uint32_t length)
134{
135 if (ip_port.ip.family == AF_INET || ip_port.ip.family == AF_INET6) {
136 if ((uint32_t)sendpacket(onion_c->net, ip_port, data, length) != length)
137 return -1;
138
139 return 0;
140 } else {
141 return -1; //TODO: TCP
142 }
143}
144
128/* Creates a sendback for use in an announce request. 145/* Creates a sendback for use in an announce request.
129 * 146 *
130 * num is 0 if we used our secret public key for the announce 147 * num is 0 if we used our secret public key for the announce
@@ -140,7 +157,8 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, IP_Port s
140 * return 0 on success 157 * return 0 on success
141 * 158 *
142 */ 159 */
143static int new_sendback(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, uint64_t *sendback) 160static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, IP_Port ip_port,
161 uint64_t *sendback)
144{ 162{
145 uint8_t data[sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port)]; 163 uint8_t data[sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port)];
146 memcpy(data, &num, sizeof(uint32_t)); 164 memcpy(data, &num, sizeof(uint32_t));
@@ -181,8 +199,8 @@ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, u
181 return num; 199 return num;
182} 200}
183 201
184static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_Port dest, uint8_t *dest_pubkey, 202static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_Port dest, const uint8_t *dest_pubkey,
185 uint8_t *ping_id, uint32_t pathnum) 203 const uint8_t *ping_id, uint32_t pathnum)
186{ 204{
187 if (num > onion_c->num_friends) 205 if (num > onion_c->num_friends)
188 return -1; 206 return -1;
@@ -207,16 +225,29 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
207 if (random_path(onion_c->dht, &onion_c->onion_paths, pathnum, &path) == -1) 225 if (random_path(onion_c->dht, &onion_c->onion_paths, pathnum, &path) == -1)
208 return -1; 226 return -1;
209 227
210 return send_announce_request(onion_c->net, &path, dest_node, onion_c->c->self_public_key, 228 uint8_t packet[ONION_MAX_PACKET_SIZE];
211 onion_c->c->self_secret_key, ping_id, 229 int len = create_announce_request(packet, sizeof(packet), &path, dest_node, onion_c->c->self_public_key,
212 onion_c->c->self_public_key, onion_c->temp_public_key, sendback); 230 onion_c->c->self_secret_key, ping_id, onion_c->c->self_public_key, onion_c->temp_public_key, sendback);
231
232 if (len == -1) {
233 return -1;
234 }
235
236 return send_onion_packet_tcp_udp(onion_c, path.ip_port1, packet, len);
213 } else { 237 } else {
214 if (random_path(onion_c->dht, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1) 238 if (random_path(onion_c->dht, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1)
215 return -1; 239 return -1;
216 240
217 return send_announce_request(onion_c->net, &path, dest_node, onion_c->friends_list[num - 1].temp_public_key, 241 uint8_t packet[ONION_MAX_PACKET_SIZE];
218 onion_c->friends_list[num - 1].temp_secret_key, ping_id, 242 int len = create_announce_request(packet, sizeof(packet), &path, dest_node,
219 onion_c->friends_list[num - 1].real_client_id, zero_ping_id, sendback); 243 onion_c->friends_list[num - 1].temp_public_key, onion_c->friends_list[num - 1].temp_secret_key, ping_id,
244 onion_c->friends_list[num - 1].real_client_id, zero_ping_id, sendback);
245
246 if (len == -1) {
247 return -1;
248 }
249
250 return send_onion_packet_tcp_udp(onion_c, path.ip_port1, packet, len);
220 } 251 }
221} 252}
222 253
@@ -249,8 +280,8 @@ static int cmp_entry(const void *a, const void *b)
249 return 0; 280 return 0;
250} 281}
251 282
252static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, 283static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, IP_Port ip_port,
253 uint8_t is_stored, uint8_t *pingid_or_key, IP_Port source) 284 uint8_t is_stored, const uint8_t *pingid_or_key, IP_Port source)
254{ 285{
255 if (num > onion_c->num_friends) 286 if (num > onion_c->num_friends)
256 return -1; 287 return -1;
@@ -308,7 +339,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ
308 return 0; 339 return 0;
309} 340}
310 341
311static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, uint8_t *client_id) 342static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, const uint8_t *client_id)
312{ 343{
313 uint32_t i; 344 uint32_t i;
314 345
@@ -324,7 +355,7 @@ static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, ui
324 return 1; 355 return 1;
325} 356}
326 357
327static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *nodes, uint16_t num_nodes, 358static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_format *nodes, uint16_t num_nodes,
328 IP_Port source) 359 IP_Port source)
329{ 360{
330 if (num > onion_c->num_friends) 361 if (num > onion_c->num_friends)
@@ -578,9 +609,15 @@ int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t *
578 uint32_t good = 0; 609 uint32_t good = 0;
579 610
580 for (i = 0; i < num_good; ++i) { 611 for (i = 0; i < num_good; ++i) {
581 if (send_data_request(onion_c->net, &path[i], list_nodes[good_nodes[i]].ip_port, 612 uint8_t o_packet[ONION_MAX_PACKET_SIZE];
582 onion_c->friends_list[friend_num].real_client_id, list_nodes[good_nodes[i]].data_public_key, nonce, packet, 613 len = create_data_request(o_packet, sizeof(o_packet), &path[i], list_nodes[good_nodes[i]].ip_port,
583 sizeof(packet)) == 0) 614 onion_c->friends_list[friend_num].real_client_id, list_nodes[good_nodes[i]].data_public_key, nonce, packet,
615 sizeof(packet));
616
617 if (len == -1)
618 continue;
619
620 if (send_onion_packet_tcp_udp(onion_c, path[i].ip_port1, o_packet, len) == 0)
584 ++good; 621 ++good;
585 } 622 }
586 623
@@ -594,7 +631,7 @@ int send_onion_data(const Onion_Client *onion_c, int friend_num, const uint8_t *
594 * return the number of packets sent on success 631 * return the number of packets sent on success
595 * return -1 on failure. 632 * return -1 on failure.
596 */ 633 */
597static int send_dht_fakeid(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32_t length) 634static int send_dht_fakeid(const Onion_Client *onion_c, int friend_num, const uint8_t *data, uint32_t length)
598{ 635{
599 if ((uint32_t)friend_num >= onion_c->num_friends) 636 if ((uint32_t)friend_num >= onion_c->num_friends)
600 return -1; 637 return -1;
@@ -657,7 +694,7 @@ static int handle_dht_fakeid(void *object, IP_Port source, const uint8_t *source
657 * return the number of packets sent on success 694 * return the number of packets sent on success
658 * return -1 on failure. 695 * return -1 on failure.
659 */ 696 */
660static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both) 697static int send_fakeid_announce(const Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both)
661{ 698{
662 if (friend_num >= onion_c->num_friends) 699 if (friend_num >= onion_c->num_friends)
663 return -1; 700 return -1;
@@ -794,7 +831,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
794 uint32_t i; 831 uint32_t i;
795 832
796 for (i = onion_c->num_friends; i != 0; --i) { 833 for (i = onion_c->num_friends; i != 0; --i) {
797 if (onion_c->friends_list[i].status != 0) 834 if (onion_c->friends_list[i - 1].status != 0)
798 break; 835 break;
799 } 836 }
800 837
@@ -815,7 +852,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
815 * return 0 on success. 852 * return 0 on success.
816 */ 853 */
817int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object, 854int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object,
818 uint32_t number, IP_Port ip_port, uint8_t *public_key), void *object, uint32_t number) 855 uint32_t number, IP_Port ip_port, const uint8_t *public_key), void *object, uint32_t number)
819{ 856{
820 if ((uint32_t)friend_num >= onion_c->num_friends) 857 if ((uint32_t)friend_num >= onion_c->num_friends)
821 return -1; 858 return -1;
@@ -869,7 +906,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin
869 * return 0 on failure (no key copied). 906 * return 0 on failure (no key copied).
870 * return timestamp on success (key copied). 907 * return timestamp on success (key copied).
871 */ 908 */
872uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key) 909uint64_t onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
873{ 910{
874 if ((uint32_t)friend_num >= onion_c->num_friends) 911 if ((uint32_t)friend_num >= onion_c->num_friends)
875 return 0; 912 return 0;
@@ -891,7 +928,7 @@ uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8
891 * return 1, ip if client_id refers to a friend and we found him 928 * return 1, ip if client_id refers to a friend and we found him
892 * 929 *
893 */ 930 */
894int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port) 931int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
895{ 932{
896 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; 933 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES];
897 934
@@ -965,7 +1002,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
965 if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) { 1002 if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) {
966 Node_format nodes_list[MAX_SENT_NODES]; 1003 Node_format nodes_list[MAX_SENT_NODES];
967 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[friendnum].real_client_id, nodes_list, 1004 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[friendnum].real_client_id, nodes_list,
968 rand() % 2 ? AF_INET : AF_INET6, 1, 0); 1005 (rand() % 2) ? AF_INET : AF_INET6, 1, 0);
969 1006
970 for (i = 0; i < num_nodes; ++i) 1007 for (i = 0; i < num_nodes; ++i)
971 client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0, ~0); 1008 client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0, ~0);
@@ -1047,7 +1084,7 @@ static void do_announce(Onion_Client *onion_c)
1047 if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) { 1084 if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) {
1048 Node_format nodes_list[MAX_SENT_NODES]; 1085 Node_format nodes_list[MAX_SENT_NODES];
1049 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->c->self_public_key, nodes_list, 1086 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->c->self_public_key, nodes_list,
1050 rand() % 2 ? AF_INET : AF_INET6, 1, 0); 1087 (rand() % 2) ? AF_INET : AF_INET6, 1, 0);
1051 1088
1052 for (i = 0; i < num_nodes; ++i) { 1089 for (i = 0; i < num_nodes; ++i) {
1053 client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0, ~0); 1090 client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0, ~0);
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index a74783f6..bf891e7a 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -97,7 +97,7 @@ typedef struct {
97 Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; 97 Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
98 uint8_t last_pinged_index; 98 uint8_t last_pinged_index;
99 99
100 int (*tcp_relay_node_callback)(void *object, uint32_t number, IP_Port ip_port, uint8_t *public_key); 100 int (*tcp_relay_node_callback)(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key);
101 void *tcp_relay_node_callback_object; 101 void *tcp_relay_node_callback_object;
102 uint32_t tcp_relay_node_callback_number; 102 uint32_t tcp_relay_node_callback_number;
103} Onion_Friend; 103} Onion_Friend;
@@ -171,7 +171,7 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
171 * return 1, ip if client_id refers to a friend and we found him 171 * return 1, ip if client_id refers to a friend and we found him
172 * 172 *
173 */ 173 */
174int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); 174int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
175 175
176/* Set the function for this friend that will be callbacked with object and number 176/* Set the function for this friend that will be callbacked with object and number
177 * when that friends gives us one of the TCP relays he is connected to. 177 * when that friends gives us one of the TCP relays he is connected to.
@@ -182,7 +182,7 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
182 * return 0 on success. 182 * return 0 on success.
183 */ 183 */
184int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object, 184int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object,
185 uint32_t number, IP_Port ip_port, uint8_t *public_key), void *object, uint32_t number); 185 uint32_t number, IP_Port ip_port, const uint8_t *public_key), void *object, uint32_t number);
186 186
187/* Set a friends DHT public key. 187/* Set a friends DHT public key.
188 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to 188 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
@@ -198,7 +198,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin
198 * return 0 on failure (no key copied). 198 * return 0 on failure (no key copied).
199 * return timestamp on success (key copied). 199 * return timestamp on success (key copied).
200 */ 200 */
201uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key); 201uint64_t onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
202 202
203#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 203#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
204#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE) 204#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c
index 5c92527e..93dade05 100644
--- a/toxcore/ping_array.c
+++ b/toxcore/ping_array.c
@@ -135,7 +135,7 @@ int ping_array_init(Ping_Array *empty_array, uint32_t size, uint32_t timeout)
135 if (size == 0 || timeout == 0 || empty_array == NULL) 135 if (size == 0 || timeout == 0 || empty_array == NULL)
136 return -1; 136 return -1;
137 137
138 empty_array->entries = calloc(size * sizeof(Ping_Array_Entry), 1); 138 empty_array->entries = calloc(size, sizeof(Ping_Array_Entry));
139 139
140 if (empty_array->entries == NULL) 140 if (empty_array->entries == NULL)
141 return -1; 141 return -1;
diff --git a/toxcore/tox.c b/toxcore/tox.c
index 79e4c042..1b6597ba 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -38,9 +38,9 @@ typedef struct Messenger Tox;
38 * Format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] 38 * Format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
39 * 39 *
40 */ 40 */
41void tox_get_address(Tox *tox, uint8_t *address) 41void tox_get_address(const Tox *tox, uint8_t *address)
42{ 42{
43 Messenger *m = tox; 43 const Messenger *m = tox;
44 getaddress(m, address); 44 getaddress(m, address);
45} 45}
46 46
@@ -61,7 +61,7 @@ void tox_get_address(Tox *tox, uint8_t *address)
61 * (the nospam for that friend was set to the new one). 61 * (the nospam for that friend was set to the new one).
62 * return FAERR_NOMEM if increasing the friend list size fails. 62 * return FAERR_NOMEM if increasing the friend list size fails.
63 */ 63 */
64int32_t tox_add_friend(Tox *tox, uint8_t *address, uint8_t *data, uint16_t length) 64int32_t tox_add_friend(Tox *tox, const uint8_t *address, const uint8_t *data, uint16_t length)
65{ 65{
66 Messenger *m = tox; 66 Messenger *m = tox;
67 return m_addfriend(m, address, data, length); 67 return m_addfriend(m, address, data, length);
@@ -81,9 +81,9 @@ int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *client_id)
81/* return the friend number associated to that client id. 81/* return the friend number associated to that client id.
82 * return -1 if no such friend. 82 * return -1 if no such friend.
83 */ 83 */
84int32_t tox_get_friend_number(Tox *tox, uint8_t *client_id) 84int32_t tox_get_friend_number(const Tox *tox, const uint8_t *client_id)
85{ 85{
86 Messenger *m = tox; 86 const Messenger *m = tox;
87 return getfriend_id(m, client_id); 87 return getfriend_id(m, client_id);
88} 88}
89 89
@@ -93,9 +93,9 @@ int32_t tox_get_friend_number(Tox *tox, uint8_t *client_id)
93 * return 0 if success. 93 * return 0 if success.
94 * return -1 if failure. 94 * return -1 if failure.
95 */ 95 */
96int tox_get_client_id(Tox *tox, int32_t friendnumber, uint8_t *client_id) 96int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *client_id)
97{ 97{
98 Messenger *m = tox; 98 const Messenger *m = tox;
99 return getclient_id(m, friendnumber, client_id); 99 return getclient_id(m, friendnumber, client_id);
100} 100}
101 101
@@ -112,9 +112,9 @@ int tox_del_friend(Tox *tox, int32_t friendnumber)
112 * return 0 if friend is not connected to us (Offline). 112 * return 0 if friend is not connected to us (Offline).
113 * return -1 on failure. 113 * return -1 on failure.
114 */ 114 */
115int tox_get_friend_connection_status(Tox *tox, int32_t friendnumber) 115int tox_get_friend_connection_status(const Tox *tox, int32_t friendnumber)
116{ 116{
117 Messenger *m = tox; 117 const Messenger *m = tox;
118 return m_get_friend_connectionstatus(m, friendnumber); 118 return m_get_friend_connectionstatus(m, friendnumber);
119} 119}
120 120
@@ -123,9 +123,9 @@ int tox_get_friend_connection_status(Tox *tox, int32_t friendnumber)
123 * return 1 if friend exists. 123 * return 1 if friend exists.
124 * return 0 if friend doesn't exist. 124 * return 0 if friend doesn't exist.
125 */ 125 */
126int tox_friend_exists(Tox *tox, int32_t friendnumber) 126int tox_friend_exists(const Tox *tox, int32_t friendnumber)
127{ 127{
128 Messenger *m = tox; 128 const Messenger *m = tox;
129 return m_friend_exists(m, friendnumber); 129 return m_friend_exists(m, friendnumber);
130} 130}
131 131
@@ -144,7 +144,8 @@ uint32_t tox_send_message(Tox *tox, int32_t friendnumber, const uint8_t *message
144 return m_sendmessage(m, friendnumber, message, length); 144 return m_sendmessage(m, friendnumber, message, length);
145} 145}
146 146
147uint32_t tox_send_message_withid(Tox *tox, int32_t friendnumber, uint32_t theid, uint8_t *message, uint32_t length) 147uint32_t tox_send_message_withid(Tox *tox, int32_t friendnumber, uint32_t theid, const uint8_t *message,
148 uint32_t length)
148{ 149{
149 Messenger *m = tox; 150 Messenger *m = tox;
150 return m_sendmessage_withid(m, friendnumber, theid, message, length); 151 return m_sendmessage_withid(m, friendnumber, theid, message, length);
@@ -160,13 +161,13 @@ uint32_t tox_send_message_withid(Tox *tox, int32_t friendnumber, uint32_t theid,
160 * m_sendaction_withid will send an action message with the id of your choosing, 161 * m_sendaction_withid will send an action message with the id of your choosing,
161 * however we can generate an id for you by calling plain m_sendaction. 162 * however we can generate an id for you by calling plain m_sendaction.
162 */ 163 */
163uint32_t tox_send_action(Tox *tox, int32_t friendnumber, uint8_t *action, uint32_t length) 164uint32_t tox_send_action(Tox *tox, int32_t friendnumber, const uint8_t *action, uint32_t length)
164{ 165{
165 Messenger *m = tox; 166 Messenger *m = tox;
166 return m_sendaction(m, friendnumber, action, length); 167 return m_sendaction(m, friendnumber, action, length);
167} 168}
168 169
169uint32_t tox_send_action_withid(Tox *tox, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length) 170uint32_t tox_send_action_withid(Tox *tox, int32_t friendnumber, uint32_t theid, const uint8_t *action, uint32_t length)
170{ 171{
171 Messenger *m = tox; 172 Messenger *m = tox;
172 return m_sendaction_withid(m, friendnumber, theid, action, length); 173 return m_sendaction_withid(m, friendnumber, theid, action, length);
@@ -180,7 +181,7 @@ uint32_t tox_send_action_withid(Tox *tox, int32_t friendnumber, uint32_t theid,
180 * return 0 if success. 181 * return 0 if success.
181 * return -1 if failure. 182 * return -1 if failure.
182 */ 183 */
183int tox_set_name(Tox *tox, uint8_t *name, uint16_t length) 184int tox_set_name(Tox *tox, const uint8_t *name, uint16_t length)
184{ 185{
185 Messenger *m = tox; 186 Messenger *m = tox;
186 return setname(m, name, length); 187 return setname(m, name, length);
@@ -193,9 +194,9 @@ int tox_set_name(Tox *tox, uint8_t *name, uint16_t length)
193 * return length of the name. 194 * return length of the name.
194 * return 0 on error. 195 * return 0 on error.
195 */ 196 */
196uint16_t tox_get_self_name(Tox *tox, uint8_t *name) 197uint16_t tox_get_self_name(const Tox *tox, uint8_t *name)
197{ 198{
198 Messenger *m = tox; 199 const Messenger *m = tox;
199 return getself_name(m, name); 200 return getself_name(m, name);
200} 201}
201 202
@@ -205,24 +206,24 @@ uint16_t tox_get_self_name(Tox *tox, uint8_t *name)
205 * return length of name (with the NULL terminator) if success. 206 * return length of name (with the NULL terminator) if success.
206 * return -1 if failure. 207 * return -1 if failure.
207 */ 208 */
208int tox_get_name(Tox *tox, int32_t friendnumber, uint8_t *name) 209int tox_get_name(const Tox *tox, int32_t friendnumber, uint8_t *name)
209{ 210{
210 Messenger *m = tox; 211 const Messenger *m = tox;
211 return getname(m, friendnumber, name); 212 return getname(m, friendnumber, name);
212} 213}
213 214
214/* returns the length of name on success. 215/* returns the length of name on success.
215 * returns -1 on failure. 216 * returns -1 on failure.
216 */ 217 */
217int tox_get_name_size(Tox *tox, int32_t friendnumber) 218int tox_get_name_size(const Tox *tox, int32_t friendnumber)
218{ 219{
219 Messenger *m = tox; 220 const Messenger *m = tox;
220 return m_get_name_size(m, friendnumber); 221 return m_get_name_size(m, friendnumber);
221} 222}
222 223
223int tox_get_self_name_size(Tox *tox) 224int tox_get_self_name_size(const Tox *tox)
224{ 225{
225 Messenger *m = tox; 226 const Messenger *m = tox;
226 return m_get_self_name_size(m); 227 return m_get_self_name_size(m);
227} 228}
228 229
@@ -231,7 +232,7 @@ int tox_get_self_name_size(Tox *tox)
231 * 232 *
232 * return 0 on success, -1 on failure. 233 * return 0 on success, -1 on failure.
233 */ 234 */
234int tox_set_status_message(Tox *tox, uint8_t *status, uint16_t length) 235int tox_set_status_message(Tox *tox, const uint8_t *status, uint16_t length)
235{ 236{
236 Messenger *m = tox; 237 Messenger *m = tox;
237 return m_set_statusmessage(m, status, length); 238 return m_set_statusmessage(m, status, length);
@@ -246,15 +247,15 @@ int tox_set_user_status(Tox *tox, uint8_t status)
246/* returns the length of status message on success. 247/* returns the length of status message on success.
247 * returns -1 on failure. 248 * returns -1 on failure.
248 */ 249 */
249int tox_get_status_message_size(Tox *tox, int32_t friendnumber) 250int tox_get_status_message_size(const Tox *tox, int32_t friendnumber)
250{ 251{
251 Messenger *m = tox; 252 const Messenger *m = tox;
252 return m_get_statusmessage_size(m, friendnumber); 253 return m_get_statusmessage_size(m, friendnumber);
253} 254}
254 255
255int tox_get_self_status_message_size(Tox *tox) 256int tox_get_self_status_message_size(const Tox *tox)
256{ 257{
257 Messenger *m = tox; 258 const Messenger *m = tox;
258 return m_get_self_statusmessage_size(m); 259 return m_get_self_statusmessage_size(m);
259} 260}
260 261
@@ -262,15 +263,15 @@ int tox_get_self_status_message_size(Tox *tox)
262 * Get the size you need to allocate from m_get_statusmessage_size. 263 * Get the size you need to allocate from m_get_statusmessage_size.
263 * The self variant will copy our own status message. 264 * The self variant will copy our own status message.
264 */ 265 */
265int tox_get_status_message(Tox *tox, int32_t friendnumber, uint8_t *buf, uint32_t maxlen) 266int tox_get_status_message(const Tox *tox, int32_t friendnumber, uint8_t *buf, uint32_t maxlen)
266{ 267{
267 Messenger *m = tox; 268 const Messenger *m = tox;
268 return m_copy_statusmessage(m, friendnumber, buf, maxlen); 269 return m_copy_statusmessage(m, friendnumber, buf, maxlen);
269} 270}
270 271
271int tox_get_self_status_message(Tox *tox, uint8_t *buf, uint32_t maxlen) 272int tox_get_self_status_message(const Tox *tox, uint8_t *buf, uint32_t maxlen)
272{ 273{
273 Messenger *m = tox; 274 const Messenger *m = tox;
274 return m_copy_self_statusmessage(m, buf, maxlen); 275 return m_copy_self_statusmessage(m, buf, maxlen);
275} 276}
276 277
@@ -279,24 +280,24 @@ int tox_get_self_status_message(Tox *tox, uint8_t *buf, uint32_t maxlen)
279 * As above, the self variant will return our own USERSTATUS. 280 * As above, the self variant will return our own USERSTATUS.
280 * If friendnumber is invalid, this shall return USERSTATUS_INVALID. 281 * If friendnumber is invalid, this shall return USERSTATUS_INVALID.
281 */ 282 */
282uint8_t tox_get_user_status(Tox *tox, int32_t friendnumber) 283uint8_t tox_get_user_status(const Tox *tox, int32_t friendnumber)
283{ 284{
284 Messenger *m = tox; 285 const Messenger *m = tox;
285 return m_get_userstatus(m, friendnumber); 286 return m_get_userstatus(m, friendnumber);
286} 287}
287 288
288uint8_t tox_get_self_user_status(Tox *tox) 289uint8_t tox_get_self_user_status(const Tox *tox)
289{ 290{
290 Messenger *m = tox; 291 const Messenger *m = tox;
291 return m_get_self_userstatus(m); 292 return m_get_self_userstatus(m);
292} 293}
293 294
294/* returns timestamp of last time friendnumber was seen online, or 0 if never seen. 295/* returns timestamp of last time friendnumber was seen online, or 0 if never seen.
295 * returns -1 on error. 296 * returns -1 on error.
296 */ 297 */
297uint64_t tox_get_last_online(Tox *tox, int32_t friendnumber) 298uint64_t tox_get_last_online(const Tox *tox, int32_t friendnumber)
298{ 299{
299 Messenger *m = tox; 300 const Messenger *m = tox;
300 return m_get_last_online(m, friendnumber); 301 return m_get_last_online(m, friendnumber);
301} 302}
302 303
@@ -317,9 +318,9 @@ int tox_set_user_is_typing(Tox *tox, int32_t friendnumber, uint8_t is_typing)
317 * returns 0 if friend is not typing. 318 * returns 0 if friend is not typing.
318 * returns 1 if friend is typing. 319 * returns 1 if friend is typing.
319 */ 320 */
320uint8_t tox_get_is_typing(Tox *tox, int32_t friendnumber) 321uint8_t tox_get_is_typing(const Tox *tox, int32_t friendnumber)
321{ 322{
322 Messenger *m = tox; 323 const Messenger *m = tox;
323 return m_get_istyping(m, friendnumber); 324 return m_get_istyping(m, friendnumber);
324} 325}
325 326
@@ -335,16 +336,16 @@ void tox_set_sends_receipts(Tox *tox, int32_t friendnumber, int yesno)
335/* Return the number of friends in the instance m. 336/* Return the number of friends in the instance m.
336 * You should use this to determine how much memory to allocate 337 * You should use this to determine how much memory to allocate
337 * for copy_friendlist. */ 338 * for copy_friendlist. */
338uint32_t tox_count_friendlist(Tox *tox) 339uint32_t tox_count_friendlist(const Tox *tox)
339{ 340{
340 Messenger *m = tox; 341 const Messenger *m = tox;
341 return count_friendlist(m); 342 return count_friendlist(m);
342} 343}
343 344
344/* Return the number of online friends in the instance m. */ 345/* Return the number of online friends in the instance m. */
345uint32_t tox_get_num_online_friends(Tox *tox) 346uint32_t tox_get_num_online_friends(const Tox *tox)
346{ 347{
347 Messenger *m = tox; 348 const Messenger *m = tox;
348 return get_num_online_friends(m); 349 return get_num_online_friends(m);
349} 350}
350 351
@@ -353,9 +354,9 @@ uint32_t tox_get_num_online_friends(Tox *tox)
353 * Otherwise, returns the number of elements copied. 354 * Otherwise, returns the number of elements copied.
354 * If the array was too small, the contents 355 * If the array was too small, the contents
355 * of out_list will be truncated to list_size. */ 356 * of out_list will be truncated to list_size. */
356uint32_t tox_get_friendlist(Tox *tox, int32_t *out_list, uint32_t list_size) 357uint32_t tox_get_friendlist(const Tox *tox, int32_t *out_list, uint32_t list_size)
357{ 358{
358 Messenger *m = tox; 359 const Messenger *m = tox;
359 return copy_friendlist(m, out_list, list_size); 360 return copy_friendlist(m, out_list, list_size);
360} 361}
361 362
@@ -373,7 +374,7 @@ void tox_callback_friend_request(Tox *tox, void (*function)(Tox *tox, const uint
373/* Set the function that will be executed when a message from a friend is received. 374/* Set the function that will be executed when a message from a friend is received.
374 * Function format is: function(int32_t friendnumber, uint8_t * message, uint32_t length) 375 * Function format is: function(int32_t friendnumber, uint8_t * message, uint32_t length)
375 */ 376 */
376void tox_callback_friend_message(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, uint16_t, void *), 377void tox_callback_friend_message(Tox *tox, void (*function)(Messenger *tox, int32_t, const uint8_t *, uint16_t, void *),
377 void *userdata) 378 void *userdata)
378{ 379{
379 Messenger *m = tox; 380 Messenger *m = tox;
@@ -383,7 +384,7 @@ void tox_callback_friend_message(Tox *tox, void (*function)(Messenger *tox, int3
383/* Set the function that will be executed when an action from a friend is received. 384/* Set the function that will be executed when an action from a friend is received.
384 * function format is: function(int32_t friendnumber, uint8_t * action, uint32_t length) 385 * function format is: function(int32_t friendnumber, uint8_t * action, uint32_t length)
385 */ 386 */
386void tox_callback_friend_action(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, uint16_t, void *), 387void tox_callback_friend_action(Tox *tox, void (*function)(Messenger *tox, int32_t, const uint8_t *, uint16_t, void *),
387 void *userdata) 388 void *userdata)
388{ 389{
389 Messenger *m = tox; 390 Messenger *m = tox;
@@ -394,7 +395,7 @@ void tox_callback_friend_action(Tox *tox, void (*function)(Messenger *tox, int32
394 * function(int32_t friendnumber, uint8_t *newname, uint16_t length) 395 * function(int32_t friendnumber, uint8_t *newname, uint16_t length)
395 * You are not responsible for freeing newname. 396 * You are not responsible for freeing newname.
396 */ 397 */
397void tox_callback_name_change(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, uint16_t, void *), 398void tox_callback_name_change(Tox *tox, void (*function)(Messenger *tox, int32_t, const uint8_t *, uint16_t, void *),
398 void *userdata) 399 void *userdata)
399{ 400{
400 Messenger *m = tox; 401 Messenger *m = tox;
@@ -405,7 +406,7 @@ void tox_callback_name_change(Tox *tox, void (*function)(Messenger *tox, int32_t
405 * function(int32_t friendnumber, uint8_t *newstatus, uint16_t length) 406 * function(int32_t friendnumber, uint8_t *newstatus, uint16_t length)
406 * You are not responsible for freeing newstatus. 407 * You are not responsible for freeing newstatus.
407 */ 408 */
408void tox_callback_status_message(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, uint16_t, void *), 409void tox_callback_status_message(Tox *tox, void (*function)(Messenger *tox, int32_t, const uint8_t *, uint16_t, void *),
409 void *userdata) 410 void *userdata)
410{ 411{
411 Messenger *m = tox; 412 Messenger *m = tox;
@@ -468,9 +469,9 @@ void tox_callback_connection_status(Tox *tox, void (*function)(Messenger *tox, i
468 469
469/* Functions to get/set the nospam part of the id. 470/* Functions to get/set the nospam part of the id.
470 */ 471 */
471uint32_t tox_get_nospam(Tox *tox) 472uint32_t tox_get_nospam(const Tox *tox)
472{ 473{
473 Messenger *m = tox; 474 const Messenger *m = tox;
474 return get_nospam(&(m->fr)); 475 return get_nospam(&(m->fr));
475} 476}
476 477
@@ -486,7 +487,8 @@ void tox_set_nospam(Tox *tox, uint32_t nospam)
486 * 487 *
487 * Function(Tox *tox, int32_t friendnumber, uint8_t *group_public_key, void *userdata) 488 * Function(Tox *tox, int32_t friendnumber, uint8_t *group_public_key, void *userdata)
488 */ 489 */
489void tox_callback_group_invite(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, void *), void *userdata) 490void tox_callback_group_invite(Tox *tox, void (*function)(Messenger *tox, int32_t, const uint8_t *, void *),
491 void *userdata)
490{ 492{
491 Messenger *m = tox; 493 Messenger *m = tox;
492 m_callback_group_invite(m, function, userdata); 494 m_callback_group_invite(m, function, userdata);
@@ -496,7 +498,7 @@ void tox_callback_group_invite(Tox *tox, void (*function)(Messenger *tox, int32_
496 * 498 *
497 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) 499 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
498 */ 500 */
499void tox_callback_group_message(Tox *tox, void (*function)(Messenger *tox, int, int, uint8_t *, uint16_t, void *), 501void tox_callback_group_message(Tox *tox, void (*function)(Messenger *tox, int, int, const uint8_t *, uint16_t, void *),
500 void *userdata) 502 void *userdata)
501{ 503{
502 Messenger *m = tox; 504 Messenger *m = tox;
@@ -507,7 +509,7 @@ void tox_callback_group_message(Tox *tox, void (*function)(Messenger *tox, int,
507 * 509 *
508 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * action, uint16_t length, void *userdata) 510 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * action, uint16_t length, void *userdata)
509 */ 511 */
510void tox_callback_group_action(Tox *tox, void (*function)(Messenger *tox, int, int, uint8_t *, uint16_t, void *), 512void tox_callback_group_action(Tox *tox, void (*function)(Messenger *tox, int, int, const uint8_t *, uint16_t, void *),
511 void *userdata) 513 void *userdata)
512{ 514{
513 Messenger *m = tox; 515 Messenger *m = tox;
@@ -552,9 +554,9 @@ int tox_del_groupchat(Tox *tox, int groupnumber)
552 * return length of name if success 554 * return length of name if success
553 * return -1 if failure 555 * return -1 if failure
554 */ 556 */
555int tox_group_peername(Tox *tox, int groupnumber, int peernumber, uint8_t *name) 557int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t *name)
556{ 558{
557 Messenger *m = tox; 559 const Messenger *m = tox;
558 return m_group_peername(m, groupnumber, peernumber, name); 560 return m_group_peername(m, groupnumber, peernumber, name);
559} 561}
560/* invite friendnumber to groupnumber 562/* invite friendnumber to groupnumber
@@ -571,7 +573,7 @@ int tox_invite_friend(Tox *tox, int32_t friendnumber, int groupnumber)
571 * returns group number on success 573 * returns group number on success
572 * returns -1 on failure. 574 * returns -1 on failure.
573 */ 575 */
574int tox_join_groupchat(Tox *tox, int32_t friendnumber, uint8_t *friend_group_public_key) 576int tox_join_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *friend_group_public_key)
575{ 577{
576 Messenger *m = tox; 578 Messenger *m = tox;
577 return join_groupchat(m, friendnumber, friend_group_public_key); 579 return join_groupchat(m, friendnumber, friend_group_public_key);
@@ -581,7 +583,7 @@ int tox_join_groupchat(Tox *tox, int32_t friendnumber, uint8_t *friend_group_pub
581 * return 0 on success 583 * return 0 on success
582 * return -1 on failure 584 * return -1 on failure
583 */ 585 */
584int tox_group_message_send(Tox *tox, int groupnumber, uint8_t *message, uint32_t length) 586int tox_group_message_send(Tox *tox, int groupnumber, const uint8_t *message, uint32_t length)
585{ 587{
586 Messenger *m = tox; 588 Messenger *m = tox;
587 return group_message_send(m, groupnumber, message, length); 589 return group_message_send(m, groupnumber, message, length);
@@ -591,7 +593,7 @@ int tox_group_message_send(Tox *tox, int groupnumber, uint8_t *message, uint32_t
591 * return 0 on success 593 * return 0 on success
592 * return -1 on failure 594 * return -1 on failure
593 */ 595 */
594int tox_group_action_send(Tox *tox, int groupnumber, uint8_t *action, uint32_t length) 596int tox_group_action_send(Tox *tox, int groupnumber, const uint8_t *action, uint32_t length)
595{ 597{
596 Messenger *m = tox; 598 Messenger *m = tox;
597 return group_action_send(m, groupnumber, action, length); 599 return group_action_send(m, groupnumber, action, length);
@@ -600,9 +602,9 @@ int tox_group_action_send(Tox *tox, int groupnumber, uint8_t *action, uint32_t l
600/* Return the number of peers in the group chat on success. 602/* Return the number of peers in the group chat on success.
601 * return -1 on failure 603 * return -1 on failure
602 */ 604 */
603int tox_group_number_peers(Tox *tox, int groupnumber) 605int tox_group_number_peers(const Tox *tox, int groupnumber)
604{ 606{
605 Messenger *m = tox; 607 const Messenger *m = tox;
606 return group_number_peers(m, groupnumber); 608 return group_number_peers(m, groupnumber);
607} 609}
608 610
@@ -616,19 +618,19 @@ int tox_group_number_peers(Tox *tox, int groupnumber)
616 * 618 *
617 * return -1 on failure. 619 * return -1 on failure.
618 */ 620 */
619int tox_group_get_names(Tox *tox, int groupnumber, uint8_t names[][TOX_MAX_NAME_LENGTH], uint16_t lengths[], 621int tox_group_get_names(const Tox *tox, int groupnumber, uint8_t names[][TOX_MAX_NAME_LENGTH], uint16_t lengths[],
620 uint16_t length) 622 uint16_t length)
621{ 623{
622 Messenger *m = tox; 624 const Messenger *m = tox;
623 return group_names(m, groupnumber, names, lengths, length); 625 return group_names(m, groupnumber, names, lengths, length);
624} 626}
625 627
626/* Return the number of chats in the instance m. 628/* Return the number of chats in the instance m.
627 * You should use this to determine how much memory to allocate 629 * You should use this to determine how much memory to allocate
628 * for copy_chatlist. */ 630 * for copy_chatlist. */
629uint32_t tox_count_chatlist(Tox *tox) 631uint32_t tox_count_chatlist(const Tox *tox)
630{ 632{
631 Messenger *m = tox; 633 const Messenger *m = tox;
632 return count_chatlist(m); 634 return count_chatlist(m);
633} 635}
634 636
@@ -637,9 +639,9 @@ uint32_t tox_count_chatlist(Tox *tox)
637 * Otherwise, returns the number of elements copied. 639 * Otherwise, returns the number of elements copied.
638 * If the array was too small, the contents 640 * If the array was too small, the contents
639 * of out_list will be truncated to list_size. */ 641 * of out_list will be truncated to list_size. */
640uint32_t tox_get_chatlist(Tox *tox, int *out_list, uint32_t list_size) 642uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size)
641{ 643{
642 Messenger *m = tox; 644 const Messenger *m = tox;
643 return copy_chatlist(m, out_list, list_size); 645 return copy_chatlist(m, out_list, list_size);
644} 646}
645 647
@@ -651,9 +653,8 @@ uint32_t tox_get_chatlist(Tox *tox, int *out_list, uint32_t list_size)
651 * 653 *
652 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata) 654 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata)
653 */ 655 */
654void tox_callback_file_send_request(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t, uint64_t, uint8_t *, 656void tox_callback_file_send_request(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t, uint64_t,
655 uint16_t, 657 const uint8_t *, uint16_t, void *), void *userdata)
656 void *), void *userdata)
657{ 658{
658 Messenger *m = tox; 659 Messenger *m = tox;
659 callback_file_sendrequest(m, function, userdata); 660 callback_file_sendrequest(m, function, userdata);
@@ -663,8 +664,8 @@ void tox_callback_file_send_request(Tox *tox, void (*function)(Messenger *tox, i
663 * Function(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata) 664 * Function(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata)
664 * 665 *
665 */ 666 */
666void tox_callback_file_control(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, 667void tox_callback_file_control(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t, uint8_t, uint8_t,
667 uint16_t, void *), void *userdata) 668 const uint8_t *, uint16_t, void *), void *userdata)
668{ 669{
669 Messenger *m = tox; 670 Messenger *m = tox;
670 callback_file_control(m, function, userdata); 671 callback_file_control(m, function, userdata);
@@ -674,9 +675,8 @@ void tox_callback_file_control(Tox *tox, void (*function)(Messenger *tox, int32_
674 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) 675 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata)
675 * 676 *
676 */ 677 */
677void tox_callback_file_data(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t, uint8_t *, uint16_t length, 678void tox_callback_file_data(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t, const uint8_t *,
678 void *), 679 uint16_t length, void *), void *userdata)
679 void *userdata)
680 680
681{ 681{
682 Messenger *m = tox; 682 Messenger *m = tox;
@@ -687,7 +687,8 @@ void tox_callback_file_data(Tox *tox, void (*function)(Messenger *tox, int32_t,
687 * return file number on success 687 * return file number on success
688 * return -1 on failure 688 * return -1 on failure
689 */ 689 */
690int tox_new_file_sender(Tox *tox, int32_t friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length) 690int tox_new_file_sender(Tox *tox, int32_t friendnumber, uint64_t filesize, const uint8_t *filename,
691 uint16_t filename_length)
691{ 692{
692 Messenger *m = tox; 693 Messenger *m = tox;
693 return new_filesender(m, friendnumber, filesize, filename, filename_length); 694 return new_filesender(m, friendnumber, filesize, filename, filename_length);
@@ -699,7 +700,7 @@ int tox_new_file_sender(Tox *tox, int32_t friendnumber, uint64_t filesize, uint8
699 * return -1 on failure 700 * return -1 on failure
700 */ 701 */
701int tox_file_send_control(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, 702int tox_file_send_control(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id,
702 uint8_t *data, uint16_t length) 703 const uint8_t *data, uint16_t length)
703{ 704{
704 Messenger *m = tox; 705 Messenger *m = tox;
705 return file_control(m, friendnumber, send_receive, filenumber, message_id, data, length); 706 return file_control(m, friendnumber, send_receive, filenumber, message_id, data, length);
@@ -709,7 +710,7 @@ int tox_file_send_control(Tox *tox, int32_t friendnumber, uint8_t send_receive,
709 * return 0 on success 710 * return 0 on success
710 * return -1 on failure 711 * return -1 on failure
711 */ 712 */
712int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length) 713int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length)
713{ 714{
714 Messenger *m = tox; 715 Messenger *m = tox;
715 return file_data(m, friendnumber, filenumber, data, length); 716 return file_data(m, friendnumber, filenumber, data, length);
@@ -720,7 +721,7 @@ int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8
720 * return size on success 721 * return size on success
721 * return -1 on failure (currently will never return -1) 722 * return -1 on failure (currently will never return -1)
722 */ 723 */
723int tox_file_data_size(Tox *tox, int32_t friendnumber) 724int tox_file_data_size(const Tox *tox, int32_t friendnumber)
724{ 725{
725 return MAX_CRYPTO_DATA_SIZE - 2; 726 return MAX_CRYPTO_DATA_SIZE - 2;
726} 727}
@@ -732,16 +733,17 @@ int tox_file_data_size(Tox *tox, int32_t friendnumber)
732 * return number of bytes remaining to be sent/received on success 733 * return number of bytes remaining to be sent/received on success
733 * return 0 on failure 734 * return 0 on failure
734 */ 735 */
735uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive) 736uint64_t tox_file_data_remaining(const Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive)
736{ 737{
737 Messenger *m = tox; 738 const Messenger *m = tox;
738 return file_dataremaining(m, friendnumber, filenumber, send_receive); 739 return file_dataremaining(m, friendnumber, filenumber, send_receive);
739} 740}
740 741
741/***************END OF FILE SENDING FUNCTIONS******************/ 742/***************END OF FILE SENDING FUNCTIONS******************/
742 743
743/* TODO: expose this properly. */ 744/* TODO: expose this properly. */
744static int tox_add_tcp_relay(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) 745static int tox_add_tcp_relay(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port,
746 const uint8_t *public_key)
745{ 747{
746 Messenger *m = tox; 748 Messenger *m = tox;
747 IP_Port ip_port_v64; 749 IP_Port ip_port_v64;
@@ -766,7 +768,7 @@ static int tox_add_tcp_relay(Tox *tox, const char *address, uint8_t ipv6enabled,
766} 768}
767 769
768int tox_bootstrap_from_address(Tox *tox, const char *address, 770int tox_bootstrap_from_address(Tox *tox, const char *address,
769 uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) 771 uint8_t ipv6enabled, uint16_t port, const uint8_t *public_key)
770{ 772{
771 Messenger *m = tox; 773 Messenger *m = tox;
772 tox_add_tcp_relay(tox, address, ipv6enabled, port, public_key); 774 tox_add_tcp_relay(tox, address, ipv6enabled, port, public_key);
@@ -776,9 +778,9 @@ int tox_bootstrap_from_address(Tox *tox, const char *address,
776/* return 0 if we are not connected to the DHT. 778/* return 0 if we are not connected to the DHT.
777 * return 1 if we are. 779 * return 1 if we are.
778 */ 780 */
779int tox_isconnected(Tox *tox) 781int tox_isconnected(const Tox *tox)
780{ 782{
781 Messenger *m = tox; 783 const Messenger *m = tox;
782 return DHT_isconnected(m->dht); 784 return DHT_isconnected(m->dht);
783} 785}
784 786
@@ -823,21 +825,21 @@ void tox_do(Tox *tox)
823/* SAVING AND LOADING FUNCTIONS: */ 825/* SAVING AND LOADING FUNCTIONS: */
824 826
825/* return size of the messenger data (for saving). */ 827/* return size of the messenger data (for saving). */
826uint32_t tox_size(Tox *tox) 828uint32_t tox_size(const Tox *tox)
827{ 829{
828 Messenger *m = tox; 830 const Messenger *m = tox;
829 return messenger_size(m); 831 return messenger_size(m);
830} 832}
831 833
832/* Save the messenger in data (must be allocated memory of size Messenger_size()). */ 834/* Save the messenger in data (must be allocated memory of size Messenger_size()). */
833void tox_save(Tox *tox, uint8_t *data) 835void tox_save(const Tox *tox, uint8_t *data)
834{ 836{
835 Messenger *m = tox; 837 const Messenger *m = tox;
836 messenger_save(m, data); 838 messenger_save(m, data);
837} 839}
838 840
839/* Load the messenger from data of size length. */ 841/* Load the messenger from data of size length. */
840int tox_load(Tox *tox, uint8_t *data, uint32_t length) 842int tox_load(Tox *tox, const uint8_t *data, uint32_t length)
841{ 843{
842 Messenger *m = tox; 844 Messenger *m = tox;
843 return messenger_load(m, data, length); 845 return messenger_load(m, data, length);
diff --git a/toxcore/tox.h b/toxcore/tox.h
index afa502f5..d931b9be 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -82,7 +82,7 @@ typedef struct Tox Tox;
82/* return TOX_FRIEND_ADDRESS_SIZE byte address to give to others. 82/* return TOX_FRIEND_ADDRESS_SIZE byte address to give to others.
83 * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] 83 * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
84 */ 84 */
85void tox_get_address(Tox *tox, uint8_t *address); 85void tox_get_address(const Tox *tox, uint8_t *address);
86 86
87/* Add a friend. 87/* Add a friend.
88 * Set the data that will be sent along with friend request. 88 * Set the data that will be sent along with friend request.
@@ -90,7 +90,7 @@ void tox_get_address(Tox *tox, uint8_t *address);
90 * data is the data and length is the length. 90 * data is the data and length is the length.
91 * 91 *
92 * return the friend number if success. 92 * return the friend number if success.
93 * return TOX_FA_TOOLONG if message length is too long. 93 * return TOX_FAERR_TOOLONG if message length is too long.
94 * return TOX_FAERR_NOMESSAGE if no message (message length must be >= 1 byte). 94 * return TOX_FAERR_NOMESSAGE if no message (message length must be >= 1 byte).
95 * return TOX_FAERR_OWNKEY if user's own key. 95 * return TOX_FAERR_OWNKEY if user's own key.
96 * return TOX_FAERR_ALREADYSENT if friend request already sent or already a friend. 96 * return TOX_FAERR_ALREADYSENT if friend request already sent or already a friend.
@@ -100,7 +100,7 @@ void tox_get_address(Tox *tox, uint8_t *address);
100 * (the nospam for that friend was set to the new one). 100 * (the nospam for that friend was set to the new one).
101 * return TOX_FAERR_NOMEM if increasing the friend list size fails. 101 * return TOX_FAERR_NOMEM if increasing the friend list size fails.
102 */ 102 */
103int32_t tox_add_friend(Tox *tox, uint8_t *address, uint8_t *data, uint16_t length); 103int32_t tox_add_friend(Tox *tox, const uint8_t *address, const uint8_t *data, uint16_t length);
104 104
105 105
106/* Add a friend without sending a friendrequest. 106/* Add a friend without sending a friendrequest.
@@ -111,14 +111,14 @@ int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *client_id);
111 111
112/* return the friend number associated to that client id. 112/* return the friend number associated to that client id.
113 return -1 if no such friend */ 113 return -1 if no such friend */
114int32_t tox_get_friend_number(Tox *tox, uint8_t *client_id); 114int32_t tox_get_friend_number(const Tox *tox, const uint8_t *client_id);
115 115
116/* Copies the public key associated to that friend id into client_id buffer. 116/* Copies the public key associated to that friend id into client_id buffer.
117 * Make sure that client_id is of size CLIENT_ID_SIZE. 117 * Make sure that client_id is of size CLIENT_ID_SIZE.
118 * return 0 if success. 118 * return 0 if success.
119 * return -1 if failure. 119 * return -1 if failure.
120 */ 120 */
121int tox_get_client_id(Tox *tox, int32_t friendnumber, uint8_t *client_id); 121int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *client_id);
122 122
123/* Remove a friend. 123/* Remove a friend.
124 * 124 *
@@ -133,14 +133,14 @@ int tox_del_friend(Tox *tox, int32_t friendnumber);
133 * return 0 if friend is not connected to us (Offline). 133 * return 0 if friend is not connected to us (Offline).
134 * return -1 on failure. 134 * return -1 on failure.
135 */ 135 */
136int tox_get_friend_connection_status(Tox *tox, int32_t friendnumber); 136int tox_get_friend_connection_status(const Tox *tox, int32_t friendnumber);
137 137
138/* Checks if there exists a friend with given friendnumber. 138/* Checks if there exists a friend with given friendnumber.
139 * 139 *
140 * return 1 if friend exists. 140 * return 1 if friend exists.
141 * return 0 if friend doesn't exist. 141 * return 0 if friend doesn't exist.
142 */ 142 */
143int tox_friend_exists(Tox *tox, int32_t friendnumber); 143int tox_friend_exists(const Tox *tox, int32_t friendnumber);
144 144
145/* Send a text chat message to an online friend. 145/* Send a text chat message to an online friend.
146 * 146 *
@@ -157,7 +157,8 @@ int tox_friend_exists(Tox *tox, int32_t friendnumber);
157 * however we can generate an id for you by calling plain m_sendmessage. 157 * however we can generate an id for you by calling plain m_sendmessage.
158 */ 158 */
159uint32_t tox_send_message(Tox *tox, int32_t friendnumber, const uint8_t *message, uint32_t length); 159uint32_t tox_send_message(Tox *tox, int32_t friendnumber, const uint8_t *message, uint32_t length);
160uint32_t tox_send_message_withid(Tox *tox, int32_t friendnumber, uint32_t theid, uint8_t *message, uint32_t length); 160uint32_t tox_send_message_withid(Tox *tox, int32_t friendnumber, uint32_t theid, const uint8_t *message,
161 uint32_t length);
161 162
162/* Send an action to an online friend. 163/* Send an action to an online friend.
163 * 164 *
@@ -173,8 +174,8 @@ uint32_t tox_send_message_withid(Tox *tox, int32_t friendnumber, uint32_t theid,
173 * m_sendaction_withid will send an action message with the id of your choosing, 174 * m_sendaction_withid will send an action message with the id of your choosing,
174 * however we can generate an id for you by calling plain m_sendaction. 175 * however we can generate an id for you by calling plain m_sendaction.
175 */ 176 */
176uint32_t tox_send_action(Tox *tox, int32_t friendnumber, uint8_t *action, uint32_t length); 177uint32_t tox_send_action(Tox *tox, int32_t friendnumber, const uint8_t *action, uint32_t length);
177uint32_t tox_send_action_withid(Tox *tox, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length); 178uint32_t tox_send_action_withid(Tox *tox, int32_t friendnumber, uint32_t theid, const uint8_t *action, uint32_t length);
178 179
179/* Set our nickname. 180/* Set our nickname.
180 * name must be a string of maximum MAX_NAME_LENGTH length. 181 * name must be a string of maximum MAX_NAME_LENGTH length.
@@ -184,7 +185,7 @@ uint32_t tox_send_action_withid(Tox *tox, int32_t friendnumber, uint32_t theid,
184 * return 0 if success. 185 * return 0 if success.
185 * return -1 if failure. 186 * return -1 if failure.
186 */ 187 */
187int tox_set_name(Tox *tox, uint8_t *name, uint16_t length); 188int tox_set_name(Tox *tox, const uint8_t *name, uint16_t length);
188 189
189/* 190/*
190 * Get your nickname. 191 * Get your nickname.
@@ -194,7 +195,7 @@ int tox_set_name(Tox *tox, uint8_t *name, uint16_t length);
194 * return length of name. 195 * return length of name.
195 * return 0 on error. 196 * return 0 on error.
196 */ 197 */
197uint16_t tox_get_self_name(Tox *tox, uint8_t *name); 198uint16_t tox_get_self_name(const Tox *tox, uint8_t *name);
198 199
199/* Get name of friendnumber and put it in name. 200/* Get name of friendnumber and put it in name.
200 * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. 201 * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
@@ -202,13 +203,13 @@ uint16_t tox_get_self_name(Tox *tox, uint8_t *name);
202 * return length of name if success. 203 * return length of name if success.
203 * return -1 if failure. 204 * return -1 if failure.
204 */ 205 */
205int tox_get_name(Tox *tox, int32_t friendnumber, uint8_t *name); 206int tox_get_name(const Tox *tox, int32_t friendnumber, uint8_t *name);
206 207
207/* returns the length of name on success. 208/* returns the length of name on success.
208 * returns -1 on failure. 209 * returns -1 on failure.
209 */ 210 */
210int tox_get_name_size(Tox *tox, int32_t friendnumber); 211int tox_get_name_size(const Tox *tox, int32_t friendnumber);
211int tox_get_self_name_size(Tox *tox); 212int tox_get_self_name_size(const Tox *tox);
212 213
213/* Set our user status. 214/* Set our user status.
214 * 215 *
@@ -218,14 +219,14 @@ int tox_get_self_name_size(Tox *tox);
218 * returns 0 on success. 219 * returns 0 on success.
219 * returns -1 on failure. 220 * returns -1 on failure.
220 */ 221 */
221int tox_set_status_message(Tox *tox, uint8_t *status, uint16_t length); 222int tox_set_status_message(Tox *tox, const uint8_t *status, uint16_t length);
222int tox_set_user_status(Tox *tox, uint8_t userstatus); 223int tox_set_user_status(Tox *tox, uint8_t userstatus);
223 224
224/* returns the length of status message on success. 225/* returns the length of status message on success.
225 * returns -1 on failure. 226 * returns -1 on failure.
226 */ 227 */
227int tox_get_status_message_size(Tox *tox, int32_t friendnumber); 228int tox_get_status_message_size(const Tox *tox, int32_t friendnumber);
228int tox_get_self_status_message_size(Tox *tox); 229int tox_get_self_status_message_size(const Tox *tox);
229 230
230/* Copy friendnumber's status message into buf, truncating if size is over maxlen. 231/* Copy friendnumber's status message into buf, truncating if size is over maxlen.
231 * Get the size you need to allocate from m_get_statusmessage_size. 232 * Get the size you need to allocate from m_get_statusmessage_size.
@@ -234,22 +235,22 @@ int tox_get_self_status_message_size(Tox *tox);
234 * returns the length of the copied data on success 235 * returns the length of the copied data on success
235 * retruns -1 on failure. 236 * retruns -1 on failure.
236 */ 237 */
237int tox_get_status_message(Tox *tox, int32_t friendnumber, uint8_t *buf, uint32_t maxlen); 238int tox_get_status_message(const Tox *tox, int32_t friendnumber, uint8_t *buf, uint32_t maxlen);
238int tox_get_self_status_message(Tox *tox, uint8_t *buf, uint32_t maxlen); 239int tox_get_self_status_message(const Tox *tox, uint8_t *buf, uint32_t maxlen);
239 240
240/* return one of TOX_USERSTATUS values. 241/* return one of TOX_USERSTATUS values.
241 * Values unknown to your application should be represented as TOX_USERSTATUS_NONE. 242 * Values unknown to your application should be represented as TOX_USERSTATUS_NONE.
242 * As above, the self variant will return our own TOX_USERSTATUS. 243 * As above, the self variant will return our own TOX_USERSTATUS.
243 * If friendnumber is invalid, this shall return TOX_USERSTATUS_INVALID. 244 * If friendnumber is invalid, this shall return TOX_USERSTATUS_INVALID.
244 */ 245 */
245uint8_t tox_get_user_status(Tox *tox, int32_t friendnumber); 246uint8_t tox_get_user_status(const Tox *tox, int32_t friendnumber);
246uint8_t tox_get_self_user_status(Tox *tox); 247uint8_t tox_get_self_user_status(const Tox *tox);
247 248
248 249
249/* returns timestamp of last time friendnumber was seen online, or 0 if never seen. 250/* returns timestamp of last time friendnumber was seen online, or 0 if never seen.
250 * returns -1 on error. 251 * returns -1 on error.
251 */ 252 */
252uint64_t tox_get_last_online(Tox *tox, int32_t friendnumber); 253uint64_t tox_get_last_online(const Tox *tox, int32_t friendnumber);
253 254
254/* Set our typing status for a friend. 255/* Set our typing status for a friend.
255 * You are responsible for turning it on or off. 256 * You are responsible for turning it on or off.
@@ -264,7 +265,7 @@ int tox_set_user_is_typing(Tox *tox, int32_t friendnumber, uint8_t is_typing);
264 * returns 0 if friend is not typing. 265 * returns 0 if friend is not typing.
265 * returns 1 if friend is typing. 266 * returns 1 if friend is typing.
266 */ 267 */
267uint8_t tox_get_is_typing(Tox *tox, int32_t friendnumber); 268uint8_t tox_get_is_typing(const Tox *tox, int32_t friendnumber);
268 269
269/* Sets whether we send read receipts for friendnumber. 270/* Sets whether we send read receipts for friendnumber.
270 * This function is not lazy, and it will fail if yesno is not (0 or 1). 271 * This function is not lazy, and it will fail if yesno is not (0 or 1).
@@ -274,17 +275,17 @@ void tox_set_sends_receipts(Tox *tox, int32_t friendnumber, int yesno);
274/* Return the number of friends in the instance m. 275/* Return the number of friends in the instance m.
275 * You should use this to determine how much memory to allocate 276 * You should use this to determine how much memory to allocate
276 * for copy_friendlist. */ 277 * for copy_friendlist. */
277uint32_t tox_count_friendlist(Tox *tox); 278uint32_t tox_count_friendlist(const Tox *tox);
278 279
279/* Return the number of online friends in the instance m. */ 280/* Return the number of online friends in the instance m. */
280uint32_t tox_get_num_online_friends(Tox *tox); 281uint32_t tox_get_num_online_friends(const Tox *tox);
281 282
282/* Copy a list of valid friend IDs into the array out_list. 283/* Copy a list of valid friend IDs into the array out_list.
283 * If out_list is NULL, returns 0. 284 * If out_list is NULL, returns 0.
284 * Otherwise, returns the number of elements copied. 285 * Otherwise, returns the number of elements copied.
285 * If the array was too small, the contents 286 * If the array was too small, the contents
286 * of out_list will be truncated to list_size. */ 287 * of out_list will be truncated to list_size. */
287uint32_t tox_get_friendlist(Tox *tox, int32_t *out_list, uint32_t list_size); 288uint32_t tox_get_friendlist(const Tox *tox, int32_t *out_list, uint32_t list_size);
288 289
289/* Set the function that will be executed when a friend request is received. 290/* Set the function that will be executed when a friend request is received.
290 * Function format is function(Tox *tox, uint8_t * public_key, uint8_t * data, uint16_t length, void *userdata) 291 * Function format is function(Tox *tox, uint8_t * public_key, uint8_t * data, uint16_t length, void *userdata)
@@ -295,27 +296,27 @@ void tox_callback_friend_request(Tox *tox, void (*function)(Tox *tox, const uint
295/* Set the function that will be executed when a message from a friend is received. 296/* Set the function that will be executed when a message from a friend is received.
296 * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * message, uint32_t length, void *userdata) 297 * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * message, uint32_t length, void *userdata)
297 */ 298 */
298void tox_callback_friend_message(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, uint16_t, void *), 299void tox_callback_friend_message(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *),
299 void *userdata); 300 void *userdata);
300 301
301/* Set the function that will be executed when an action from a friend is received. 302/* Set the function that will be executed when an action from a friend is received.
302 * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * action, uint32_t length, void *userdata) 303 * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * action, uint32_t length, void *userdata)
303 */ 304 */
304void tox_callback_friend_action(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, uint16_t, void *), 305void tox_callback_friend_action(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *),
305 void *userdata); 306 void *userdata);
306 307
307/* Set the callback for name changes. 308/* Set the callback for name changes.
308 * function(Tox *tox, int32_t friendnumber, uint8_t *newname, uint16_t length, void *userdata) 309 * function(Tox *tox, int32_t friendnumber, uint8_t *newname, uint16_t length, void *userdata)
309 * You are not responsible for freeing newname 310 * You are not responsible for freeing newname
310 */ 311 */
311void tox_callback_name_change(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, uint16_t, void *), 312void tox_callback_name_change(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *),
312 void *userdata); 313 void *userdata);
313 314
314/* Set the callback for status message changes. 315/* Set the callback for status message changes.
315 * function(Tox *tox, int32_t friendnumber, uint8_t *newstatus, uint16_t length, void *userdata) 316 * function(Tox *tox, int32_t friendnumber, uint8_t *newstatus, uint16_t length, void *userdata)
316 * You are not responsible for freeing newstatus. 317 * You are not responsible for freeing newstatus.
317 */ 318 */
318void tox_callback_status_message(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, uint16_t, void *), 319void tox_callback_status_message(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *),
319 void *userdata); 320 void *userdata);
320 321
321/* Set the callback for status type changes. 322/* Set the callback for status type changes.
@@ -357,7 +358,7 @@ void tox_callback_connection_status(Tox *tox, void (*function)(Tox *tox, int32_t
357 358
358/* Functions to get/set the nospam part of the id. 359/* Functions to get/set the nospam part of the id.
359 */ 360 */
360uint32_t tox_get_nospam(Tox *tox); 361uint32_t tox_get_nospam(const Tox *tox);
361void tox_set_nospam(Tox *tox, uint32_t nospam); 362void tox_set_nospam(Tox *tox, uint32_t nospam);
362 363
363 364
@@ -367,20 +368,20 @@ void tox_set_nospam(Tox *tox, uint32_t nospam);
367 * 368 *
368 * Function(Tox *tox, int friendnumber, uint8_t *group_public_key, void *userdata) 369 * Function(Tox *tox, int friendnumber, uint8_t *group_public_key, void *userdata)
369 */ 370 */
370void tox_callback_group_invite(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, void *), void *userdata); 371void tox_callback_group_invite(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, void *), void *userdata);
371 372
372/* Set the callback for group messages. 373/* Set the callback for group messages.
373 * 374 *
374 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) 375 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
375 */ 376 */
376void tox_callback_group_message(Tox *tox, void (*function)(Tox *tox, int, int, uint8_t *, uint16_t, void *), 377void tox_callback_group_message(Tox *tox, void (*function)(Tox *tox, int, int, const uint8_t *, uint16_t, void *),
377 void *userdata); 378 void *userdata);
378 379
379/* Set the callback for group actions. 380/* Set the callback for group actions.
380 * 381 *
381 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * action, uint16_t length, void *userdata) 382 * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * action, uint16_t length, void *userdata)
382 */ 383 */
383void tox_callback_group_action(Tox *tox, void (*function)(Tox *tox, int, int, uint8_t *, uint16_t, void *), 384void tox_callback_group_action(Tox *tox, void (*function)(Tox *tox, int, int, const uint8_t *, uint16_t, void *),
384 void *userdata); 385 void *userdata);
385 386
386/* Set callback function for peer name list changes. 387/* Set callback function for peer name list changes.
@@ -417,7 +418,7 @@ int tox_del_groupchat(Tox *tox, int groupnumber);
417 * return length of name if success 418 * return length of name if success
418 * return -1 if failure 419 * return -1 if failure
419 */ 420 */
420int tox_group_peername(Tox *tox, int groupnumber, int peernumber, uint8_t *name); 421int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t *name);
421 422
422/* invite friendnumber to groupnumber 423/* invite friendnumber to groupnumber
423 * return 0 on success 424 * return 0 on success
@@ -430,24 +431,24 @@ int tox_invite_friend(Tox *tox, int32_t friendnumber, int groupnumber);
430 * returns group number on success 431 * returns group number on success
431 * returns -1 on failure. 432 * returns -1 on failure.
432 */ 433 */
433int tox_join_groupchat(Tox *tox, int32_t friendnumber, uint8_t *friend_group_public_key); 434int tox_join_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *friend_group_public_key);
434 435
435/* send a group message 436/* send a group message
436 * return 0 on success 437 * return 0 on success
437 * return -1 on failure 438 * return -1 on failure
438 */ 439 */
439int tox_group_message_send(Tox *tox, int groupnumber, uint8_t *message, uint32_t length); 440int tox_group_message_send(Tox *tox, int groupnumber, const uint8_t *message, uint32_t length);
440 441
441/* send a group action 442/* send a group action
442 * return 0 on success 443 * return 0 on success
443 * return -1 on failure 444 * return -1 on failure
444 */ 445 */
445int tox_group_action_send(Tox *tox, int groupnumber, uint8_t *action, uint32_t length); 446int tox_group_action_send(Tox *tox, int groupnumber, const uint8_t *action, uint32_t length);
446 447
447/* Return the number of peers in the group chat on success. 448/* Return the number of peers in the group chat on success.
448 * return -1 on failure 449 * return -1 on failure
449 */ 450 */
450int tox_group_number_peers(Tox *tox, int groupnumber); 451int tox_group_number_peers(const Tox *tox, int groupnumber);
451 452
452/* List all the peers in the group chat. 453/* List all the peers in the group chat.
453 * 454 *
@@ -459,20 +460,20 @@ int tox_group_number_peers(Tox *tox, int groupnumber);
459 * 460 *
460 * return -1 on failure. 461 * return -1 on failure.
461 */ 462 */
462int tox_group_get_names(Tox *tox, int groupnumber, uint8_t names[][TOX_MAX_NAME_LENGTH], uint16_t lengths[], 463int tox_group_get_names(const Tox *tox, int groupnumber, uint8_t names[][TOX_MAX_NAME_LENGTH], uint16_t lengths[],
463 uint16_t length); 464 uint16_t length);
464 465
465/* Return the number of chats in the instance m. 466/* Return the number of chats in the instance m.
466 * You should use this to determine how much memory to allocate 467 * You should use this to determine how much memory to allocate
467 * for copy_chatlist. */ 468 * for copy_chatlist. */
468uint32_t tox_count_chatlist(Tox *tox); 469uint32_t tox_count_chatlist(const Tox *tox);
469 470
470/* Copy a list of valid chat IDs into the array out_list. 471/* Copy a list of valid chat IDs into the array out_list.
471 * If out_list is NULL, returns 0. 472 * If out_list is NULL, returns 0.
472 * Otherwise, returns the number of elements copied. 473 * Otherwise, returns the number of elements copied.
473 * If the array was too small, the contents 474 * If the array was too small, the contents
474 * of out_list will be truncated to list_size. */ 475 * of out_list will be truncated to list_size. */
475uint32_t tox_get_chatlist(Tox *tox, int *out_list, uint32_t list_size); 476uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size);
476 477
477 478
478/****************FILE SENDING FUNCTIONS*****************/ 479/****************FILE SENDING FUNCTIONS*****************/
@@ -523,8 +524,8 @@ enum {
523 * 524 *
524 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata) 525 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata)
525 */ 526 */
526void tox_callback_file_send_request(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint64_t, uint8_t *, uint16_t, 527void tox_callback_file_send_request(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint64_t, const uint8_t *,
527 void *), void *userdata); 528 uint16_t, void *), void *userdata);
528 529
529/* Set the callback for file control requests. 530/* Set the callback for file control requests.
530 * 531 *
@@ -534,7 +535,7 @@ void tox_callback_file_send_request(Tox *tox, void (*function)(Tox *m, int32_t,
534 * Function(Tox *tox, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata) 535 * Function(Tox *tox, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata)
535 * 536 *
536 */ 537 */
537void tox_callback_file_control(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, 538void tox_callback_file_control(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint8_t, uint8_t, const uint8_t *,
538 uint16_t, void *), void *userdata); 539 uint16_t, void *), void *userdata);
539 540
540/* Set the callback for file data. 541/* Set the callback for file data.
@@ -542,8 +543,8 @@ void tox_callback_file_control(Tox *tox, void (*function)(Tox *m, int32_t, uint8
542 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) 543 * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata)
543 * 544 *
544 */ 545 */
545void tox_callback_file_data(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint8_t *, uint16_t length, void *), 546void tox_callback_file_data(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, const uint8_t *, uint16_t length,
546 void *userdata); 547 void *), void *userdata);
547 548
548 549
549/* Send a file send request. 550/* Send a file send request.
@@ -551,7 +552,8 @@ void tox_callback_file_data(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t,
551 * return file number on success 552 * return file number on success
552 * return -1 on failure 553 * return -1 on failure
553 */ 554 */
554int tox_new_file_sender(Tox *tox, int32_t friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length); 555int tox_new_file_sender(Tox *tox, int32_t friendnumber, uint64_t filesize, const uint8_t *filename,
556 uint16_t filename_length);
555 557
556/* Send a file control request. 558/* Send a file control request.
557 * 559 *
@@ -562,21 +564,21 @@ int tox_new_file_sender(Tox *tox, int32_t friendnumber, uint64_t filesize, uint8
562 * return -1 on failure 564 * return -1 on failure
563 */ 565 */
564int tox_file_send_control(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, 566int tox_file_send_control(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id,
565 uint8_t *data, uint16_t length); 567 const uint8_t *data, uint16_t length);
566 568
567/* Send file data. 569/* Send file data.
568 * 570 *
569 * return 0 on success 571 * return 0 on success
570 * return -1 on failure 572 * return -1 on failure
571 */ 573 */
572int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length); 574int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length);
573 575
574/* Returns the recommended/maximum size of the filedata you send with tox_file_send_data() 576/* Returns the recommended/maximum size of the filedata you send with tox_file_send_data()
575 * 577 *
576 * return size on success 578 * return size on success
577 * return -1 on failure (currently will never return -1) 579 * return -1 on failure (currently will never return -1)
578 */ 580 */
579int tox_file_data_size(Tox *tox, int32_t friendnumber); 581int tox_file_data_size(const Tox *tox, int32_t friendnumber);
580 582
581/* Give the number of bytes left to be sent/received. 583/* Give the number of bytes left to be sent/received.
582 * 584 *
@@ -585,7 +587,7 @@ int tox_file_data_size(Tox *tox, int32_t friendnumber);
585 * return number of bytes remaining to be sent/received on success 587 * return number of bytes remaining to be sent/received on success
586 * return 0 on failure 588 * return 0 on failure
587 */ 589 */
588uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive); 590uint64_t tox_file_data_remaining(const Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive);
589 591
590/***************END OF FILE SENDING FUNCTIONS******************/ 592/***************END OF FILE SENDING FUNCTIONS******************/
591 593
@@ -606,12 +608,12 @@ uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenum
606 * returns 0 otherwise 608 * returns 0 otherwise
607 */ 609 */
608int tox_bootstrap_from_address(Tox *tox, const char *address, uint8_t ipv6enabled, 610int tox_bootstrap_from_address(Tox *tox, const char *address, uint8_t ipv6enabled,
609 uint16_t port, uint8_t *public_key); 611 uint16_t port, const uint8_t *public_key);
610 612
611/* return 0 if we are not connected to the DHT. 613/* return 0 if we are not connected to the DHT.
612 * return 1 if we are. 614 * return 1 if we are.
613 */ 615 */
614int tox_isconnected(Tox *tox); 616int tox_isconnected(const Tox *tox);
615 617
616/* 618/*
617 * Run this function at startup. 619 * Run this function at startup.
@@ -645,17 +647,17 @@ void tox_do(Tox *tox);
645/* SAVING AND LOADING FUNCTIONS: */ 647/* SAVING AND LOADING FUNCTIONS: */
646 648
647/* return size of messenger data (for saving). */ 649/* return size of messenger data (for saving). */
648uint32_t tox_size(Tox *tox); 650uint32_t tox_size(const Tox *tox);
649 651
650/* Save the messenger in data (must be allocated memory of size Messenger_size()). */ 652/* Save the messenger in data (must be allocated memory of size Messenger_size()). */
651void tox_save(Tox *tox, uint8_t *data); 653void tox_save(const Tox *tox, uint8_t *data);
652 654
653/* Load the messenger from data of size length. 655/* Load the messenger from data of size length.
654 * 656 *
655 * returns 0 on success 657 * returns 0 on success
656 * returns -1 on failure 658 * returns -1 on failure
657 */ 659 */
658int tox_load(Tox *tox, uint8_t *data, uint32_t length); 660int tox_load(Tox *tox, const uint8_t *data, uint32_t length);
659 661
660#ifdef __cplusplus 662#ifdef __cplusplus
661} 663}
diff --git a/toxdns/toxdns.c b/toxdns/toxdns.c
index 79d2adbb..7a7a052d 100644
--- a/toxdns/toxdns.c
+++ b/toxdns/toxdns.c
@@ -26,6 +26,7 @@
26#endif 26#endif
27 27
28#include "../toxcore/Messenger.h" 28#include "../toxcore/Messenger.h"
29#include "../toxcore/logger.h"
29#include "toxdns.h" 30#include "toxdns.h"
30 31
31static const char base32[32] = {"abcdefghijklmnopqrstuvwxyz012345"}; 32static const char base32[32] = {"abcdefghijklmnopqrstuvwxyz012345"};
@@ -143,7 +144,7 @@ int tox_generate_dns3_string(void *dns3_object, uint8_t *string, uint16_t string
143 } 144 }
144 145
145 if (end_len != string - old_str) { 146 if (end_len != string - old_str) {
146 printf("tox_generate_dns3_string Fail, %u != %u\n", end_len, string - old_str); 147 LOGGER_ERROR("tox_generate_dns3_string Fail, %u != %lu\n", end_len, string - old_str);
147 return -1; 148 return -1;
148 } 149 }
149 150
@@ -216,8 +217,11 @@ int tox_decrypt_dns3_TXT(void *dns3_object, uint8_t *tox_id, uint8_t *id_record,
216 /*if (id_record_len > 255 || id_record_len <= (sizeof(uint32_t) + crypto_box_MACBYTES)) 217 /*if (id_record_len > 255 || id_record_len <= (sizeof(uint32_t) + crypto_box_MACBYTES))
217 return -1;*/ 218 return -1;*/
218 219
220 uint8_t id_record_null[id_record_len + 1];
221 memcpy(id_record_null, id_record, id_record_len);
222 id_record_null[id_record_len] = 0;
219 uint8_t data[id_record_len]; 223 uint8_t data[id_record_len];
220 int length = decode(data, id_record); 224 int length = decode(data, id_record_null);
221 225
222 if (length == -1) 226 if (length == -1)
223 return -1; 227 return -1;