diff options
51 files changed, 2476 insertions, 2106 deletions
@@ -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 | |||
45 | On FreeBSD 10+: | 49 | On FreeBSD 10+: |
46 | 50 | ||
47 | ```tcsh | 51 | ```tcsh |
48 | pkg install automake autoconf | 52 | pkg install net-im/tox |
49 | ``` | 53 | ``` |
54 | Note, if you install from ports select NaCl for performance, and sodium if you want it to be portable. | ||
50 | 55 | ||
51 | You should get and install [libsodium](https://github.com/jedisct1/libsodium): | 56 | You should get and install [libsodium](https://github.com/jedisct1/libsodium): |
52 | ```bash | 57 | ```bash |
53 | git clone git://github.com/jedisct1/libsodium.git | 58 | git clone git://github.com/jedisct1/libsodium.git |
54 | cd libsodium | 59 | cd libsodium |
55 | git checkout tags/0.4.2 | 60 | git checkout tags/0.5.0 |
56 | ./autogen.sh | 61 | ./autogen.sh |
57 | ./configure && make check | 62 | ./configure && make check |
58 | sudo checkinstall --install --pkgname libsodium --pkgversion 0.4.2 --nodoc | 63 | sudo checkinstall --install --pkgname libsodium --pkgversion 0.5.0 --nodoc |
59 | sudo ldconfig | 64 | sudo ldconfig |
60 | cd .. | 65 | cd .. |
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 |
68 | git clone git://github.com/jedisct1/libsodium.git | 73 | git clone git://github.com/jedisct1/libsodium.git |
69 | cd libsodium | 74 | cd libsodium |
70 | git checkout tags/0.4.2 | 75 | git checkout tags/0.5.0 |
71 | ./autogen.sh | 76 | ./autogen.sh |
72 | ./configure | 77 | ./configure |
73 | make check | 78 | make 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 | |||
158 | You must install yasm before installing libvpx, otherwise libvpx will fail to make correctly. | ||
159 | |||
160 | pkg-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 | ||
149 | Uncompress and install them all. Make sure to follow the README as the instructions change, but they all follow the same pattern below: | 162 | Uncompress 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 | |||
154 | sudo make install | 167 | sudo make install |
155 | ``` | 168 | ``` |
156 | 169 | ||
157 | In your local TOX repository: | 170 | Compiling and installing Tox Core |
158 | 171 | ||
159 | Then generate makefile, build and install tox: | ||
160 | ```bash | 172 | ```bash |
161 | cd ProjectTox-Core | 173 | cd ProjectTox-Core |
162 | autoreconf -i | 174 | autoreconf -i |
@@ -165,36 +177,210 @@ make | |||
165 | make install | 177 | make install |
166 | ``` | 178 | ``` |
167 | 179 | ||
168 | Do not install them from macports (or any dependencies for that matter) as they get shoved in the wrong directory | 180 | If 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 | |||
184 | Ensure you set the locations correctly depending on where you installed libsodium on your computer. | ||
185 | |||
186 | If 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 | ||
171 | Another thing: you may want to install is the latest gcc. This caused me a few problems as XCode from 4.3 | 188 | ``` |
172 | no longer includes gcc and instead uses LLVM-GCC, a nice install guide can be found at | 189 | export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig |
173 | http://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 | |||
199 | It'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 | |||
204 | We will assume that you don't have any VM running Linux around and will guide you from the ground up. | ||
205 | |||
206 | First, you would need to get a virtual machine and a Linux distribution image file. | ||
207 | |||
208 | For a virtual machine we will use VirtualBox. You can get it [here](https://www.virtualbox.org/wiki/Downloads). | ||
209 | |||
210 | For a Linux distribution we will use Lubuntu 14.04 32-bit, which you can get [here](https://help.ubuntu.com/community/Lubuntu/GetLubuntu). | ||
211 | |||
212 | After 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 | |||
214 | When 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 | |||
216 | Then, 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 | |||
218 | Start the VM and follow the installation instructions. | ||
219 | |||
220 | After 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 | |||
222 | Open terminal from **Lubuntu's menu** -> **Accessories**. | ||
223 | |||
224 | Execute: | ||
225 | ```bash | ||
226 | sudo apt-get update | ||
227 | sudo apt-get install build-essential -y | ||
228 | cd /media/*/*/ | ||
229 | sudo ./VBoxLinuxAdditions.run | ||
230 | ``` | ||
231 | |||
232 | After 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 | |||
234 | Execute: | ||
235 | ```bash | ||
236 | sudo adduser `whoami` vboxsf | ||
237 | ``` | ||
238 | Note the use of a [grave accent](http://en.wikipedia.org/wiki/Grave_accent) instead of an apostrophe. | ||
239 | |||
240 | Then just reboot the system with: | ||
241 | ```bash | ||
242 | sudo reboot | ||
243 | ``` | ||
244 | |||
245 | After 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 | |||
247 | Now 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 | |||
252 | First we will install all tools that we would need for building: | ||
253 | ```bash | ||
254 | sudo apt-get install build-essential libtool autotools-dev automake checkinstall check git yasm pkg-config mingw-w64 -y | ||
255 | ``` | ||
256 | |||
257 | Then we will define a few variables, **depending on which you will build either 32-bit or 64-bit Tox**. | ||
258 | |||
259 | For 32-bit Tox build, do: | ||
260 | ```bash | ||
261 | WINDOWS_TOOLCHAIN=i686-w64-mingw32 | ||
262 | LIB_VPX_TARGET=x86-win32-gcc | ||
263 | ``` | ||
264 | |||
265 | For 64-bit Tox build, do: | ||
266 | ```bash | ||
267 | WINDOWS_TOOLCHAIN=x86_64-w64-mingw32 | ||
268 | LIB_VPX_TARGET=x86_64-win64-gcc | ||
269 | ``` | ||
270 | |||
271 | This is the only difference between 32-bit and 64-bit build procedures. | ||
272 | |||
273 | For speeding up the build process do: | ||
274 | ``` | ||
275 | MAKEFLAGS=j$(nproc) | ||
276 | export MAKEFLAGS | ||
277 | ``` | ||
278 | |||
279 | And let's make a folder where we will be building everything at | ||
280 | ```bash | ||
281 | cd ~ | ||
282 | mkdir prefix | ||
283 | cd prefix | ||
284 | PREFIX_DIR=$(pwd) | ||
285 | cd .. | ||
286 | mkdir build | ||
287 | cd build | ||
288 | ``` | ||
289 | |||
290 | <a name="windows-cross-compile-compiling" /> | ||
291 | #####Compiling | ||
292 | |||
293 | Now we will build libraries needed for audio/video: VPX and Opus. | ||
294 | |||
295 | VPX: | ||
296 | ```bash | ||
297 | git clone http://git.chromium.org/webm/libvpx.git | ||
298 | cd libvpx | ||
299 | git checkout tags/v1.3.0 | ||
300 | CROSS="$WINDOWS_TOOLCHAIN"- ./configure --target="$LIB_VPX_TARGET" --prefix="$PREFIX_DIR" --disable-examples --disable-unit-tests --disable-shared --enable-static | ||
301 | make | ||
302 | make install | ||
303 | cd .. | ||
304 | ``` | ||
305 | |||
306 | Opus: | ||
307 | ```bash | ||
308 | wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz | ||
309 | tar -xf opus-1.1.tar.gz | ||
310 | cd opus-1.1 | ||
311 | ./configure --host="$WINDOWS_TOOLCHAIN" --prefix="$PREFIX_DIR" --disable-extra-programs --disable-doc --disable-shared --enable-static | ||
312 | make | ||
313 | make install | ||
314 | cd .. | ||
315 | ``` | ||
316 | |||
317 | Now we will build sodium crypto library: | ||
318 | ```bash | ||
319 | git clone https://github.com/jedisct1/libsodium/ | ||
320 | cd libsodium | ||
321 | git checkout tags/0.4.5 | ||
322 | ./autogen.sh | ||
323 | ./configure --host="$WINDOWS_TOOLCHAIN" --prefix="$PREFIX_DIR" --disable-shared --enable-static | ||
324 | make | ||
325 | make install | ||
326 | cd .. | ||
327 | ``` | ||
328 | |||
329 | And finally we will build Tox: | ||
330 | ```bash | ||
331 | git clone https://github.com/irungentoo/toxcore | ||
332 | cd 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 | ||
335 | make | ||
336 | make install | ||
337 | cd .. | ||
338 | ``` | ||
339 | |||
340 | Then we make Tox shared library: | ||
341 | ```bash | ||
342 | cd "$PREFIX_DIR" | ||
343 | mkdir tmp | ||
344 | cd 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 | |||
351 | And we will copy it over to the `toxbuild` directory: | ||
352 | ```bash | ||
353 | mkdir -p /media/sf_toxbuild/release/lib | ||
354 | mv libtox.dll* /media/sf_toxbuild/release/lib | ||
355 | mkdir -p /media/sf_toxbuild/release/include | ||
356 | mv ../include/tox /media/sf_toxbuild/release/include | ||
357 | ``` | ||
358 | |||
359 | That'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 | |||
364 | Note 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 | |||
178 | You should install: | 366 | You should install: |
179 | - [MinGW](http://sourceforge.net/projects/mingw/) | 367 | - [MinGW](http://sourceforge.net/projects/mingw/) |
180 | 368 | ||
181 | When installing MinGW, make sure to select the MSYS option in the installer. | 369 | When installing MinGW, make sure to select the MSYS option in the installer. |
182 | MinGW will install an "MinGW shell" (you should get a shortcut for it), make | 370 | MinGW 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. |
183 | sure to perform all operations (i.e., generating/running configure script, compiling, etc.) from the MinGW shell. | ||
184 | 371 | ||
185 | First download the source tarball from https://download.libsodium.org/libsodium/releases/ and build it. | 372 | First download the source tarball from https://download.libsodium.org/libsodium/releases/ and build it. |
186 | Assuming that you got the libsodium-0.4.2.tar.gz release: | 373 | Assuming that you got the libsodium-0.5.0.tar.gz release: |
187 | ```cmd | 374 | ```cmd |
188 | tar -zxvf libsodium-0.4.2.tar.gz | 375 | tar -zxvf libsodium-0.5.0.tar.gz |
189 | cd libsodium-0.4.2 | 376 | cd libsodium-0.5.0 |
190 | ./configure | 377 | ./configure |
191 | make | 378 | make |
192 | make install | 379 | make install |
193 | cd .. | 380 | cd .. |
194 | ``` | 381 | ``` |
195 | 382 | ||
196 | You can also use a precompiled win32 binary of libsodium, however you will have | 383 | You 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. |
197 | 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. | ||
198 | 384 | ||
199 | Next, 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. | 385 | Next, 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 |
335 | sudo apt-get install ncurses-dev | 521 | sudo apt-get install ncurses-dev |
336 | ``` | 522 | ``` |
337 | |||
@@ -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 | ||
4 | With 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 /> | 4 | With 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 |
11 | Tox must use UDP simply because [hole punching](http://en.wikipedia.org/wiki/UDP_hole_punching) with TCP is not as reliable. | 11 | Tox must use UDP simply because [hole punching](https://en.wikipedia.org/wiki/UDP_hole_punching) with TCP is not as reliable. |
12 | However, 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. | 12 | However, 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 |
15 | Every 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. | 15 | Every 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 | |||
294 | static int response_callback_good; | 294 | static int response_callback_good; |
295 | static uint8_t response_callback_connection_id; | 295 | static uint8_t response_callback_connection_id; |
296 | static uint8_t response_callback_public_key[crypto_box_PUBLICKEYBYTES]; | 296 | static uint8_t response_callback_public_key[crypto_box_PUBLICKEYBYTES]; |
297 | static int response_callback(void *object, uint8_t connection_id, uint8_t *public_key) | 297 | static 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 | } |
323 | static int data_callback_good; | 323 | static int data_callback_good; |
324 | static int data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length) | 324 | static 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 | ||
343 | static int oob_data_callback_good; | 343 | static int oob_data_callback_good; |
344 | static uint8_t oob_pubkey[crypto_box_PUBLICKEYBYTES]; | 344 | static uint8_t oob_pubkey[crypto_box_PUBLICKEYBYTES]; |
345 | static int oob_data_callback(void *object, uint8_t *public_key, uint8_t *data, uint16_t length) | 345 | static 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 | } |
31 | uint32_t messages_received; | 31 | uint32_t messages_received; |
32 | 32 | ||
33 | void print_message(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) | 33 | void 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 | ||
45 | uint32_t name_changes; | 45 | uint32_t name_changes; |
46 | 46 | ||
47 | void print_nickchange(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) | 47 | void 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 | |||
69 | uint8_t filenum; | 69 | uint8_t filenum; |
70 | uint32_t file_accepted; | 70 | uint32_t file_accepted; |
71 | uint64_t file_size; | 71 | uint64_t file_size; |
72 | void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, | 72 | void 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 | |||
85 | uint32_t file_sent; | 85 | uint32_t file_sent; |
86 | uint32_t sendf_ok; | 86 | uint32_t sendf_ok; |
87 | void file_print_control(Tox *m, int friendnumber, uint8_t send_recieve, uint8_t filenumber, uint8_t control_type, | 87 | void 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 | ||
101 | uint64_t size_recv; | 101 | uint64_t size_recv; |
102 | uint8_t num; | 102 | uint8_t num; |
103 | void write_file(Tox *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) | 103 | void 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 | |||
142 | static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int length) | ||
143 | { | ||
144 | } | ||
145 | |||
146 | static 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 | ||
27 | pthread_mutex_t muhmutex; | ||
27 | 28 | ||
28 | typedef enum _CallStatus { | 29 | typedef 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 | |||
129 | static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int length) | ||
130 | { | ||
131 | } | ||
132 | |||
133 | static 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 | } |
@@ -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 | ||
31 | Friend_requests.c: | 31 | Friend_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 | ||
465 | void print_public_key(uint8_t *public_key) | 478 | void 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 | ||
22 | void print_key(uint8_t *client_id) | 22 | void 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 | |||
46 | void 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 | |||
58 | int 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 | ||
59 | void print_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) | 59 | void 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 | |||
17 | uint32_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 | ||
8 | int main(int argc, char *argv[]) | 45 | int 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 */ |
635 | void wrap(char output[STRING_LENGTH_WRAPPED], char input[STRING_LENGTH], int line_width) | 635 | void 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 | ||
880 | void print_message(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) | 879 | void 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 | ||
887 | void print_nickchange(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) | 888 | void 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 | ||
903 | void print_statuschange(Tox *m, int friendnumber, uint8_t *string, uint16_t length, void *userdata) | 904 | void 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; | |||
921 | static int load_data(Tox *m) | 922 | static 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 | ||
1004 | void print_invite(Tox *m, int friendnumber, uint8_t *group_public_key, void *userdata) | 1004 | void 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 | ||
1060 | void print_groupmessage(Tox *m, int groupnumber, int peernumber, uint8_t *message, uint16_t length, void *userdata) | 1060 | void 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 | } |
1121 | void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, | 1122 | void 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 | ||
1135 | void file_print_control(Tox *m, int friendnumber, uint8_t send_recieve, uint8_t filenumber, uint8_t control_type, | 1136 | void 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 | ||
1151 | void write_file(Tox *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) | 1151 | void 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 | ||
131 | static char path[1024]; | 131 | static char path[1024]; |
132 | 132 | ||
133 | void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, | 133 | void 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 | ||
171 | void file_print_control(Tox *m, int friendnumber, uint8_t recieve_send, uint8_t filenumber, uint8_t control_type, | 171 | void 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 | ||
188 | void write_file(Tox *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) | 188 | void 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 | |||
4 | libtoxav_la_include_HEADERS = ../toxav/toxav.h | 4 | libtoxav_la_include_HEADERS = ../toxav/toxav.h |
5 | libtoxav_la_includedir = $(includedir)/tox | 5 | libtoxav_la_includedir = $(includedir)/tox |
6 | 6 | ||
7 | libtoxav_la_SOURCES = ../toxav/event.h \ | 7 | libtoxav_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 | |||
39 | const uint16_t min_jbuf_size = 4; | ||
40 | const uint16_t min_readiness_idx = 2; /* when is buffer ready to dqq */ | ||
38 | 41 | ||
39 | int empty_queue(JitterBuffer *q) | 42 | int 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 | ||
78 | void terminate_queue(JitterBuffer *q) | 81 | void 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 | ||
213 | int 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 | ||
211 | int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t video_bitrate) | 236 | int 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 | |||
255 | int 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 | ||
299 | void codec_terminate_session ( CodecState *cs ) | 366 | void 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 | |||
386 | inline 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 | |||
396 | int 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 | ||
49 | extern const uint16_t min_jbuf_size; | ||
50 | |||
49 | typedef struct _CodecState { | 51 | typedef 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 | ||
97 | void codec_terminate_session(CodecState *cs); | 106 | void codec_terminate_session(CodecState *cs); |
98 | 107 | ||
99 | #endif | 108 | /* Reconfigure video encoder |
109 | return 0 on success. | ||
110 | return -1 on failure. */ | ||
111 | int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_t height); | ||
112 | int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate); | ||
113 | |||
114 | /* Calculate energy and return 1 if has voice, 0 if not */ | ||
115 | int 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; \ | ||
43 | pthread_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 | |||
53 | typedef struct _EventContainer { | ||
54 | void *(*func)(void *); | ||
55 | void *func_args; | ||
56 | unsigned timeout; | ||
57 | long long id; | ||
58 | |||
59 | } EventContainer; | ||
60 | |||
61 | typedef 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 | |||
71 | int throw_event( void *(func)(void *), void *arg ); | ||
72 | int reset_timer_event ( int id, uint32_t timeout ); | ||
73 | int throw_timer_event ( void *(func)(void *), void *arg, unsigned timeout); | ||
74 | int cancel_timer_event ( int id ); | ||
75 | int execute_timer_event ( int id ); | ||
76 | |||
77 | struct _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 | */ | ||
88 | void clear_events (EventContainer **event_container, size_t *counter) | ||
89 | { | ||
90 | free(*event_container ); | ||
91 | |||
92 | *event_container = NULL; | ||
93 | *counter = 0; | ||
94 | } | ||
95 | |||
96 | int 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 | |||
145 | void 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 | |||
168 | void 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 */ | ||
193 | void *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 | |||
233 | int 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 | |||
242 | EventHandler event_handler; | ||
243 | |||
244 | /* Place and order array of timers */ | ||
245 | int 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 | |||
265 | int 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 | |||
321 | int 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 */ | ||
349 | inline__ 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 | |||
360 | void __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? */ | ||
373 | void __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 | */ | ||
41 | extern 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 ) | |||
86 | GENERIC_HEADER ( CallId ) | 82 | GENERIC_HEADER ( CallId ) |
87 | GENERIC_HEADER ( Info ) | 83 | GENERIC_HEADER ( Info ) |
88 | GENERIC_HEADER ( Reason ) | 84 | GENERIC_HEADER ( Reason ) |
89 | GENERIC_HEADER ( CryptoKey ) | ||
90 | GENERIC_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 { | |||
117 | static struct _Callbacks { | 109 | static struct _Callbacks { |
118 | MSICallback function; | 110 | MSICallback function; |
119 | void *data; | 111 | void *data; |
120 | } callbacks[11] = {0}; | 112 | } callbacks[11] = {{0}}; |
121 | 113 | ||
122 | inline__ void invoke_callback(int32_t call_index, MSICallbackID id) | 114 | inline__ 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 | |||
228 | iterator ++; if(size_con <= 3) {return -1;} size_con -= 3; \ | 217 | iterator ++; if(size_con <= 3) {return -1;} size_con -= 3; \ |
229 | uint16_t _value_size; memcpy(&_value_size, iterator, sizeof(_value_size)); _value_size = ntohs(_value_size);\ | 218 | uint16_t _value_size; memcpy(&_value_size, iterator, sizeof(_value_size)); _value_size = ntohs(_value_size);\ |
230 | if(size_con < _value_size) { return -1; } size_con -= _value_size; \ | 219 | if(size_con < _value_size) { return -1; } size_con -= _value_size; \ |
231 | header.header_value = calloc(sizeof(uint8_t), _value_size); \ | 220 | if ( !(header.header_value = calloc(sizeof(uint8_t), _value_size)) ) \ |
221 | LOGGER_ERROR("Allocation failed! Program might misbehave!"); \ | ||
232 | header.size = _value_size; \ | 222 | header.size = _value_size; \ |
233 | memcpy(header.header_value, iterator + 2, _value_size);\ | 223 | memcpy(header.header_value, iterator + 2, _value_size);\ |
234 | iterator = iterator + 2 + _value_size; /* set iterator at new header or end_byte */ } | 224 | iterator = 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) \ |
319 | var.header_value = calloc(sizeof *mheader_value, t_size); \ | 299 | if (!(var.header_value = calloc(sizeof *mheader_value, t_size))) \ |
320 | if (var.header_value == NULL) { LOGGER_WARNING("Header allocation failed!"); } \ | 300 | { LOGGER_WARNING("Header allocation failed! Program might misbehave!"); } \ |
321 | else { memcpy(var.header_value, mheader_value, t_size); \ | 301 | else { memcpy(var.header_value, mheader_value, t_size); \ |
322 | var.size = t_size; } | 302 | var.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 | */ | ||
434 | int 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) \ |
588 | void msi_msg_set_##header ( MSIMessage* _msg, const uint8_t* header_value, uint16_t _size ) \ | 527 | void 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 ) | |||
594 | GENERIC_SETTER_DEFINITION ( reason ) | 533 | GENERIC_SETTER_DEFINITION ( reason ) |
595 | GENERIC_SETTER_DEFINITION ( info ) | 534 | GENERIC_SETTER_DEFINITION ( info ) |
596 | GENERIC_SETTER_DEFINITION ( callid ) | 535 | GENERIC_SETTER_DEFINITION ( callid ) |
597 | GENERIC_SETTER_DEFINITION ( cryptokey ) | ||
598 | GENERIC_SETTER_DEFINITION ( nonce ) | ||
599 | 536 | ||
600 | 537 | ||
538 | |||
539 | |||
540 | typedef 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 | |||
549 | typedef 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 | |||
561 | struct 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 | */ | ||
575 | int 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 | */ | ||
632 | int 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 | */ | ||
682 | void *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 | */ | ||
729 | TimerHandler *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 | */ | ||
771 | void 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 | */ |
608 | void t_randomstr ( uint8_t *str, size_t size ) | 796 | void 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 | ||
628 | typedef enum { | 816 | typedef 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 | */ |
733 | int call_id_bigger( const uint8_t *first, const uint8_t *second) | 914 | int 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 | */ |
823 | int handle_error ( MSISession *session, MSICall *call, MSICallError errid, uint32_t to ) | 1002 | int 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 | */ | ||
858 | int 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 | */ |
883 | void add_peer( MSICall *call, int peer_id ) | 1036 | void 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 | } |
1121 | int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *msg ) | 1275 | int 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 | } |
1153 | int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *msg ) | 1295 | int 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 | } |
1181 | int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *msg ) | 1318 | int 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 | } |
1204 | int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg ) | 1337 | int 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 **********/ |
1228 | int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg ) | 1361 | int 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 | } |
1246 | int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg ) | 1386 | int 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 | } |
1295 | int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg ) | 1412 | int 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 | */ |
1379 | void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16_t length, void *object ) | 1496 | void 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 | ||
1478 | free_end: | 1594 | free_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 | 31 | void 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 | */ | ||
83 | inline__ 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 | */ | ||
119 | static 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 ) | |||
321 | RTPHeader *build_header ( RTPSession *session ) | 267 | RTPHeader *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 | */ |
360 | RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length ) | 310 | RTPMessage *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 | */ |
418 | int rtp_handle_packet ( void *object, uint8_t *data, uint32_t length ) | 366 | int 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 | */ | ||
574 | int 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 | */ | ||
606 | void 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 | */ | ||
631 | RTPMessage *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 | */ |
763 | RTPSession *rtp_init_session ( int payload_type, | 526 | RTPSession *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 | */ |
842 | int rtp_terminate_session ( RTPSession *session, Messenger *messenger ) | 586 | void 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 | */ |
187 | void rtp_free_msg ( RTPSession *session, RTPMessage *msg ); | 168 | void 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 | */ |
204 | RTPSession *rtp_init_session ( int payload_type, | 180 | RTPSession *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 | */ |
222 | int rtp_terminate_session ( RTPSession *session, Messenger *messenger ); | 192 | void 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 | ||
74 | const ToxAvCodecSettings av_DefaultSettings = { | 86 | const 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 | */ |
124 | void toxav_kill ( ToxAv *av ) | 138 | void 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 | */ | ||
181 | void 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 | */ | ||
192 | void 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 | */ |
286 | int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video ) | 326 | int 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; | 394 | error: |
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 | */ |
351 | int toxav_kill_transmission ( ToxAv *av, int32_t call_index ) | 412 | int 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 | */ |
397 | inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, const uint8_t *payload, | 459 | inline__ 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 | */ | ||
418 | inline__ 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 | */ |
471 | inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **output) | 516 | inline__ 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 | */ | ||
509 | inline__ 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 | */ |
527 | inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input) | 550 | inline__ 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 | */ | ||
570 | inline__ 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 | */ |
613 | inline__ int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, int frame_size) | 613 | inline__ 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 | |||
632 | inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, | 648 | inline__ 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 | */ |
673 | int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer ) | 703 | int 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 | */ | ||
720 | ToxAvCallState 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 | /** | 743 | inline__ 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 | */ | ||
706 | inline__ 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 | /** | 748 | int 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 | */ | ||
724 | inline__ 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 | ||
734 | inline__ Tox *toxav_get_tox(ToxAv *av) | 755 | void 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 | |||
827 | end: | ||
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 | ||
28 | extern "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 | ||
77 | typedef 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 | */ |
109 | typedef struct _ToxAvCodecSettings { | 121 | typedef 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); | |||
152 | void toxav_register_callstate_callback (ToxAVCallback callback, ToxAvCallbackID id, void *userdata); | 165 | void 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 | */ | ||
173 | void 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 | */ | ||
181 | void 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 | |||
240 | int toxav_kill_transmission(ToxAv *av, int32_t call_index); | 269 | int 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 | */ | ||
251 | int 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 | */ | ||
265 | int 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 ) | |||
339 | int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer ); | 343 | int 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 | */ | ||
353 | ToxAvCallState 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 | ||
372 | Tox *toxav_get_tox(ToxAv *av); | 385 | Tox *toxav_get_tox(ToxAv *av); |
373 | #endif /* __TOXAV */ \ No newline at end of file | 386 | |
387 | int 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 | */ |
2215 | uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num) | 2215 | uint16_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 | */ |
309 | uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num); | 309 | uint16_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). */ |
312 | void do_DHT(DHT *dht); | 312 | void 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 | ||
42 | static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status); | 42 | static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status); |
43 | static int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); | 43 | static 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 |
46 | static uint8_t friend_not_valid(Messenger *m, int32_t friendnumber) | 47 | static 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 | */ |
112 | int getclient_id(Messenger *m, int32_t friendnumber, uint8_t *client_id) | 113 | int 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 | */ |
128 | static uint16_t address_checksum(uint8_t *address, uint32_t len) | 129 | static 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 | */ |
145 | void getaddress(Messenger *m, uint8_t *address) | 146 | void 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. */ |
155 | static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, uint8_t *public_key) | 156 | static 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 | */ |
186 | int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) | 187 | int32_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 | ||
349 | int m_get_friend_connectionstatus(Messenger *m, int32_t friendnumber) | 350 | int 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 | ||
357 | int m_friend_exists(Messenger *m, int32_t friendnumber) | 358 | int 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 | */ |
405 | uint32_t m_sendaction(Messenger *m, int32_t friendnumber, uint8_t *action, uint32_t length) | 406 | uint32_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 | ||
422 | uint32_t m_sendaction_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length) | 423 | uint32_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 | */ |
437 | static int m_sendname(Messenger *m, int32_t friendnumber, uint8_t *name, uint16_t length) | 439 | static 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 | */ |
450 | int setfriendname(Messenger *m, int32_t friendnumber, uint8_t *name, uint16_t length) | 452 | int 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 | */ |
495 | uint16_t getself_name(Messenger *m, uint8_t *name) | 497 | uint16_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 | */ |
512 | int getname(Messenger *m, int32_t friendnumber, uint8_t *name) | 514 | int 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 | ||
521 | int m_get_name_size(Messenger *m, int32_t friendnumber) | 523 | int 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 | ||
529 | int m_get_self_name_size(Messenger *m) | 531 | int 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 | */ |
568 | int m_get_statusmessage_size(Messenger *m, int32_t friendnumber) | 570 | int 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 | */ |
579 | int m_copy_statusmessage(Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen) | 581 | int 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 | */ |
592 | int m_get_self_statusmessage_size(Messenger *m) | 596 | int m_get_self_statusmessage_size(const Messenger *m) |
593 | { | 597 | { |
594 | return m->statusmessage_length; | 598 | return m->statusmessage_length; |
595 | } | 599 | } |
596 | 600 | ||
597 | int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen) | 601 | int 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 | ||
604 | uint8_t m_get_userstatus(Messenger *m, int32_t friendnumber) | 609 | uint8_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 | ||
618 | uint8_t m_get_self_userstatus(Messenger *m) | 623 | uint8_t m_get_self_userstatus(const Messenger *m) |
619 | { | 624 | { |
620 | return m->userstatus; | 625 | return m->userstatus; |
621 | } | 626 | } |
622 | 627 | ||
623 | uint64_t m_get_last_online(Messenger *m, int32_t friendnumber) | 628 | uint64_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 | ||
647 | uint8_t m_get_istyping(Messenger *m, int32_t friendnumber) | 652 | uint8_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 | ||
655 | static int send_statusmessage(Messenger *m, int32_t friendnumber, uint8_t *status, uint16_t length) | 660 | static 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 | ||
660 | static int send_userstatus(Messenger *m, int32_t friendnumber, uint8_t status) | 665 | static 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 | ||
665 | static int send_user_istyping(Messenger *m, int32_t friendnumber, uint8_t is_typing) | 670 | static 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 | ||
671 | static int send_ping(Messenger *m, int32_t friendnumber) | 676 | static 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 | ||
681 | static int send_relays(Messenger *m, int32_t friendnumber) | 686 | static 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 | ||
700 | static int set_friend_statusmessage(Messenger *m, int32_t friendnumber, uint8_t *status, uint16_t length) | 705 | static 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 | ||
713 | static void set_friend_userstatus(Messenger *m, int32_t friendnumber, uint8_t status) | 718 | static 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 | ||
718 | static void set_friend_typing(Messenger *m, int32_t friendnumber, uint8_t is_typing) | 723 | static 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. */ |
745 | void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 750 | void 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 | ||
752 | void m_callback_action(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 757 | void 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 | ||
759 | void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 764 | void 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 | ||
766 | void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 771 | void 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 | ||
804 | static void break_files(Messenger *m, int32_t friendnumber); | 809 | static void break_files(const Messenger *m, int32_t friendnumber); |
805 | static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, uint8_t status) | 810 | static 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 | ||
840 | int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length) | 845 | int 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 | */ |
862 | static uint8_t groupnumber_not_valid(Messenger *m, int groupnumber) | 868 | static 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 | */ |
880 | static IP_Port get_friend_ipport(Messenger *m, int32_t friendnumber) | 886 | static 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 | */ |
904 | static int group_num(Messenger *m, uint8_t *group_public_key) | 910 | static 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 | */ |
921 | void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, void *), void *userdata) | 927 | void 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 | */ |
931 | void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t *, uint16_t, void *), | 938 | void 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 | */ |
942 | void m_callback_group_action(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t *, uint16_t, void *), | 949 | void 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 | ||
961 | static int get_chat_num(Messenger *m, Group_Chat *chat) | 968 | static 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 | */ |
1114 | int m_group_peername(Messenger *m, int groupnumber, int peernumber, uint8_t *name) | 1121 | int 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 | */ |
1141 | static uint8_t group_invited(Messenger *m, int32_t friendnumber, int groupnumber) | 1148 | static 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 | */ |
1189 | int join_groupchat(Messenger *m, int32_t friendnumber, uint8_t *friend_group_public_key) | 1196 | int 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 | */ |
1222 | int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length) | 1232 | int 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 | */ |
1237 | int group_action_send(Messenger *m, int groupnumber, uint8_t *action, uint32_t length) | 1247 | int 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 | */ |
1251 | int group_number_peers(Messenger *m, int groupnumber) | 1261 | int 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 | */ |
1269 | int group_names(Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[], uint16_t length) | 1279 | int 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 | */ |
1315 | void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint64_t, uint8_t *, | 1326 | void 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 | */ |
1327 | void callback_file_control(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, | 1338 | void 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 | */ |
1339 | void callback_file_data(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t *, uint16_t length, | 1350 | void 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 | */ |
1353 | int file_sendrequest(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, | 1364 | int 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 | */ |
1376 | int new_filesender(Messenger *m, int32_t friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length) | 1387 | int 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 | */ |
1406 | int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, | 1418 | int 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 | */ |
1494 | int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length) | 1506 | int 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 | */ |
1529 | uint64_t file_dataremaining(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive) | 1541 | uint64_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 | */ |
1552 | static void break_files(Messenger *m, int32_t friendnumber) | 1564 | static 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 | ||
1565 | static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, | 1577 | static 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 | */ |
1655 | void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 1667 | void 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 | */ |
1667 | int m_msi_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length) | 1679 | int 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 | ||
1672 | static int handle_custom_lossy_packet(void *object, int friend_num, uint8_t *packet, uint16_t length) | 1684 | static 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 | ||
1686 | int custom_lossy_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, | 1698 | int 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 | ||
1703 | int send_custom_lossy_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint32_t length) | 1715 | int 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 | ||
1717 | static int handle_custom_lossless_packet(void *object, int friend_num, uint8_t *packet, uint16_t length) | 1729 | static 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 | ||
1737 | int custom_lossless_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, | 1749 | int 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 | ||
1755 | int send_custom_lossless_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint32_t length) | 1767 | int 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*/ |
1770 | static int friend_already_added(const uint8_t *client_id, void *data) | 1782 | static 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 | ||
2216 | static int friend_new_connection(Messenger *m, int32_t friendnumber, uint8_t *real_public_key) | 2228 | static 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 |
2335 | static time_t lastdump = 0; | 2347 | static time_t lastdump = 0; |
2336 | static char IDString[CLIENT_ID_SIZE * 2 + 1]; | 2348 | static char IDString[CLIENT_ID_SIZE * 2 + 1]; |
2337 | static char *ID2String(uint8_t *client_id) | 2349 | static 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 | ||
2529 | static uint32_t saved_friendslist_size(Messenger *m) | 2542 | static 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 | ||
2534 | static uint32_t friends_list_save(Messenger *m, uint8_t *data) | 2547 | static 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) */ |
2613 | uint32_t messenger_size(Messenger *m) | 2630 | uint32_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(). */ |
2638 | void messenger_save(Messenger *m, uint8_t *data) | 2655 | void 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 | ||
2699 | static int messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type) | 2715 | static 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. */ |
2776 | int messenger_load(Messenger *m, uint8_t *data, uint32_t length) | 2792 | int 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. */ |
2796 | uint32_t count_friendlist(Messenger *m) | 2812 | uint32_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. */ |
2811 | uint32_t get_num_online_friends(Messenger *m) | 2827 | uint32_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. */ |
2821 | uint32_t copy_friendlist(Messenger *m, int32_t *out_list, uint32_t list_size) | 2837 | uint32_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 | */ |
2853 | int get_friendlist(Messenger *m, int32_t **out_list, uint32_t *out_list_length) | 2869 | int 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. */ |
2883 | uint32_t count_chatlist(Messenger *m) | 2899 | uint32_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. */ |
2902 | uint32_t copy_chatlist(Messenger *m, int *out_list, uint32_t list_size) | 2918 | uint32_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 | */ |
261 | void getaddress(Messenger *m, uint8_t *address); | 261 | void 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 | */ |
279 | int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length); | 279 | int32_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 | */ |
299 | int getclient_id(Messenger *m, int32_t friendnumber, uint8_t *client_id); | 299 | int 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 | */ |
314 | int m_get_friend_connectionstatus(Messenger *m, int32_t friendnumber); | 314 | int 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 | */ |
321 | int m_friend_exists(Messenger *m, int32_t friendnumber); | 321 | int 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 | */ |
347 | uint32_t m_sendaction(Messenger *m, int32_t friendnumber, uint8_t *action, uint32_t length); | 347 | uint32_t m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length); |
348 | uint32_t m_sendaction_withid(Messenger *m, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length); | 348 | uint32_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 | */ |
358 | int setfriendname(Messenger *m, int32_t friendnumber, uint8_t *name, uint16_t length); | 359 | int 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 | */ |
378 | uint16_t getself_name(Messenger *m, uint8_t *name); | 379 | uint16_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 | */ |
386 | int getname(Messenger *m, int32_t friendnumber, uint8_t *name); | 387 | int 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 | */ |
391 | int m_get_name_size(Messenger *m, int32_t friendnumber); | 392 | int m_get_name_size(const Messenger *m, int32_t friendnumber); |
392 | int m_get_self_name_size(Messenger *m); | 393 | int 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 | */ |
406 | int m_get_statusmessage_size(Messenger *m, int32_t friendnumber); | 407 | int m_get_statusmessage_size(const Messenger *m, int32_t friendnumber); |
407 | int m_get_self_statusmessage_size(Messenger *m); | 408 | int 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 | */ |
416 | int m_copy_statusmessage(Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen); | 417 | int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen); |
417 | int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen); | 418 | int 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 | */ |
424 | uint8_t m_get_userstatus(Messenger *m, int32_t friendnumber); | 425 | uint8_t m_get_userstatus(const Messenger *m, int32_t friendnumber); |
425 | uint8_t m_get_self_userstatus(Messenger *m); | 426 | uint8_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 | */ |
430 | uint64_t m_get_last_online(Messenger *m, int32_t friendnumber); | 431 | uint64_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 | */ |
445 | uint8_t m_get_istyping(Messenger *m, int32_t friendnumber); | 446 | uint8_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 | */ |
461 | void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 462 | void 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 | */ |
467 | void m_callback_action(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 468 | void 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 | */ |
474 | void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 475 | void 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 | */ |
482 | void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 483 | void 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 | */ |
529 | void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, void *), void *userdata); | 530 | void 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 | */ |
535 | void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t *, uint16_t, void *), | 537 | void 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 | */ |
542 | void m_callback_group_action(Messenger *m, void (*function)(Messenger *m, int, int, uint8_t *, uint16_t, void *), | 544 | void 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 | */ |
573 | int m_group_peername(Messenger *m, int groupnumber, int peernumber, uint8_t *name); | 575 | int 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 | */ |
586 | int join_groupchat(Messenger *m, int32_t friendnumber, uint8_t *friend_group_public_key); | 588 | int 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 | */ |
592 | int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length); | 594 | int 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 | */ |
598 | int group_action_send(Messenger *m, int groupnumber, uint8_t *action, uint32_t length); | 600 | int 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 | */ |
603 | int group_number_peers(Messenger *m, int groupnumber); | 605 | int 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 | */ |
615 | int group_names(Messenger *m, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[], uint16_t length); | 617 | int 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 | */ |
624 | void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint64_t, uint8_t *, | 627 | void 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 | */ |
632 | void callback_file_control(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, | 635 | void 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 | */ |
640 | void callback_file_data(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t, uint8_t *, uint16_t length, | 643 | void 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 | */ |
648 | int file_sendrequest(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, | 651 | int 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 | */ |
656 | int new_filesender(Messenger *m, int32_t friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length); | 659 | int 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 | */ |
664 | int file_control(Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, | 668 | int 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 | */ |
672 | int file_data(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length); | 676 | int 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 | */ |
681 | uint64_t file_dataremaining(Messenger *m, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive); | 685 | uint64_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 | */ |
689 | void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, int32_t, uint8_t *, uint16_t, void *), | 693 | void 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 | */ |
697 | int m_msi_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length); | 701 | int 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 | */ |
706 | int custom_lossy_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, | 710 | int 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 | */ |
714 | int send_custom_lossy_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint32_t length); | 718 | int 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 | */ |
724 | int custom_lossless_packet_registerhandler(Messenger *m, int32_t friendnumber, uint8_t byte, | 728 | int 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 | */ |
732 | int send_custom_lossless_packet(Messenger *m, int32_t friendnumber, uint8_t *data, uint32_t length); | 736 | int 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). */ |
759 | uint32_t messenger_size(Messenger *m); | 763 | uint32_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()) */ |
762 | void messenger_save(Messenger *m, uint8_t *data); | 766 | void 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. */ |
765 | int messenger_load(Messenger *m, uint8_t *data, uint32_t length); | 769 | int 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. */ |
770 | uint32_t count_friendlist(Messenger *m); | 774 | uint32_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. */ |
773 | uint32_t get_num_online_friends(Messenger *m); | 777 | uint32_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. */ |
780 | uint32_t copy_friendlist(Messenger *m, int32_t *out_list, uint32_t list_size); | 784 | uint32_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 | */ |
788 | int get_friendlist(Messenger *m, int **out_list, uint32_t *out_list_length); | 792 | int 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. */ |
793 | uint32_t count_chatlist(Messenger *m); | 797 | uint32_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. */ |
800 | uint32_t copy_chatlist(Messenger *m, int *out_list, uint32_t list_size); | 804 | uint32_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 | */ |
68 | static int generate_handshake(TCP_Client_Connection *TCP_conn, uint8_t *self_public_key, uint8_t *self_secret_key) | 68 | static 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 | */ |
93 | static int handle_handshake(TCP_Client_Connection *TCP_conn, uint8_t *data) | 94 | static 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 | */ |
140 | static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, uint8_t *data, uint16_t length) | 141 | static 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 | ||
185 | void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, | 186 | void 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 | ||
200 | static 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 | */ |
203 | int send_data(TCP_Client_Connection *con, uint8_t con_id, uint8_t *data, uint16_t length) | 206 | int 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 | */ |
221 | int send_oob_packet(TCP_Client_Connection *con, uint8_t *public_key, uint8_t *data, uint16_t length) | 227 | int 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 | ||
253 | void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, | 259 | void 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 | ||
260 | void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, uint8_t *public_key, | 266 | void 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 | */ |
295 | static int send_ping_response(TCP_Client_Connection *con, uint64_t ping_id) | 301 | static 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 | */ |
321 | int send_onion_request(TCP_Client_Connection *con, uint8_t *data, uint16_t length) | 336 | int 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 | ||
329 | void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, uint8_t *data, | 344 | void 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 | */ |
338 | TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key, uint8_t *self_public_key, | 353 | TCP_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 | */ |
391 | static int handle_TCP_packet(TCP_Client_Connection *conn, uint8_t *data, uint16_t length) | 406 | static 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_ | |||
522 | static int do_confirmed_TCP(TCP_Client_Connection *conn) | 538 | static 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 | */ |
82 | TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key, uint8_t *self_public_key, | 83 | TCP_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 | */ |
97 | int send_onion_request(TCP_Client_Connection *con, uint8_t *data, uint16_t length); | 98 | int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length); |
98 | void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, uint8_t *data, | 99 | void 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 | */ |
105 | int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key); | 106 | int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key); |
106 | void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, | 107 | void 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); |
108 | void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number, | 109 | void 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 | */ |
130 | int send_data(TCP_Client_Connection *con, uint8_t con_id, uint8_t *data, uint16_t length); | 131 | int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length); |
131 | void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, | 132 | void 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 | */ |
138 | int send_oob_packet(TCP_Client_Connection *con, uint8_t *public_key, uint8_t *data, uint16_t length); | 139 | int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length); |
139 | void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, uint8_t *public_key, | 140 | void 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 | */ |
100 | static int get_TCP_connection_index(TCP_Server *TCP_server, uint8_t *public_key) | 100 | static 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 | */ |
113 | static int add_accepted(TCP_Server *TCP_server, TCP_Secure_Connection *con) | 113 | static 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 | */ |
252 | int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, uint8_t *shared_key, | 252 | int 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 | */ |
321 | static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t *data, uint16_t length) | 321 | static 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 | */ |
392 | static int handle_TCP_handshake(TCP_Secure_Connection *con, uint8_t *data, uint16_t length, uint8_t *self_secret_key) | 392 | static 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 | */ |
438 | static int read_connection_handshake(TCP_Secure_Connection *con, uint8_t *self_secret_key) | 439 | static 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 | */ |
454 | static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, uint8_t *public_key) | 455 | static 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 | */ |
487 | static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, uint8_t *public_key) | 488 | static 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 | */ |
565 | static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, uint8_t *public_key, uint8_t *data, | 566 | static 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 | */ |
648 | static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, uint8_t *data, uint16_t length) | 649 | static 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 | ||
767 | static int confirm_TCP_connection(TCP_Server *TCP_server, TCP_Secure_Connection *con, uint8_t *data, uint16_t length) | 768 | static 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 | ||
840 | TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, uint16_t *ports, uint8_t *public_key, | 843 | TCP_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 | */ |
136 | TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, uint16_t *ports, uint8_t *public_key, | 136 | TCP_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 | */ |
167 | int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, uint8_t *shared_key, | 167 | int 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 | */ | ||
114 | static 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 | ||
109 | void 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 | |||
138 | int 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 | ||
118 | void bs_list_free(BS_LIST *list) | 158 | void 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 | |||
248 | int 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 | ||
33 | typedef struct { | 33 | typedef 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 |
41 | void 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 | */ | ||
48 | int 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 */ |
44 | void bs_list_free(BS_LIST *list); | 51 | void bs_list_free(BS_LIST *list); |
@@ -67,4 +74,12 @@ int bs_list_add(BS_LIST *list, const void *data, int id); | |||
67 | */ | 74 | */ |
68 | int bs_list_remove(BS_LIST *list, const void *data, int id); | 75 | int 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 | */ | ||
83 | int 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 | ||
35 | static uint8_t crypt_connection_id_not_valid(Net_Crypto *c, int crypt_connection_id) | 35 | static 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 | */ |
73 | static int create_cookie_request(Net_Crypto *c, uint8_t *packet, uint8_t *dht_public_key, uint64_t number, | 73 | static 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 | */ |
103 | static int create_cookie(uint8_t *cookie, uint8_t *bytes, uint8_t *encryption_key) | 103 | static 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 | */ |
151 | static int create_cookie_response(Net_Crypto *c, uint8_t *packet, uint8_t *request_plain, uint8_t *shared_key, | 151 | static 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 | */ |
180 | static int handle_cookie_request(Net_Crypto *c, uint8_t *request_plain, uint8_t *shared_key, uint8_t *dht_public_key, | 180 | static 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 | */ |
223 | static int tcp_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id, uint8_t *packet, | 223 | static 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 | */ |
246 | static int tcp_oob_handle_cookie_request(Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t *dht_public_key, | 246 | static 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 | */ |
305 | static int create_crypto_handshake(Net_Crypto *c, uint8_t *packet, uint8_t *cookie, uint8_t *nonce, uint8_t *session_pk, | 305 | static 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 | */ |
351 | static int handle_crypto_handshake(Net_Crypto *c, uint8_t *nonce, uint8_t *session_pk, uint8_t *peer_real_pk, | 351 | static 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 | ||
389 | static Crypto_Connection *get_crypto_connection(Net_Crypto *c, int crypt_connection_id) | 389 | static 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 | */ |
403 | static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) | 403 | static 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 | */ |
459 | static uint32_t num_packets_array(Packets_Array *array) | 459 | static 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 | */ |
469 | static int add_data_to_buffer(Packets_Array *array, uint32_t number, Packet_Data *data) | 469 | static 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 | */ |
499 | static int get_data_pointer(Packets_Array *array, Packet_Data **data, uint32_t number) | 499 | static 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 | */ |
520 | static int64_t add_data_end_of_buffer(Packets_Array *array, Packet_Data *data) | 520 | static 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 | */ |
610 | static int generate_request_packet(uint8_t *data, uint16_t length, Packets_Array *recv_array) | 610 | static 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 | */ |
659 | static int handle_request_packet(Packets_Array *send_array, uint8_t *data, uint16_t length) | 659 | static 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 | */ |
721 | static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) | 721 | static 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 | */ |
753 | static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num, | 753 | static 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 | */ |
774 | static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) | 774 | static 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 | */ |
802 | static uint16_t get_nonce_uint16(uint8_t *nonce) | 830 | static 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 | */ |
818 | static int handle_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, const uint8_t *packet, | 846 | static 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 | */ |
855 | static int send_request_packet(Net_Crypto *c, int crypt_connection_id) | 883 | static 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 | */ |
877 | static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num) | 905 | static 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 | */ |
923 | static int new_temp_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length) | 951 | static 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 | */ |
954 | static int clear_temp_packet(Net_Crypto *c, int crypt_connection_id) | 982 | static 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 | */ |
977 | static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) | 1005 | static 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 | */ |
1001 | static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, uint8_t *cookie, uint8_t *dht_public_key) | 1029 | static 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 | */ |
1026 | static int send_kill_packet(Net_Crypto *c, int crypt_connection_id) | 1055 | static 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 | */ |
1043 | static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length) | 1072 | static 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 | */ |
1292 | static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key) | 1322 | static 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 | */ |
1310 | static int getcryptconnection_id_dht_pubkey(Net_Crypto *c, uint8_t *dht_public_key) | 1340 | static 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 | */ |
1468 | int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key) | 1498 | int 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 | */ |
1498 | static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id) | 1528 | static 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 | */ |
1523 | static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id) | 1553 | static 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 | */ |
1548 | uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key) | 1578 | uint64_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 | */ |
1570 | int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp) | 1600 | int 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 | ||
1631 | static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *public_key) | 1662 | static 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 | ||
1698 | static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length) | 1729 | static 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 | ||
1723 | static int tcp_oob_callback(void *object, uint8_t *public_key, uint8_t *data, uint16_t length) | 1754 | static 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 | */ |
1765 | static int tcp_connection_check(Net_Crypto *c, uint8_t *public_key) | 1796 | static 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 | */ |
1800 | int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key) | 1831 | int 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 | */ |
1853 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key) | 1884 | int 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 | */ |
1885 | unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num) | 1916 | unsigned 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 | */ |
2049 | int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object, | 2080 | int 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 | */ |
2071 | int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object, | 2102 | int 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 | */ |
2093 | int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, | 2124 | int 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 | */ |
2112 | static int crypto_id_ip_port(Net_Crypto *c, IP_Port ip_port) | 2143 | static 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 | */ |
2349 | uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) | 2379 | uint32_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 | */ |
2366 | int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) | 2396 | int64_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 | */ |
2403 | int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) | 2433 | int 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 | */ |
2445 | unsigned int crypto_connection_status(Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected) | 2475 | unsigned 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 | */ |
2468 | void save_keys(Net_Crypto *c, uint8_t *keys) | 2498 | void 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 | */ |
2556 | uint32_t crypto_run_interval(Net_Crypto *c) | 2586 | uint32_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 | */ |
221 | int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key); | 223 | int 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 | */ |
228 | uint64_t get_connection_dht_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key); | 230 | uint64_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 | */ |
237 | int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key, uint64_t timestamp); | 239 | int 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 | */ |
256 | int connection_status_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_status_callback)(void *object, | 259 | int 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 | */ |
267 | int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connection_data_callback)(void *object, | 270 | int 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 | */ |
279 | int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, | 282 | int 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 | */ |
285 | uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id); | 289 | uint32_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 | */ |
294 | int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); | 298 | int64_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 | */ |
301 | int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); | 305 | int 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 | */ |
308 | int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key); | 312 | int 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 | */ |
315 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key); | 319 | int 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 | */ |
323 | unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num); | 327 | unsigned 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 | */ |
337 | unsigned int crypto_connection_status(Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected); | 341 | unsigned 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 | */ |
348 | void save_keys(Net_Crypto *c, uint8_t *keys); | 352 | void 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 | */ |
362 | uint32_t crypto_run_interval(Net_Crypto *c); | 366 | uint32_t crypto_run_interval(const Net_Crypto *c); |
363 | 367 | ||
364 | /* Main loop. */ | 368 | /* Main loop. */ |
365 | void do_net_crypto(Net_Crypto *c); | 369 | void 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 | */ |
57 | int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes) | 57 | int 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 | */ |
95 | int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length) | 96 | int 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 | */ | ||
152 | int 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 | ||
192 | int onion_send_1(Onion *onion, uint8_t *plain, uint32_t len, IP_Port source, const uint8_t *nonce) | 212 | int 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 | */ |
79 | int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes); | 79 | int 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 | */ | ||
90 | int 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 | */ |
89 | int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length); | 101 | int 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 | */ |
109 | int onion_send_1(Onion *onion, uint8_t *plain, uint32_t len, IP_Port source, const uint8_t *nonce); | 121 | int 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 | */ |
52 | int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key, | 52 | int 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 | */ |
91 | int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key, | 92 | int 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 | */ | ||
133 | int 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 | */ | ||
164 | int 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 */ |
118 | static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, const uint8_t *public_key, IP_Port ret_ip_port, | 180 | static 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 | */ | ||
78 | int 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 | */ | ||
96 | int 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 | */ |
78 | int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key, | 114 | int 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 | */ |
97 | int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key, | 134 | int 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 | ||
101 | Onion_Announce *new_onion_announce(DHT *dht); | 138 | Onion_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 | */ |
41 | static int is_path_used(Onion_Client_Paths *onion_paths, Node_format *nodes) | 41 | static 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 | */ |
71 | static int random_path(DHT *dht, Onion_Client_Paths *onion_paths, uint32_t pathnum, Onion_Path *path) | 71 | static 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 | */ | ||
133 | static 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 | */ |
143 | static int new_sendback(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, uint64_t *sendback) | 160 | static 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 | ||
184 | static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_Port dest, uint8_t *dest_pubkey, | 202 | static 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 | ||
252 | static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, | 283 | static 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 | ||
311 | static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, uint8_t *client_id) | 342 | static 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 | ||
327 | static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *nodes, uint16_t num_nodes, | 358 | static 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 | */ |
597 | static int send_dht_fakeid(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32_t length) | 634 | static 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 | */ |
660 | static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both) | 697 | static 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 | */ |
817 | int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object, | 854 | int 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 | */ |
872 | uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key) | 909 | uint64_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 | */ |
894 | int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port) | 931 | int 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 | */ |
174 | int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); | 174 | int 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 | */ |
184 | int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object, | 184 | int 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 | */ |
201 | uint64_t onion_getfriend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t *dht_key); | 201 | uint64_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 | */ |
41 | void tox_get_address(Tox *tox, uint8_t *address) | 41 | void 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 | */ |
64 | int32_t tox_add_friend(Tox *tox, uint8_t *address, uint8_t *data, uint16_t length) | 64 | int32_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 | */ |
84 | int32_t tox_get_friend_number(Tox *tox, uint8_t *client_id) | 84 | int32_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 | */ |
96 | int tox_get_client_id(Tox *tox, int32_t friendnumber, uint8_t *client_id) | 96 | int 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 | */ |
115 | int tox_get_friend_connection_status(Tox *tox, int32_t friendnumber) | 115 | int 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 | */ |
126 | int tox_friend_exists(Tox *tox, int32_t friendnumber) | 126 | int 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 | ||
147 | uint32_t tox_send_message_withid(Tox *tox, int32_t friendnumber, uint32_t theid, uint8_t *message, uint32_t length) | 147 | uint32_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 | */ |
163 | uint32_t tox_send_action(Tox *tox, int32_t friendnumber, uint8_t *action, uint32_t length) | 164 | uint32_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 | ||
169 | uint32_t tox_send_action_withid(Tox *tox, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length) | 170 | uint32_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 | */ |
183 | int tox_set_name(Tox *tox, uint8_t *name, uint16_t length) | 184 | int 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 | */ |
196 | uint16_t tox_get_self_name(Tox *tox, uint8_t *name) | 197 | uint16_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 | */ |
208 | int tox_get_name(Tox *tox, int32_t friendnumber, uint8_t *name) | 209 | int 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 | */ |
217 | int tox_get_name_size(Tox *tox, int32_t friendnumber) | 218 | int 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 | ||
223 | int tox_get_self_name_size(Tox *tox) | 224 | int 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 | */ |
234 | int tox_set_status_message(Tox *tox, uint8_t *status, uint16_t length) | 235 | int 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 | */ |
249 | int tox_get_status_message_size(Tox *tox, int32_t friendnumber) | 250 | int 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 | ||
255 | int tox_get_self_status_message_size(Tox *tox) | 256 | int 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 | */ |
265 | int tox_get_status_message(Tox *tox, int32_t friendnumber, uint8_t *buf, uint32_t maxlen) | 266 | int 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 | ||
271 | int tox_get_self_status_message(Tox *tox, uint8_t *buf, uint32_t maxlen) | 272 | int 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 | */ |
282 | uint8_t tox_get_user_status(Tox *tox, int32_t friendnumber) | 283 | uint8_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 | ||
288 | uint8_t tox_get_self_user_status(Tox *tox) | 289 | uint8_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 | */ |
297 | uint64_t tox_get_last_online(Tox *tox, int32_t friendnumber) | 298 | uint64_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 | */ |
320 | uint8_t tox_get_is_typing(Tox *tox, int32_t friendnumber) | 321 | uint8_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. */ |
338 | uint32_t tox_count_friendlist(Tox *tox) | 339 | uint32_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. */ |
345 | uint32_t tox_get_num_online_friends(Tox *tox) | 346 | uint32_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. */ |
356 | uint32_t tox_get_friendlist(Tox *tox, int32_t *out_list, uint32_t list_size) | 357 | uint32_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 | */ |
376 | void tox_callback_friend_message(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, uint16_t, void *), | 377 | void 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 | */ |
386 | void tox_callback_friend_action(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, uint16_t, void *), | 387 | void 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 | */ |
397 | void tox_callback_name_change(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, uint16_t, void *), | 398 | void 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 | */ |
408 | void tox_callback_status_message(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, uint16_t, void *), | 409 | void 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 | */ |
471 | uint32_t tox_get_nospam(Tox *tox) | 472 | uint32_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 | */ |
489 | void tox_callback_group_invite(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t *, void *), void *userdata) | 490 | void 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 | */ |
499 | void tox_callback_group_message(Tox *tox, void (*function)(Messenger *tox, int, int, uint8_t *, uint16_t, void *), | 501 | void 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 | */ |
510 | void tox_callback_group_action(Tox *tox, void (*function)(Messenger *tox, int, int, uint8_t *, uint16_t, void *), | 512 | void 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 | */ |
555 | int tox_group_peername(Tox *tox, int groupnumber, int peernumber, uint8_t *name) | 557 | int 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 | */ |
574 | int tox_join_groupchat(Tox *tox, int32_t friendnumber, uint8_t *friend_group_public_key) | 576 | int 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 | */ |
584 | int tox_group_message_send(Tox *tox, int groupnumber, uint8_t *message, uint32_t length) | 586 | int 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 | */ |
594 | int tox_group_action_send(Tox *tox, int groupnumber, uint8_t *action, uint32_t length) | 596 | int 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 | */ |
603 | int tox_group_number_peers(Tox *tox, int groupnumber) | 605 | int 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 | */ |
619 | int tox_group_get_names(Tox *tox, int groupnumber, uint8_t names[][TOX_MAX_NAME_LENGTH], uint16_t lengths[], | 621 | int 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. */ |
629 | uint32_t tox_count_chatlist(Tox *tox) | 631 | uint32_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. */ |
640 | uint32_t tox_get_chatlist(Tox *tox, int *out_list, uint32_t list_size) | 642 | uint32_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 | */ |
654 | void tox_callback_file_send_request(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t, uint64_t, uint8_t *, | 656 | void 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 | */ |
666 | void tox_callback_file_control(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, | 667 | void 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 | */ |
677 | void tox_callback_file_data(Tox *tox, void (*function)(Messenger *tox, int32_t, uint8_t, uint8_t *, uint16_t length, | 678 | void 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 | */ |
690 | int tox_new_file_sender(Tox *tox, int32_t friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length) | 690 | int 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 | */ |
701 | int tox_file_send_control(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, | 702 | int 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 | */ |
712 | int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length) | 713 | int 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 | */ |
723 | int tox_file_data_size(Tox *tox, int32_t friendnumber) | 724 | int 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 | */ |
735 | uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive) | 736 | uint64_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. */ |
744 | static int tox_add_tcp_relay(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) | 745 | static 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 | ||
768 | int tox_bootstrap_from_address(Tox *tox, const char *address, | 770 | int 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 | */ |
779 | int tox_isconnected(Tox *tox) | 781 | int 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). */ |
826 | uint32_t tox_size(Tox *tox) | 828 | uint32_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()). */ |
833 | void tox_save(Tox *tox, uint8_t *data) | 835 | void 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. */ |
840 | int tox_load(Tox *tox, uint8_t *data, uint32_t length) | 842 | int 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 | */ |
85 | void tox_get_address(Tox *tox, uint8_t *address); | 85 | void 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 | */ |
103 | int32_t tox_add_friend(Tox *tox, uint8_t *address, uint8_t *data, uint16_t length); | 103 | int32_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 */ |
114 | int32_t tox_get_friend_number(Tox *tox, uint8_t *client_id); | 114 | int32_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 | */ |
121 | int tox_get_client_id(Tox *tox, int32_t friendnumber, uint8_t *client_id); | 121 | int 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 | */ |
136 | int tox_get_friend_connection_status(Tox *tox, int32_t friendnumber); | 136 | int 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 | */ |
143 | int tox_friend_exists(Tox *tox, int32_t friendnumber); | 143 | int 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 | */ |
159 | uint32_t tox_send_message(Tox *tox, int32_t friendnumber, const uint8_t *message, uint32_t length); | 159 | uint32_t tox_send_message(Tox *tox, int32_t friendnumber, const uint8_t *message, uint32_t length); |
160 | uint32_t tox_send_message_withid(Tox *tox, int32_t friendnumber, uint32_t theid, uint8_t *message, uint32_t length); | 160 | uint32_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 | */ |
176 | uint32_t tox_send_action(Tox *tox, int32_t friendnumber, uint8_t *action, uint32_t length); | 177 | uint32_t tox_send_action(Tox *tox, int32_t friendnumber, const uint8_t *action, uint32_t length); |
177 | uint32_t tox_send_action_withid(Tox *tox, int32_t friendnumber, uint32_t theid, uint8_t *action, uint32_t length); | 178 | uint32_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 | */ |
187 | int tox_set_name(Tox *tox, uint8_t *name, uint16_t length); | 188 | int 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 | */ |
197 | uint16_t tox_get_self_name(Tox *tox, uint8_t *name); | 198 | uint16_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 | */ |
205 | int tox_get_name(Tox *tox, int32_t friendnumber, uint8_t *name); | 206 | int 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 | */ |
210 | int tox_get_name_size(Tox *tox, int32_t friendnumber); | 211 | int tox_get_name_size(const Tox *tox, int32_t friendnumber); |
211 | int tox_get_self_name_size(Tox *tox); | 212 | int 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 | */ |
221 | int tox_set_status_message(Tox *tox, uint8_t *status, uint16_t length); | 222 | int tox_set_status_message(Tox *tox, const uint8_t *status, uint16_t length); |
222 | int tox_set_user_status(Tox *tox, uint8_t userstatus); | 223 | int 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 | */ |
227 | int tox_get_status_message_size(Tox *tox, int32_t friendnumber); | 228 | int tox_get_status_message_size(const Tox *tox, int32_t friendnumber); |
228 | int tox_get_self_status_message_size(Tox *tox); | 229 | int 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 | */ |
237 | int tox_get_status_message(Tox *tox, int32_t friendnumber, uint8_t *buf, uint32_t maxlen); | 238 | int tox_get_status_message(const Tox *tox, int32_t friendnumber, uint8_t *buf, uint32_t maxlen); |
238 | int tox_get_self_status_message(Tox *tox, uint8_t *buf, uint32_t maxlen); | 239 | int 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 | */ |
245 | uint8_t tox_get_user_status(Tox *tox, int32_t friendnumber); | 246 | uint8_t tox_get_user_status(const Tox *tox, int32_t friendnumber); |
246 | uint8_t tox_get_self_user_status(Tox *tox); | 247 | uint8_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 | */ |
252 | uint64_t tox_get_last_online(Tox *tox, int32_t friendnumber); | 253 | uint64_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 | */ |
267 | uint8_t tox_get_is_typing(Tox *tox, int32_t friendnumber); | 268 | uint8_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. */ |
277 | uint32_t tox_count_friendlist(Tox *tox); | 278 | uint32_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. */ |
280 | uint32_t tox_get_num_online_friends(Tox *tox); | 281 | uint32_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. */ |
287 | uint32_t tox_get_friendlist(Tox *tox, int32_t *out_list, uint32_t list_size); | 288 | uint32_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 | */ |
298 | void tox_callback_friend_message(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, uint16_t, void *), | 299 | void 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 | */ |
304 | void tox_callback_friend_action(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, uint16_t, void *), | 305 | void 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 | */ |
311 | void tox_callback_name_change(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, uint16_t, void *), | 312 | void 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 | */ |
318 | void tox_callback_status_message(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, uint16_t, void *), | 319 | void 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 | */ |
360 | uint32_t tox_get_nospam(Tox *tox); | 361 | uint32_t tox_get_nospam(const Tox *tox); |
361 | void tox_set_nospam(Tox *tox, uint32_t nospam); | 362 | void 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 | */ |
370 | void tox_callback_group_invite(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t *, void *), void *userdata); | 371 | void 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 | */ |
376 | void tox_callback_group_message(Tox *tox, void (*function)(Tox *tox, int, int, uint8_t *, uint16_t, void *), | 377 | void 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 | */ |
383 | void tox_callback_group_action(Tox *tox, void (*function)(Tox *tox, int, int, uint8_t *, uint16_t, void *), | 384 | void 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 | */ |
420 | int tox_group_peername(Tox *tox, int groupnumber, int peernumber, uint8_t *name); | 421 | int 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 | */ |
433 | int tox_join_groupchat(Tox *tox, int32_t friendnumber, uint8_t *friend_group_public_key); | 434 | int 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 | */ |
439 | int tox_group_message_send(Tox *tox, int groupnumber, uint8_t *message, uint32_t length); | 440 | int 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 | */ |
445 | int tox_group_action_send(Tox *tox, int groupnumber, uint8_t *action, uint32_t length); | 446 | int 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 | */ |
450 | int tox_group_number_peers(Tox *tox, int groupnumber); | 451 | int 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 | */ |
462 | int tox_group_get_names(Tox *tox, int groupnumber, uint8_t names[][TOX_MAX_NAME_LENGTH], uint16_t lengths[], | 463 | int 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. */ |
468 | uint32_t tox_count_chatlist(Tox *tox); | 469 | uint32_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. */ |
475 | uint32_t tox_get_chatlist(Tox *tox, int *out_list, uint32_t list_size); | 476 | uint32_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 | */ |
526 | void tox_callback_file_send_request(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint64_t, uint8_t *, uint16_t, | 527 | void 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 | */ |
537 | void tox_callback_file_control(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, | 538 | void 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 | */ |
545 | void tox_callback_file_data(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint8_t *, uint16_t length, void *), | 546 | void 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 | */ |
554 | int tox_new_file_sender(Tox *tox, int32_t friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length); | 555 | int 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 | */ |
564 | int tox_file_send_control(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, | 566 | int 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 | */ |
572 | int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length); | 574 | int 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 | */ |
579 | int tox_file_data_size(Tox *tox, int32_t friendnumber); | 581 | int 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 | */ |
588 | uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive); | 590 | uint64_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 | */ |
608 | int tox_bootstrap_from_address(Tox *tox, const char *address, uint8_t ipv6enabled, | 610 | int 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 | */ |
614 | int tox_isconnected(Tox *tox); | 616 | int 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). */ |
648 | uint32_t tox_size(Tox *tox); | 650 | uint32_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()). */ |
651 | void tox_save(Tox *tox, uint8_t *data); | 653 | void 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 | */ |
658 | int tox_load(Tox *tox, uint8_t *data, uint32_t length); | 660 | int 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 | ||
31 | static const char base32[32] = {"abcdefghijklmnopqrstuvwxyz012345"}; | 32 | static 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; |