summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL.md28
-rw-r--r--Makefile.am6
-rw-r--r--auto_tests/encryptsave_test.c24
-rw-r--r--auto_tests/tox_test.c44
-rw-r--r--auto_tests/toxav_basic_test.c6
-rw-r--r--auto_tests/toxav_many_test.c16
-rw-r--r--other/apidsl/tox.in.h57
-rw-r--r--other/apidsl/toxav.in.h11
-rw-r--r--other/bootstrap_daemon/README.md134
-rw-r--r--other/bootstrap_daemon/tox-bootstrapd.service8
-rw-r--r--testing/irc_syncbot.c2
-rw-r--r--testing/nTox.c14
-rw-r--r--testing/tox_shell.c2
-rw-r--r--testing/tox_sync.c2
-rw-r--r--toxav/toxav.c6
-rw-r--r--toxav/toxav.h150
-rw-r--r--toxav/video.c5
-rw-r--r--toxcore/Messenger.c11
-rw-r--r--toxcore/assoc.c18
-rw-r--r--toxcore/group.c2
-rw-r--r--toxcore/net_crypto.c4
-rw-r--r--toxcore/tox.c61
-rw-r--r--toxcore/tox.h67
-rw-r--r--toxencryptsave/toxencryptsave.c12
-rw-r--r--toxencryptsave/toxencryptsave.h8
25 files changed, 368 insertions, 330 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 549a3a4f..b7f1e5a0 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -2,6 +2,9 @@
2 2
3- [Installation](#installation) 3- [Installation](#installation)
4 - [Unix like](#unix) 4 - [Unix like](#unix)
5 - [Quick install](#quick-install)
6 - [Build manually](#build-manually)
7 - [Compile toxcore](#compile-toxcore)
5 - [OS X](#osx) 8 - [OS X](#osx)
6 - [Homebrew](#homebrew) 9 - [Homebrew](#homebrew)
7 - [Non-Homebrew](#non-homebrew) 10 - [Non-Homebrew](#non-homebrew)
@@ -24,16 +27,33 @@
24<a name="unix" /> 27<a name="unix" />
25###Most Unix like OSes: 28###Most Unix like OSes:
26 29
30#### Quick install:
31
32On Gentoo:
33```
34# layman -f && layman -a tox-overlay && emerge net-libs/tox
35```
36
37And you're done `:)`</br>
38If you happen to run some other distro which isn't made for compiling, there are steps below:
39
40#### Build manually
41
27Build dependencies: 42Build dependencies:
28 43
29Note: package fetching commands may vary by OS. 44Note: package fetching commands may vary by OS.
30 45
31On Ubuntu: 46On Ubuntu `< 15.04` / Debian `< 8`:
32 47
33```bash 48```bash
34sudo apt-get install build-essential libtool autotools-dev automake checkinstall check git yasm 49sudo apt-get install build-essential libtool autotools-dev automake checkinstall check git yasm
35``` 50```
36 51
52On Ubuntu `>= 15.04` / Debian `>= 8`:
53```bash
54sudo apt-get install build-essential libtool autotools-dev automake checkinstall check git yasm libsodium13 libsodium-dev
55```
56
37On Fedora: 57On Fedora:
38 58
39```bash 59```bash
@@ -55,7 +75,7 @@ Note, if you install from ports select NaCl for performance, and sodium if you w
55 75
56**For A/V support, also install the dependences listed in the [libtoxav] (#libtoxav) section.** 76**For A/V support, also install the dependences listed in the [libtoxav] (#libtoxav) section.**
57 77
58You should get and install [libsodium](https://github.com/jedisct1/libsodium): 78You should get and install [libsodium](https://github.com/jedisct1/libsodium). If you have installed `libsodium` from repo, ommit this step, and jump directly to [compiling toxcore](#compile-toxcore):
59```bash 79```bash
60git clone git://github.com/jedisct1/libsodium.git 80git clone git://github.com/jedisct1/libsodium.git
61cd libsodium 81cd libsodium
@@ -88,7 +108,9 @@ echo '/usr/local/lib/' | sudo tee -a /etc/ld.so.conf.d/locallib.conf
88sudo ldconfig 108sudo ldconfig
89``` 109```
90 110
91Then clone this repo and generate makefile: 111##### Compile toxcore
112
113Then clone this repo, generate makefile, and install `toxcore` system-wide:
92```bash 114```bash
93git clone git://github.com/irungentoo/toxcore.git 115git clone git://github.com/irungentoo/toxcore.git
94cd toxcore 116cd toxcore
diff --git a/Makefile.am b/Makefile.am
index 995620ef..7d5c788a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,9 +22,9 @@ EXTRA_DIST = \
22 $(top_srcdir)/docs/updates/Crypto.md \ 22 $(top_srcdir)/docs/updates/Crypto.md \
23 $(top_srcdir)/docs/updates/Spam-Prevention.md \ 23 $(top_srcdir)/docs/updates/Spam-Prevention.md \
24 $(top_srcdir)/docs/updates/Symmetric-NAT-Transversal.md \ 24 $(top_srcdir)/docs/updates/Symmetric-NAT-Transversal.md \
25 $(top_srcdir)/tools/README \ 25 $(top_srcdir)/other/astyle/README \
26 $(top_srcdir)/tools/astylerc \ 26 $(top_srcdir)/other/astyle/astylerc \
27 $(top_srcdir)/tools/pre-commit 27 $(top_srcdir)/other/astyle/pre-commit
28 28
29if BUILD_AV 29if BUILD_AV
30 30
diff --git a/auto_tests/encryptsave_test.c b/auto_tests/encryptsave_test.c
index a239bcee..d187e352 100644
--- a/auto_tests/encryptsave_test.c
+++ b/auto_tests/encryptsave_test.c
@@ -55,8 +55,8 @@ END_TEST
55 55
56START_TEST(test_save_friend) 56START_TEST(test_save_friend)
57{ 57{
58 Tox *tox1 = tox_new(0, 0, 0, 0); 58 Tox *tox1 = tox_new(0, 0);
59 Tox *tox2 = tox_new(0, 0, 0, 0); 59 Tox *tox2 = tox_new(0, 0);
60 ck_assert_msg(tox1 || tox2, "Failed to create 2 tox instances"); 60 ck_assert_msg(tox1 || tox2, "Failed to create 2 tox instances");
61 uint32_t to_compare = 974536; 61 uint32_t to_compare = 974536;
62 tox_callback_friend_request(tox2, accept_friend_request, &to_compare); 62 tox_callback_friend_request(tox2, accept_friend_request, &to_compare);
@@ -75,15 +75,23 @@ START_TEST(test_save_friend)
75 ck_assert_msg(ret, "failed to encrypted save: %u", error1); 75 ck_assert_msg(ret, "failed to encrypted save: %u", error1);
76 ck_assert_msg(tox_is_data_encrypted(enc_data), "magic number missing"); 76 ck_assert_msg(tox_is_data_encrypted(enc_data), "magic number missing");
77 77
78 struct Tox_Options options;
79 tox_options_default(&options);
80 options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE;
81 options.savedata_data = enc_data;
82 options.savedata_length = size2;
83
78 TOX_ERR_NEW err2; 84 TOX_ERR_NEW err2;
79 Tox *tox3 = tox_new(0, enc_data, size2, &err2); 85 Tox *tox3 = tox_new(&options, &err2);
80 ck_assert_msg(err2 == TOX_ERR_NEW_LOAD_ENCRYPTED, "wrong error! %u. should fail with %u", err2, 86 ck_assert_msg(err2 == TOX_ERR_NEW_LOAD_ENCRYPTED, "wrong error! %u. should fail with %u", err2,
81 TOX_ERR_NEW_LOAD_ENCRYPTED); 87 TOX_ERR_NEW_LOAD_ENCRYPTED);
82 uint8_t dec_data[size]; 88 uint8_t dec_data[size];
83 TOX_ERR_DECRYPTION err3; 89 TOX_ERR_DECRYPTION err3;
84 ret = tox_pass_decrypt(enc_data, size2, "correcthorsebatterystaple", 25, dec_data, &err3); 90 ret = tox_pass_decrypt(enc_data, size2, "correcthorsebatterystaple", 25, dec_data, &err3);
85 ck_assert_msg(ret, "failed to decrypt save: %u", err3); 91 ck_assert_msg(ret, "failed to decrypt save: %u", err3);
86 tox3 = tox_new(0, dec_data, size, &err2); 92 options.savedata_data = dec_data;
93 options.savedata_length = size;
94 tox3 = tox_new(&options, &err2);
87 ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to load from decrypted data: %u", err2); 95 ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to load from decrypted data: %u", err2);
88 uint8_t address2[TOX_PUBLIC_KEY_SIZE]; 96 uint8_t address2[TOX_PUBLIC_KEY_SIZE];
89 ret = tox_friend_get_public_key(tox3, 0, address2, 0); 97 ret = tox_friend_get_public_key(tox3, 0, address2, 0);
@@ -111,7 +119,9 @@ START_TEST(test_save_friend)
111 119
112 // and now with the code in use (I only bothered with manually to debug this, and it seems a waste 120 // and now with the code in use (I only bothered with manually to debug this, and it seems a waste
113 // to remove the manual check now that it's there) 121 // to remove the manual check now that it's there)
114 Tox *tox4 = tox_new(0, out1, size, &err2); 122 options.savedata_data = out1;
123 options.savedata_length = size;
124 Tox *tox4 = tox_new(&options, &err2);
115 ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to new the third"); 125 ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to new the third");
116 uint8_t address5[TOX_PUBLIC_KEY_SIZE]; 126 uint8_t address5[TOX_PUBLIC_KEY_SIZE];
117 ret = tox_friend_get_public_key(tox4, 0, address5, 0); 127 ret = tox_friend_get_public_key(tox4, 0, address5, 0);
@@ -154,6 +164,10 @@ START_TEST(test_keys)
154 ck_assert_msg(ret, "generic failure 5: %u", decerr); 164 ck_assert_msg(ret, "generic failure 5: %u", decerr);
155 ck_assert_msg(memcmp(out2, string, 44) == 0, "decryption 2 failed"); 165 ck_assert_msg(memcmp(out2, string, 44) == 0, "decryption 2 failed");
156 166
167 ret = tox_pass_decrypt(encrypted2, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, NULL, 0, out2, &decerr);
168 ck_assert_msg(!ret, "Decrypt succeeded with wrong pass");
169 ck_assert_msg(decerr != TOX_ERR_DECRYPTION_FAILED, "Bad error code %u", decerr);
170
157 // test that pass_decrypt can decrypt things from pass_key_encrypt 171 // test that pass_decrypt can decrypt things from pass_key_encrypt
158 ret = tox_pass_decrypt(encrypted, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, "123qweasdzxc", 12, out1, &decerr); 172 ret = tox_pass_decrypt(encrypted, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, "123qweasdzxc", 12, out1, &decerr);
159 ck_assert_msg(ret, "generic failure 6: %u", decerr); 173 ck_assert_msg(ret, "generic failure 6: %u", decerr);
diff --git a/auto_tests/tox_test.c b/auto_tests/tox_test.c
index 40022b0a..501c93dc 100644
--- a/auto_tests/tox_test.c
+++ b/auto_tests/tox_test.c
@@ -286,8 +286,8 @@ void tox_connection_status(Tox *tox, TOX_CONNECTION connection_status, void *use
286 286
287START_TEST(test_one) 287START_TEST(test_one)
288{ 288{
289 Tox *tox1 = tox_new(0, 0, 0, 0); 289 Tox *tox1 = tox_new(0, 0);
290 Tox *tox2 = tox_new(0, 0, 0, 0); 290 Tox *tox2 = tox_new(0, 0);
291 291
292 { 292 {
293 TOX_ERR_GET_PORT error; 293 TOX_ERR_GET_PORT error;
@@ -340,7 +340,12 @@ START_TEST(test_one)
340 tox_kill(tox2); 340 tox_kill(tox2);
341 TOX_ERR_NEW err_n; 341 TOX_ERR_NEW err_n;
342 342
343 tox2 = tox_new(0, data, save_size, &err_n); 343 struct Tox_Options options;
344 tox_options_default(&options);
345 options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE;
346 options.savedata_data = data;
347 options.savedata_length = save_size;
348 tox2 = tox_new(&options, &err_n);
344 ck_assert_msg(err_n == TOX_ERR_NEW_OK, "Load failed"); 349 ck_assert_msg(err_n == TOX_ERR_NEW_OK, "Load failed");
345 350
346 ck_assert_msg(tox_self_get_name_size(tox2) == sizeof name, "Wrong name size."); 351 ck_assert_msg(tox_self_get_name_size(tox2) == sizeof name, "Wrong name size.");
@@ -352,6 +357,23 @@ START_TEST(test_one)
352 tox_self_get_name(tox2, new_name); 357 tox_self_get_name(tox2, new_name);
353 ck_assert_msg(memcmp(name, new_name, TOX_MAX_NAME_LENGTH) == 0, "Wrong name"); 358 ck_assert_msg(memcmp(name, new_name, TOX_MAX_NAME_LENGTH) == 0, "Wrong name");
354 359
360 uint8_t sk[TOX_SECRET_KEY_SIZE];
361 tox_self_get_secret_key(tox2, sk);
362 tox_kill(tox2);
363
364 tox_options_default(&options);
365 options.savedata_type = TOX_SAVEDATA_TYPE_SECRET_KEY;
366 options.savedata_data = sk;
367 options.savedata_length = sizeof(sk);
368 tox2 = tox_new(&options, &err_n);
369 ck_assert_msg(err_n == TOX_ERR_NEW_OK, "Load failed");
370 uint8_t address3[TOX_ADDRESS_SIZE];
371 tox_self_get_address(tox2, address3);
372 ck_assert_msg(memcmp(address3, address, TOX_PUBLIC_KEY_SIZE) == 0, "Wrong public key.");
373 uint8_t pk[TOX_PUBLIC_KEY_SIZE];
374 tox_self_get_public_key(tox2, pk);
375 ck_assert_msg(memcmp(pk, address, TOX_PUBLIC_KEY_SIZE) == 0, "Wrong public key.");
376
355 tox_kill(tox1); 377 tox_kill(tox1);
356 tox_kill(tox2); 378 tox_kill(tox2);
357} 379}
@@ -361,11 +383,11 @@ START_TEST(test_few_clients)
361{ 383{
362 long long unsigned int con_time, cur_time = time(NULL); 384 long long unsigned int con_time, cur_time = time(NULL);
363 TOX_ERR_NEW t_n_error; 385 TOX_ERR_NEW t_n_error;
364 Tox *tox1 = tox_new(0, 0, 0, &t_n_error); 386 Tox *tox1 = tox_new(0, &t_n_error);
365 ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error"); 387 ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error");
366 Tox *tox2 = tox_new(0, 0, 0, &t_n_error); 388 Tox *tox2 = tox_new(0, &t_n_error);
367 ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error"); 389 ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error");
368 Tox *tox3 = tox_new(0, 0, 0, &t_n_error); 390 Tox *tox3 = tox_new(0, &t_n_error);
369 ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error"); 391 ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "wrong error");
370 392
371 ck_assert_msg(tox1 || tox2 || tox3, "Failed to create 3 tox instances"); 393 ck_assert_msg(tox1 || tox2 || tox3, "Failed to create 3 tox instances");
@@ -745,7 +767,7 @@ START_TEST(test_many_clients)
745 uint32_t to_comp = 974536; 767 uint32_t to_comp = 974536;
746 768
747 for (i = 0; i < NUM_TOXES; ++i) { 769 for (i = 0; i < NUM_TOXES; ++i) {
748 toxes[i] = tox_new(0, 0, 0, 0); 770 toxes[i] = tox_new(0, 0);
749 ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i); 771 ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i);
750 tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp); 772 tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp);
751 } 773 }
@@ -832,7 +854,7 @@ START_TEST(test_many_clients_tcp)
832 opts.udp_enabled = 0; 854 opts.udp_enabled = 0;
833 } 855 }
834 856
835 toxes[i] = tox_new(&opts, 0, 0, 0); 857 toxes[i] = tox_new(&opts, 0);
836 ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i); 858 ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i);
837 tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp); 859 tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp);
838 uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; 860 uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
@@ -926,7 +948,7 @@ START_TEST(test_many_clients_tcp_b)
926 opts.udp_enabled = 0; 948 opts.udp_enabled = 0;
927 } 949 }
928 950
929 toxes[i] = tox_new(&opts, 0, 0, 0); 951 toxes[i] = tox_new(&opts, 0);
930 ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i); 952 ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i);
931 tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp); 953 tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp);
932 uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; 954 uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
@@ -1062,7 +1084,7 @@ START_TEST(test_many_group)
1062 uint32_t to_comp = 234212; 1084 uint32_t to_comp = 234212;
1063 1085
1064 for (i = 0; i < NUM_GROUP_TOX; ++i) { 1086 for (i = 0; i < NUM_GROUP_TOX; ++i) {
1065 toxes[i] = tox_new(0, 0, 0, 0); 1087 toxes[i] = tox_new(0, 0);
1066 ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i); 1088 ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i);
1067 tox_callback_friend_request(toxes[i], &g_accept_friend_request, &to_comp); 1089 tox_callback_friend_request(toxes[i], &g_accept_friend_request, &to_comp);
1068 tox_callback_group_invite(toxes[i], &print_group_invite_callback, &to_comp); 1090 tox_callback_group_invite(toxes[i], &print_group_invite_callback, &to_comp);
@@ -1189,7 +1211,7 @@ Suite *tox_suite(void)
1189 1211
1190 DEFTESTCASE(one); 1212 DEFTESTCASE(one);
1191 DEFTESTCASE_SLOW(few_clients, 50); 1213 DEFTESTCASE_SLOW(few_clients, 50);
1192 DEFTESTCASE_SLOW(many_clients, 150); 1214 DEFTESTCASE_SLOW(many_clients, 80);
1193 DEFTESTCASE_SLOW(many_clients_tcp, 20); 1215 DEFTESTCASE_SLOW(many_clients_tcp, 20);
1194 DEFTESTCASE_SLOW(many_clients_tcp_b, 20); 1216 DEFTESTCASE_SLOW(many_clients_tcp_b, 20);
1195 DEFTESTCASE_SLOW(many_group, 100); 1217 DEFTESTCASE_SLOW(many_group, 100);
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c
index 79c5b724..a3847640 100644
--- a/auto_tests/toxav_basic_test.c
+++ b/auto_tests/toxav_basic_test.c
@@ -131,13 +131,13 @@ START_TEST(test_AV_flows)
131 { 131 {
132 TOX_ERR_NEW error; 132 TOX_ERR_NEW error;
133 133
134 bootstrap = tox_new(NULL, NULL, 0, &error); 134 bootstrap = tox_new(NULL, &error);
135 ck_assert(error == TOX_ERR_NEW_OK); 135 ck_assert(error == TOX_ERR_NEW_OK);
136 136
137 Alice = tox_new(NULL, NULL, 0, &error); 137 Alice = tox_new(NULL, &error);
138 ck_assert(error == TOX_ERR_NEW_OK); 138 ck_assert(error == TOX_ERR_NEW_OK);
139 139
140 Bob = tox_new(NULL, NULL, 0, &error); 140 Bob = tox_new(NULL, &error);
141 ck_assert(error == TOX_ERR_NEW_OK); 141 ck_assert(error == TOX_ERR_NEW_OK);
142 } 142 }
143 143
diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c
index a15acce3..761a4525 100644
--- a/auto_tests/toxav_many_test.c
+++ b/auto_tests/toxav_many_test.c
@@ -56,9 +56,7 @@ void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool
56} 56}
57void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data) 57void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data)
58{ 58{
59 (void) av; 59 printf("Handling CALL STATE callback: %d %p\n", state, av);
60
61 printf("Handling CALL STATE callback: %d\n", state);
62 ((CallControl*)user_data)[friend_number].state = state; 60 ((CallControl*)user_data)[friend_number].state = state;
63} 61}
64void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number, 62void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number,
@@ -188,7 +186,7 @@ void* call_thread(void* pd)
188 toxav_call_control(AliceAV, friend_number, TOXAV_CALL_CONTROL_CANCEL, &rc); 186 toxav_call_control(AliceAV, friend_number, TOXAV_CALL_CONTROL_CANCEL, &rc);
189 187
190 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { 188 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
191 printf("toxav_call_control failed: %d\n", rc); 189 printf("toxav_call_control failed: %d %p %p\n", rc, AliceAV, BobAV);
192 ck_assert(0); 190 ck_assert(0);
193 } 191 }
194 } 192 }
@@ -210,19 +208,19 @@ START_TEST(test_AV_three_calls)
210 { 208 {
211 TOX_ERR_NEW error; 209 TOX_ERR_NEW error;
212 210
213 bootstrap = tox_new(NULL, NULL, 0, &error); 211 bootstrap = tox_new(NULL, &error);
214 ck_assert(error == TOX_ERR_NEW_OK); 212 ck_assert(error == TOX_ERR_NEW_OK);
215 213
216 Alice = tox_new(NULL, NULL, 0, &error); 214 Alice = tox_new(NULL, &error);
217 ck_assert(error == TOX_ERR_NEW_OK); 215 ck_assert(error == TOX_ERR_NEW_OK);
218 216
219 Bobs[0] = tox_new(NULL, NULL, 0, &error); 217 Bobs[0] = tox_new(NULL, &error);
220 ck_assert(error == TOX_ERR_NEW_OK); 218 ck_assert(error == TOX_ERR_NEW_OK);
221 219
222 Bobs[1] = tox_new(NULL, NULL, 0, &error); 220 Bobs[1] = tox_new(NULL, &error);
223 ck_assert(error == TOX_ERR_NEW_OK); 221 ck_assert(error == TOX_ERR_NEW_OK);
224 222
225 Bobs[2] = tox_new(NULL, NULL, 0, &error); 223 Bobs[2] = tox_new(NULL, &error);
226 ck_assert(error == TOX_ERR_NEW_OK); 224 ck_assert(error == TOX_ERR_NEW_OK);
227 } 225 }
228 226
diff --git a/other/apidsl/tox.in.h b/other/apidsl/tox.in.h
index dd47df23..30c78e44 100644
--- a/other/apidsl/tox.in.h
+++ b/other/apidsl/tox.in.h
@@ -340,6 +340,24 @@ enum class PROXY_TYPE {
340 SOCKS5, 340 SOCKS5,
341} 341}
342 342
343/**
344 * Type of savedata to create the Tox instance from.
345 */
346enum class SAVEDATA_TYPE {
347 /**
348 * No savedata.
349 */
350 NONE,
351 /**
352 * Savedata is one that was obtained from ${savedata.get}
353 */
354 TOX_SAVE,
355 /**
356 * Savedata is a secret key of length ${SECRET_KEY_SIZE}
357 */
358 SECRET_KEY,
359}
360
343 361
344static class options { 362static class options {
345 /** 363 /**
@@ -416,6 +434,23 @@ static class options {
416 * The port to use for the TCP server. If 0, the tcp server is disabled. 434 * The port to use for the TCP server. If 0, the tcp server is disabled.
417 */ 435 */
418 uint16_t tcp_port; 436 uint16_t tcp_port;
437
438 namespace savedata {
439 /**
440 * The type of savedata to load from.
441 */
442 SAVEDATA_TYPE type;
443
444 /**
445 * The savedata.
446 */
447 const uint8_t[length] data;
448
449 /**
450 * The length of the savedata.
451 */
452 size_t length;
453 }
419 } 454 }
420 455
421 456
@@ -474,21 +509,17 @@ static class options {
474 * This function will bring the instance into a valid state. Running the event 509 * This function will bring the instance into a valid state. Running the event
475 * loop with a new instance will operate correctly. 510 * loop with a new instance will operate correctly.
476 * 511 *
477 * If the data parameter is not NULL, this function will load the Tox instance
478 * from a byte array previously filled by ${savedata.get}.
479 *
480 * If loading failed or succeeded only partially, the new or partially loaded 512 * If loading failed or succeeded only partially, the new or partially loaded
481 * instance is returned and an error code is set. 513 * instance is returned and an error code is set.
482 * 514 *
483 * @param options An options object as described above. If this parameter is 515 * @param options An options object as described above. If this parameter is
484 * NULL, the default options are used. 516 * NULL, the default options are used.
485 * @param data A byte array containing data previously stored by ${savedata.get}.
486 * @param length The length of the byte array data. If this parameter is 0, the
487 * data parameter is ignored.
488 * 517 *
489 * @see $iterate for the event loop. 518 * @see $iterate for the event loop.
519 *
520 * @return A new Tox instance pointer on success or NULL on failure.
490 */ 521 */
491static this new(const options_t *options, const uint8_t[length] data) { 522static this new(const options_t *options) {
492 NULL, 523 NULL,
493 /** 524 /**
494 * The function was unable to allocate enough memory to store the internal 525 * The function was unable to allocate enough memory to store the internal
@@ -580,13 +611,8 @@ uint8_t[size] savedata {
580 * Sends a "get nodes" request to the given bootstrap node with IP, port, and 611 * Sends a "get nodes" request to the given bootstrap node with IP, port, and
581 * public key to setup connections. 612 * public key to setup connections.
582 * 613 *
583 * This function will attempt to connect to the node using UDP and TCP at the 614 * This function will attempt to connect to the node using UDP. You must use
584 * same time. 615 * this function even if ${options.this.udp_enabled} was set to false.
585 *
586 * Tox will use the node as a TCP relay in case ${options.this.udp_enabled} was
587 * false, and also to connect to friends that are in TCP-only mode. Tox will
588 * also use the TCP connection when NAT hole punching is slow, and later switch
589 * to UDP if hole punching succeeds.
590 * 616 *
591 * @param address The hostname or IP address (IPv4 or IPv6) of the node. 617 * @param address The hostname or IP address (IPv4 or IPv6) of the node.
592 * @param port The port on the host on which the bootstrap Tox instance is 618 * @param port The port on the host on which the bootstrap Tox instance is
@@ -1481,7 +1507,7 @@ namespace file {
1481 */ 1507 */
1482 DATA, 1508 DATA,
1483 /** 1509 /**
1484 * Avatar filename. This consists of $hash(image). 1510 * Avatar file_id. This consists of $hash(image).
1485 * Avatar data. This consists of the image data. 1511 * Avatar data. This consists of the image data.
1486 * 1512 *
1487 * Avatars can be sent at any time the client wishes. Generally, a client will 1513 * Avatars can be sent at any time the client wishes. Generally, a client will
@@ -1625,6 +1651,7 @@ namespace file {
1625 1651
1626 1652
1627 error for get { 1653 error for get {
1654 NULL,
1628 /** 1655 /**
1629 * The friend_number passed did not designate a valid friend. 1656 * The friend_number passed did not designate a valid friend.
1630 */ 1657 */
diff --git a/other/apidsl/toxav.in.h b/other/apidsl/toxav.in.h
index bcf554ac..0631c827 100644
--- a/other/apidsl/toxav.in.h
+++ b/other/apidsl/toxav.in.h
@@ -562,10 +562,9 @@ namespace video {
562 * @param y Y (Luminance) plane data. 562 * @param y Y (Luminance) plane data.
563 * @param u U (Chroma) plane data. 563 * @param u U (Chroma) plane data.
564 * @param v V (Chroma) plane data. 564 * @param v V (Chroma) plane data.
565 * @param a A (Alpha) plane data.
566 */ 565 */
567 bool send_frame(uint32_t friend_number, uint16_t width, uint16_t height, 566 bool send_frame(uint32_t friend_number, uint16_t width, uint16_t height,
568 const uint8_t *y, const uint8_t *u, const uint8_t *v, const uint8_t *a) with error for send_frame; 567 const uint8_t *y, const uint8_t *u, const uint8_t *v) with error for send_frame;
569} 568}
570/******************************************************************************* 569/*******************************************************************************
571 * 570 *
@@ -603,19 +602,17 @@ namespace video {
603 * Y = MAX(width, abs(ystride)) * height, 602 * Y = MAX(width, abs(ystride)) * height,
604 * U = MAX(width/2, abs(ustride)) * (height/2) and 603 * U = MAX(width/2, abs(ustride)) * (height/2) and
605 * V = MAX(width/2, abs(vstride)) * (height/2). 604 * V = MAX(width/2, abs(vstride)) * (height/2).
606 * A = MAX(width, abs(astride)) * height.
607 * @param ystride 605 * @param ystride
608 * @param ustride 606 * @param ustride
609 * @param vstride 607 * @param vstride Strides data. Strides represent padding for each plane
610 * @param astride Strides data. Strides represent padding for each plane
611 * that may or may not be present. You must handle strides in 608 * that may or may not be present. You must handle strides in
612 * your image processing code. Strides are negative if the 609 * your image processing code. Strides are negative if the
613 * image is bottom-up hence why you MUST abs() it when 610 * image is bottom-up hence why you MUST abs() it when
614 * calculating plane buffer size. 611 * calculating plane buffer size.
615 */ 612 */
616 typedef void(uint32_t friend_number, uint16_t width, uint16_t height, 613 typedef void(uint32_t friend_number, uint16_t width, uint16_t height,
617 const uint8_t *y, const uint8_t *u, const uint8_t *v, const uint8_t *a, 614 const uint8_t *y, const uint8_t *u, const uint8_t *v,
618 int32_t ystride, int32_t ustride, int32_t vstride, int32_t astride); 615 int32_t ystride, int32_t ustride, int32_t vstride);
619 } 616 }
620} 617}
621 618
diff --git a/other/bootstrap_daemon/README.md b/other/bootstrap_daemon/README.md
index d0c16eb1..e77e3ae0 100644
--- a/other/bootstrap_daemon/README.md
+++ b/other/bootstrap_daemon/README.md
@@ -1,6 +1,17 @@
1##Instructions 1#Instructions
2 2
3This instruction primarily tested on Linux but, may be, will work on other POSIX-compliant systems. 3- [For `systemd` users](#systemd)
4 - [Troubleshooting](#systemd-troubleshooting)
5<br>
6- [For `init.d` users](#initd)
7 - [Troubleshooting](#initd-troubleshooting)
8
9
10These instructions are primarily tested on Debian Linux, Wheezy for init.d and Jessie for systemd, but they should work on other POSIX-compliant systems too.
11
12
13<a name="systemd" />
14##For `systemd` users:
4 15
5For security reasons we run the daemon under its own user. 16For security reasons we run the daemon under its own user.
6 17
@@ -9,100 +20,129 @@ Create a new user by executing the following:
9sudo useradd --home-dir /var/lib/tox-bootstrapd --create-home --system --shell /sbin/nologin --comment "Account to run Tox's DHT bootstrap daemon" --user-group tox-bootstrapd 20sudo useradd --home-dir /var/lib/tox-bootstrapd --create-home --system --shell /sbin/nologin --comment "Account to run Tox's DHT bootstrap daemon" --user-group tox-bootstrapd
10``` 21```
11 22
12Copy `tox-bootstrapd.conf` file to where `CFGFILE` variable from `tox-bootstrapd.sh` tells (for `init.d` users) or `ExecStart=` from `tox-bootstrap.service` ( for `systemd` users). By default it's `/etc/tox-bootstrapd.conf`.
13
14Go over everything in `tox-bootstrapd.conf`. Make sure `pid_file_path` matches `PIDFILE` from `tox-bootstrapd.sh` (`init.d`) or `PIDFile=` from `tox-bootstrap.service` AND file in `ExecStartPre`(`systemd`).
15
16
17Restrict access to home directory: 23Restrict access to home directory:
18```sh 24```sh
19sudo chmod 700 /var/lib/tox-bootstrapd 25sudo chmod 700 /var/lib/tox-bootstrapd
20``` 26```
21 27
22##For `init.d` users: 28Copy `tox-bootstrapd.conf` file to where `ExecStart=` from `tox-bootstrapd.service` points to. By default it's `/etc/tox-bootstrapd.conf`.
29```sh
30sudo cp tox-bootstrapd.conf /etc/tox-bootstrapd.conf
31```
23 32
24Look at the variable declarations in the beginning of `tox-bootstrapd.sh` init script to see if you need to change anything for it to work for you. The default values must be fine for most users and we assume that you use those next. 33Go over everything in the copied `tox-bootstrapd.conf` file. Set options you want and add actual working nodes to the `bootstrap_nodes` list, instead of the example ones, if you want your node to connect to the Tox network. Make sure `pid_file_path` matches `PIDFile=` from `tox-bootstrapd.service`.
25 34
26Copy `tox-bootstrapd.sh` init file to `/etc/init.d/tox-bootstrapd` (note the disappearance of ".sh" ending). 35Copy `tox-bootstrapd.service` to `/etc/systemd/system/`:
27```sh 36```sh
28sudo cp tox-bootstrapd.sh /etc/init.d/tox-bootstrapd 37sudo cp tox-bootstrapd.service /etc/systemd/system/
29``` 38```
30 39
31Set permissions for the init system to run the script: 40You must uncomment the next line in tox-bootstrapd.service, if you want to use port number < 1024
41
42 #CapabilityBoundingSet=CAP_NET_BIND_SERVICE
43
44and, possibly, install `libcap2-bin` or `libcap2` package, depending of your distribution.
45
46Reload systemd units definitions, enable service for automatic start (if needed), start it and verify it's running:
32```sh 47```sh
33sudo chmod 755 /etc/init.d/tox-bootstrapd 48sudo systemctl daemon-reload
49sudo systemctl enable tox-bootstrapd.service
50sudo systemctl start tox-bootstrapd.service
51sudo systemctl status tox-bootstrapd.service
34``` 52```
35 53
36Make the init system aware of the script: 54Get your public key and check that the daemon initialized correctly:
37```sh 55```sh
38sudo update-rc.d tox-bootstrapd defaults 56sudo grep "tox-bootstrapd" /var/log/syslog
39``` 57```
40 58
41Start the daemon: 59<a name="systemd-troubleshooting" />
60###Troubleshooting:
61
62- Check daemon's status:
42```sh 63```sh
43sudo service tox-bootstrapd start 64sudo systemctl status tox-bootstrapd.service
44``` 65```
45 66
46Verify it's running: 67- Check the log for errors:
47```sh 68```sh
48sudo service tox-bootstrapd status 69sudo grep "tox-bootstrapd" /var/log/syslog
70# or
71sudo journalctl --pager-end
72# or
73sudo journalctl -f _SYSTEMD_UNIT=tox-bootstrapd.service
49``` 74```
50 75
51Get your public key and check that the daemon initialized correctly: 76- Make sure tox-bootstrapd user has write permission for keys and pid files.
77
78- Make sure tox-bootstrapd has read permission for the config file.
79
80- Make sure tox-bootstrapd location matches its path in tox-bootstrapd.service file.
81
82
83<a name="initd" />
84##For `init.d` users
85
86For security reasons we run the daemon under its own user.
87
88Create a new user by executing the following:
52```sh 89```sh
53sudo grep "tox-bootstrapd" /var/log/syslog 90sudo useradd --home-dir /var/lib/tox-bootstrapd --create-home --system --shell /sbin/nologin --comment "Account to run Tox's DHT bootstrap daemon" --user-group tox-bootstrapd
54``` 91```
55 92
56##For `systemd` users: 93Restrict access to home directory:
94```sh
95sudo chmod 700 /var/lib/tox-bootstrapd
96```
57 97
58Copy tox-bootstrap.service to /etc/systemd/system/: 98Copy `tox-bootstrapd.conf` file to where `CFGFILE` variable from `tox-bootstrapd.sh` points to. By default it's `/etc/tox-bootstrapd.conf`.
59```sh 99```sh
60sudo cp tox-bootstrap.service /etc/systemd/system/ 100sudo cp tox-bootstrapd.conf /etc/tox-bootstrapd.conf
61``` 101```
62 102
63Make sure, that path to `chown` and `mkdir` is correct in `tox-bootstrap.service` (they may be different in some distributions, by default `/bin/chown` and `/bin/mkdir`) 103Go over everything in the copied `tox-bootstrapd.conf` file. Set options you want and add actual working nodes to the `bootstrap_nodes` list, instead of the example ones, if you want your node to connect to the Tox network. Make sure `pid_file_path` matches `PIDFILE` from `tox-bootstrapd.sh`.
64 104
65You must uncomment the next line in tox-bootstrap.service, if you want to use port number <1024 105Look at the variable declarations in the beginning of `tox-bootstrapd.sh` init script to see if you need to change anything for it to work on your system. The default values must be fine for most users and we assume that you use those next.
66
67 #CapabilityBoundingSet=CAP_NET_BIND_SERVICE
68 106
69and, possibly, install `libcap2-bin` or `libcap2` package, depending of your distribution. 107Copy `tox-bootstrapd.sh` init script to `/etc/init.d/tox-bootstrapd` (note the disappearance of ".sh" ending):
108```sh
109sudo cp tox-bootstrapd.sh /etc/init.d/tox-bootstrapd
110```
70 111
112Set permissions for the init system to run the script:
113```sh
114sudo chmod 755 /etc/init.d/tox-bootstrapd
115```
71 116
72Reload systemd units definitions, enable service for automatic start (if needed), and start it: 117Make the init system aware of the script, start the daemon and verify it's running:
73```sh 118```sh
74sudo systemctl daemon-reload 119sudo update-rc.d tox-bootstrapd defaults
75sudo systemctl enable tox-bootstrap.service 120sudo service tox-bootstrapd start
76sudo systemctl start tox-bootstrap.service 121sudo service tox-bootstrapd status
122```
123
124Get your public key and check that the daemon initialized correctly:
125```sh
126sudo grep "tox-bootstrapd" /var/log/syslog
77``` 127```
128
129<a name="initd-troubleshooting" />
78###Troubleshooting: 130###Troubleshooting:
79 131
80- Check daemon's status: 132- Check daemon's status:
81```sh 133```sh
82#init.d
83sudo service tox-bootstrapd status 134sudo service tox-bootstrapd status
84
85#systemd
86sudo systemctl status tox-bootstrap.service
87``` 135```
88 136
89- Check the log for errors: 137- Check the log for errors:
90```sh 138```sh
91#init.d
92sudo grep "tox-bootstrapd" /var/log/syslog 139sudo grep "tox-bootstrapd" /var/log/syslog
93
94#systemd
95sudo journalctl -f _SYSTEMD_UNIT=tox-bootstrap.service
96``` 140```
97 141
98`init.d`:
99- Check that variables in the beginning of `/etc/init.d/tox-bootstrapd` are valid. 142- Check that variables in the beginning of `/etc/init.d/tox-bootstrapd` are valid.
100 143
101 144- Make sure tox-bootstrapd user has write permission for keys and pid files.
102Common:
103
104- Make sure tox-bootstrapd user has write permission for keys and pid files (in systemd pid file insured by unit definition).
105 145
106- Make sure tox-bootstrapd has read permission for the config file. 146- Make sure tox-bootstrapd has read permission for the config file.
107 147
108- Make sure tox-bootstrapd location matches its path in init scripts, if you specified non-default `--prefix`, when building. 148- Make sure tox-bootstrapd location matches its path in the `/etc/init.d/tox-bootstrapd` init script.
diff --git a/other/bootstrap_daemon/tox-bootstrapd.service b/other/bootstrap_daemon/tox-bootstrapd.service
index 4b499311..db54cc41 100644
--- a/other/bootstrap_daemon/tox-bootstrapd.service
+++ b/other/bootstrap_daemon/tox-bootstrapd.service
@@ -4,16 +4,14 @@ After=network.target
4 4
5[Service] 5[Service]
6Type=forking 6Type=forking
7PermissionsStartOnly=true 7RuntimeDirectory=tox-bootstrapd
8ExecStartPre=-/bin/mkdir /var/run/tox-bootstrapd -p 8RuntimeDirectoryMode=750
9ExecStartPre=/bin/chown tox-bootstrapd:tox-bootstrapd -R /var/run/tox-bootstrapd 9PIDFile=/var/run/tox-bootstrapd/tox-bootstrapd.pid
10WorkingDirectory=/var/lib/tox-bootstrapd 10WorkingDirectory=/var/lib/tox-bootstrapd
11ExecStart=/usr/local/bin/tox-bootstrapd /etc/tox-bootstrapd.conf 11ExecStart=/usr/local/bin/tox-bootstrapd /etc/tox-bootstrapd.conf
12User=tox-bootstrapd 12User=tox-bootstrapd
13Group=tox-bootstrapd 13Group=tox-bootstrapd
14PIDFile=/var/run/tox-bootstrapd/tox-bootstrapd.pid
15#CapabilityBoundingSet=CAP_NET_BIND_SERVICE 14#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
16 15
17[Install] 16[Install]
18WantedBy=multi-user.target 17WantedBy=multi-user.target
19
diff --git a/testing/irc_syncbot.c b/testing/irc_syncbot.c
index 2d326c4b..a4e2254a 100644
--- a/testing/irc_syncbot.c
+++ b/testing/irc_syncbot.c
@@ -222,7 +222,7 @@ Tox *init_tox(int argc, char *argv[])
222 exit(0); 222 exit(0);
223 } 223 }
224 224
225 Tox *tox = tox_new(0, 0, 0, 0); 225 Tox *tox = tox_new(0, 0);
226 226
227 if (!tox) 227 if (!tox)
228 exit(1); 228 exit(1);
diff --git a/testing/nTox.c b/testing/nTox.c
index 77f812b5..03f17da5 100644
--- a/testing/nTox.c
+++ b/testing/nTox.c
@@ -942,7 +942,17 @@ static Tox *load_data()
942 return 0; 942 return 0;
943 } 943 }
944 944
945 Tox *m = tox_new(0, data, size, NULL); 945 struct Tox_Options options;
946
947 tox_options_default(&options);
948
949 options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE;
950
951 options.savedata_data = data;
952
953 options.savedata_length = size;
954
955 Tox *m = tox_new(&options, NULL);
946 956
947 if (fclose(data_file) < 0) { 957 if (fclose(data_file) < 0) {
948 perror("[!] fclose failed"); 958 perror("[!] fclose failed");
@@ -953,7 +963,7 @@ static Tox *load_data()
953 return m; 963 return m;
954 } 964 }
955 965
956 return tox_new(0, 0, 0, NULL); 966 return tox_new(NULL, NULL);
957} 967}
958 968
959static int save_data(Tox *m) 969static int save_data(Tox *m)
diff --git a/testing/tox_shell.c b/testing/tox_shell.c
index 23fa320a..521e9f36 100644
--- a/testing/tox_shell.c
+++ b/testing/tox_shell.c
@@ -95,7 +95,7 @@ int main(int argc, char *argv[])
95 printf("error setting flags\n"); 95 printf("error setting flags\n");
96 } 96 }
97 97
98 Tox *tox = tox_new(0, 0, 0, 0); 98 Tox *tox = tox_new(0, 0);
99 tox_callback_friend_connection_status(tox, print_online, NULL); 99 tox_callback_friend_connection_status(tox, print_online, NULL);
100 tox_callback_friend_message(tox, print_message, master); 100 tox_callback_friend_message(tox, print_message, master);
101 101
diff --git a/testing/tox_sync.c b/testing/tox_sync.c
index be1fe32d..738c2f2d 100644
--- a/testing/tox_sync.c
+++ b/testing/tox_sync.c
@@ -243,7 +243,7 @@ int main(int argc, char *argv[])
243 exit(0); 243 exit(0);
244 } 244 }
245 245
246 Tox *tox = tox_new(0, 0, 0, 0); 246 Tox *tox = tox_new(0, 0);
247 tox_callback_file_recv_chunk(tox, write_file, NULL); 247 tox_callback_file_recv_chunk(tox, write_file, NULL);
248 tox_callback_file_recv_control(tox, file_print_control, NULL); 248 tox_callback_file_recv_control(tox, file_print_control, NULL);
249 tox_callback_file_recv(tox, file_request_accept, NULL); 249 tox_callback_file_recv(tox, file_request_accept, NULL);
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 7ce6b9bc..35523319 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -807,7 +807,7 @@ END:
807 return rc == TOXAV_ERR_SEND_FRAME_OK; 807 return rc == TOXAV_ERR_SEND_FRAME_OK;
808} 808}
809 809
810bool toxav_video_send_frame(ToxAV* av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t* y, const uint8_t* u, const uint8_t* v, const uint8_t* a,TOXAV_ERR_SEND_FRAME* error) 810bool toxav_video_send_frame(ToxAV* av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t* y, const uint8_t* u, const uint8_t* v, TOXAV_ERR_SEND_FRAME* error)
811{ 811{
812 TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK; 812 TOXAV_ERR_SEND_FRAME rc = TOXAV_ERR_SEND_FRAME_OK;
813 ToxAVCall* call; 813 ToxAVCall* call;
@@ -852,10 +852,6 @@ bool toxav_video_send_frame(ToxAV* av, uint32_t friend_number, uint16_t width, u
852 memcpy(img.planes[VPX_PLANE_U], u, (width/2) * (height/2)); 852 memcpy(img.planes[VPX_PLANE_U], u, (width/2) * (height/2));
853 memcpy(img.planes[VPX_PLANE_V], v, (width/2) * (height/2)); 853 memcpy(img.planes[VPX_PLANE_V], v, (width/2) * (height/2));
854 854
855 /* TODO LOL */
856 if (a && img.planes[VPX_PLANE_ALPHA])
857 memcpy(img.planes[VPX_PLANE_ALPHA], a, width * height);
858
859 int vrc = vpx_codec_encode(call->video.second->encoder, &img, 855 int vrc = vpx_codec_encode(call->video.second->encoder, &img,
860 call->video.second->frame_counter, 1, 0, MAX_ENCODE_TIME_US); 856 call->video.second->frame_counter, 1, 0, MAX_ENCODE_TIME_US);
861 857
diff --git a/toxav/toxav.h b/toxav/toxav.h
index c75f8bff..0b9be241 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -82,35 +82,27 @@ typedef struct Tox Tox;
82#define TOXAV_DEFINED 82#define TOXAV_DEFINED
83typedef struct ToxAV ToxAV; 83typedef struct ToxAV ToxAV;
84#endif /* TOXAV_DEFINED */ 84#endif /* TOXAV_DEFINED */
85
86
87/******************************************************************************* 85/*******************************************************************************
88 * 86 *
89 * :: API version 87 * :: API version
90 * 88 *
91 ******************************************************************************/ 89 ******************************************************************************/
92
93
94
95/** 90/**
96 * The major version number. Incremented when the API or ABI changes in an 91 * The major version number. Incremented when the API or ABI changes in an
97 * incompatible way. 92 * incompatible way.
98 */ 93 */
99#define TOXAV_VERSION_MAJOR 0u 94#define TOXAV_VERSION_MAJOR 0u
100
101/** 95/**
102 * The minor version number. Incremented when functionality is added without 96 * The minor version number. Incremented when functionality is added without
103 * breaking the API or ABI. Set to 0 when the major version number is 97 * breaking the API or ABI. Set to 0 when the major version number is
104 * incremented. 98 * incremented.
105 */ 99 */
106#define TOXAV_VERSION_MINOR 0u 100#define TOXAV_VERSION_MINOR 0u
107
108/** 101/**
109 * The patch or revision number. Incremented when bugfixes are applied without 102 * The patch or revision number. Incremented when bugfixes are applied without
110 * changing any functionality or API or ABI. 103 * changing any functionality or API or ABI.
111 */ 104 */
112#define TOXAV_VERSION_PATCH 0u 105#define TOXAV_VERSION_PATCH 0u
113
114/** 106/**
115 * A macro to check at preprocessing time whether the client code is compatible 107 * A macro to check at preprocessing time whether the client code is compatible
116 * with the installed version of ToxAV. 108 * with the installed version of ToxAV.
@@ -120,84 +112,65 @@ typedef struct ToxAV ToxAV;
120 (TOXAV_VERSION_MINOR > MINOR || \ 112 (TOXAV_VERSION_MINOR > MINOR || \
121 (TOXAV_VERSION_MINOR == MINOR && \ 113 (TOXAV_VERSION_MINOR == MINOR && \
122 TOXAV_VERSION_PATCH >= PATCH))) 114 TOXAV_VERSION_PATCH >= PATCH)))
123
124/** 115/**
125 * A macro to make compilation fail if the client code is not compatible with 116 * A macro to make compilation fail if the client code is not compatible with
126 * the installed version of ToxAV. 117 * the installed version of ToxAV.
127 */ 118 */
128#define TOXAV_VERSION_REQUIRE(MAJOR, MINOR, PATCH) \ 119#define TOXAV_VERSION_REQUIRE(MAJOR, MINOR, PATCH) \
129 typedef char toxav_required_version[TOXAV_IS_COMPATIBLE(MAJOR, MINOR, PATCH) ? 1 : -1] 120 typedef char toxav_required_version[TOXAV_IS_COMPATIBLE(MAJOR, MINOR, PATCH) ? 1 : -1]
130
131/** 121/**
132 * A convenience macro to call toxav_version_is_compatible with the currently 122 * A convenience macro to call toxav_version_is_compatible with the currently
133 * compiling API version. 123 * compiling API version.
134 */ 124 */
135#define TOXAV_VERSION_IS_ABI_COMPATIBLE() \ 125#define TOXAV_VERSION_IS_ABI_COMPATIBLE() \
136 toxav_version_is_compatible(TOXAV_VERSION_MAJOR, TOXAV_VERSION_MINOR, TOXAV_VERSION_PATCH) 126 toxav_version_is_compatible(TOXAV_VERSION_MAJOR, TOXAV_VERSION_MINOR, TOXAV_VERSION_PATCH)
137
138/** 127/**
139 * Return the major version number of the library. Can be used to display the 128 * Return the major version number of the library. Can be used to display the
140 * ToxAV library version or to check whether the client is compatible with the 129 * ToxAV library version or to check whether the client is compatible with the
141 * dynamically linked version of ToxAV. 130 * dynamically linked version of ToxAV.
142 */ 131 */
143uint32_t toxav_version_major(void); 132uint32_t toxav_version_major(void);
144
145/** 133/**
146 * Return the minor version number of the library. 134 * Return the minor version number of the library.
147 */ 135 */
148uint32_t toxav_version_minor(void); 136uint32_t toxav_version_minor(void);
149
150/** 137/**
151 * Return the patch number of the library. 138 * Return the patch number of the library.
152 */ 139 */
153uint32_t toxav_version_patch(void); 140uint32_t toxav_version_patch(void);
154
155/** 141/**
156 * Return whether the compiled library version is compatible with the passed 142 * Return whether the compiled library version is compatible with the passed
157 * version numbers. 143 * version numbers.
158 */ 144 */
159bool toxav_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch); 145bool toxav_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
160
161
162/******************************************************************************* 146/*******************************************************************************
163 * 147 *
164 * :: Creation and destruction 148 * :: Creation and destruction
165 * 149 *
166 ******************************************************************************/ 150 ******************************************************************************/
167
168
169
170typedef enum TOXAV_ERR_NEW { 151typedef enum TOXAV_ERR_NEW {
171
172 /** 152 /**
173 * The function returned successfully. 153 * The function returned successfully.
174 */ 154 */
175 TOXAV_ERR_NEW_OK, 155 TOXAV_ERR_NEW_OK,
176
177 /** 156 /**
178 * One of the arguments to the function was NULL when it was not expected. 157 * One of the arguments to the function was NULL when it was not expected.
179 */ 158 */
180 TOXAV_ERR_NEW_NULL, 159 TOXAV_ERR_NEW_NULL,
181
182 /** 160 /**
183 * Memory allocation failure while trying to allocate structures required for 161 * Memory allocation failure while trying to allocate structures required for
184 * the A/V session. 162 * the A/V session.
185 */ 163 */
186 TOXAV_ERR_NEW_MALLOC, 164 TOXAV_ERR_NEW_MALLOC,
187
188 /** 165 /**
189 * Attempted to create a second session for the same Tox instance. 166 * Attempted to create a second session for the same Tox instance.
190 */ 167 */
191 TOXAV_ERR_NEW_MULTIPLE, 168 TOXAV_ERR_NEW_MULTIPLE,
192
193} TOXAV_ERR_NEW; 169} TOXAV_ERR_NEW;
194
195
196/** 170/**
197 * Start new A/V session. There can only be only one session per Tox instance. 171 * Start new A/V session. There can only be only one session per Tox instance.
198 */ 172 */
199ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error); 173ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error);
200
201/** 174/**
202 * Releases all resources associated with the A/V session. 175 * Releases all resources associated with the A/V session.
203 * 176 *
@@ -206,80 +179,59 @@ ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error);
206 * called and the av pointer becomes invalid. 179 * called and the av pointer becomes invalid.
207 */ 180 */
208void toxav_kill(ToxAV *toxAV); 181void toxav_kill(ToxAV *toxAV);
209
210/** 182/**
211 * Returns the Tox instance the A/V object was created for. 183 * Returns the Tox instance the A/V object was created for.
212 */ 184 */
213Tox *toxav_get_tox(const ToxAV *toxAV); 185Tox *toxav_get_tox(const ToxAV *toxAV);
214
215
216/******************************************************************************* 186/*******************************************************************************
217 * 187 *
218 * :: A/V event loop 188 * :: A/V event loop
219 * 189 *
220 ******************************************************************************/ 190 ******************************************************************************/
221
222
223
224/** 191/**
225 * Returns the interval in milliseconds when the next toxav_iterate call should 192 * Returns the interval in milliseconds when the next toxav_iterate call should
226 * be. If no call is active at the moment, this function returns 200. 193 * be. If no call is active at the moment, this function returns 200.
227 */ 194 */
228uint32_t toxav_iteration_interval(const ToxAV *toxAV); 195uint32_t toxav_iteration_interval(const ToxAV *toxAV);
229
230/** 196/**
231 * Main loop for the session. This function needs to be called in intervals of 197 * Main loop for the session. This function needs to be called in intervals of
232 * toxav_iteration_interval() milliseconds. It is best called in the separate 198 * toxav_iteration_interval() milliseconds. It is best called in the separate
233 * thread from tox_iterate. 199 * thread from tox_iterate.
234 */ 200 */
235void toxav_iterate(ToxAV *toxAV); 201void toxav_iterate(ToxAV *toxAV);
236
237
238/******************************************************************************* 202/*******************************************************************************
239 * 203 *
240 * :: Call setup 204 * :: Call setup
241 * 205 *
242 ******************************************************************************/ 206 ******************************************************************************/
243
244
245
246typedef enum TOXAV_ERR_CALL { 207typedef enum TOXAV_ERR_CALL {
247
248 /** 208 /**
249 * The function returned successfully. 209 * The function returned successfully.
250 */ 210 */
251 TOXAV_ERR_CALL_OK, 211 TOXAV_ERR_CALL_OK,
252
253 /** 212 /**
254 * A resource allocation error occurred while trying to create the structures 213 * A resource allocation error occurred while trying to create the structures
255 * required for the call. 214 * required for the call.
256 */ 215 */
257 TOXAV_ERR_CALL_MALLOC, 216 TOXAV_ERR_CALL_MALLOC,
258
259 /** 217 /**
260 * The friend number did not designate a valid friend. 218 * The friend number did not designate a valid friend.
261 */ 219 */
262 TOXAV_ERR_CALL_FRIEND_NOT_FOUND, 220 TOXAV_ERR_CALL_FRIEND_NOT_FOUND,
263
264 /** 221 /**
265 * The friend was valid, but not currently connected. 222 * The friend was valid, but not currently connected.
266 */ 223 */
267 TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED, 224 TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED,
268
269 /** 225 /**
270 * Attempted to call a friend while already in an audio or video call with 226 * Attempted to call a friend while already in an audio or video call with
271 * them. 227 * them.
272 */ 228 */
273 TOXAV_ERR_CALL_FRIEND_ALREADY_IN_CALL, 229 TOXAV_ERR_CALL_FRIEND_ALREADY_IN_CALL,
274
275 /** 230 /**
276 * Audio or video bit rate is invalid. 231 * Audio or video bit rate is invalid.
277 */ 232 */
278 TOXAV_ERR_CALL_INVALID_BIT_RATE, 233 TOXAV_ERR_CALL_INVALID_BIT_RATE,
279
280} TOXAV_ERR_CALL; 234} TOXAV_ERR_CALL;
281
282
283/** 235/**
284 * Call a friend. This will start ringing the friend. 236 * Call a friend. This will start ringing the friend.
285 * 237 *
@@ -294,7 +246,6 @@ typedef enum TOXAV_ERR_CALL {
294 * video sending. 246 * video sending.
295 */ 247 */
296bool toxav_call(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL *error); 248bool toxav_call(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL *error);
297
298/** 249/**
299 * The function type for the call callback. 250 * The function type for the call callback.
300 * 251 *
@@ -303,47 +254,36 @@ bool toxav_call(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, u
303 * @param video_enabled True if friend is sending video. 254 * @param video_enabled True if friend is sending video.
304 */ 255 */
305typedef void toxav_call_cb(ToxAV *toxAV, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data); 256typedef void toxav_call_cb(ToxAV *toxAV, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data);
306
307
308/** 257/**
309 * Set the callback for the `call` event. Pass NULL to unset. 258 * Set the callback for the `call` event. Pass NULL to unset.
310 * 259 *
311 */ 260 */
312void toxav_callback_call(ToxAV *toxAV, toxav_call_cb *callback, void *user_data); 261void toxav_callback_call(ToxAV *toxAV, toxav_call_cb *callback, void *user_data);
313
314typedef enum TOXAV_ERR_ANSWER { 262typedef enum TOXAV_ERR_ANSWER {
315
316 /** 263 /**
317 * The function returned successfully. 264 * The function returned successfully.
318 */ 265 */
319 TOXAV_ERR_ANSWER_OK, 266 TOXAV_ERR_ANSWER_OK,
320
321 /** 267 /**
322 * Failed to initialize codecs for call session. Note that codec initiation 268 * Failed to initialize codecs for call session. Note that codec initiation
323 * will fail if there is no receive callback registered for either audio or 269 * will fail if there is no receive callback registered for either audio or
324 * video. 270 * video.
325 */ 271 */
326 TOXAV_ERR_ANSWER_CODEC_INITIALIZATION, 272 TOXAV_ERR_ANSWER_CODEC_INITIALIZATION,
327
328 /** 273 /**
329 * The friend number did not designate a valid friend. 274 * The friend number did not designate a valid friend.
330 */ 275 */
331 TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND, 276 TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND,
332
333 /** 277 /**
334 * The friend was valid, but they are not currently trying to initiate a call. 278 * The friend was valid, but they are not currently trying to initiate a call.
335 * This is also returned if this client is already in a call with the friend. 279 * This is also returned if this client is already in a call with the friend.
336 */ 280 */
337 TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING, 281 TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING,
338
339 /** 282 /**
340 * Audio or video bit rate is invalid. 283 * Audio or video bit rate is invalid.
341 */ 284 */
342 TOXAV_ERR_ANSWER_INVALID_BIT_RATE, 285 TOXAV_ERR_ANSWER_INVALID_BIT_RATE,
343
344} TOXAV_ERR_ANSWER; 286} TOXAV_ERR_ANSWER;
345
346
347/** 287/**
348 * Accept an incoming call. 288 * Accept an incoming call.
349 * 289 *
@@ -357,18 +297,12 @@ typedef enum TOXAV_ERR_ANSWER {
357 * video sending. 297 * video sending.
358 */ 298 */
359bool toxav_answer(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_ANSWER *error); 299bool toxav_answer(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_ANSWER *error);
360
361
362/******************************************************************************* 300/*******************************************************************************
363 * 301 *
364 * :: Call state graph 302 * :: Call state graph
365 * 303 *
366 ******************************************************************************/ 304 ******************************************************************************/
367
368
369
370enum TOXAV_CALL_STATE { 305enum TOXAV_CALL_STATE {
371
372 /** 306 /**
373 * Set by the AV core if an error occurred on the remote end or if friend 307 * Set by the AV core if an error occurred on the remote end or if friend
374 * timed out. This is the final state after which no more state 308 * timed out. This is the final state after which no more state
@@ -376,34 +310,28 @@ enum TOXAV_CALL_STATE {
376 * in combination with other call states. 310 * in combination with other call states.
377 */ 311 */
378 TOXAV_CALL_STATE_ERROR = 1, 312 TOXAV_CALL_STATE_ERROR = 1,
379
380 /** 313 /**
381 * The call has finished. This is the final state after which no more state 314 * The call has finished. This is the final state after which no more state
382 * transitions can occur for the call. This call state will never be 315 * transitions can occur for the call. This call state will never be
383 * triggered in combination with other call states. 316 * triggered in combination with other call states.
384 */ 317 */
385 TOXAV_CALL_STATE_FINISHED = 2, 318 TOXAV_CALL_STATE_FINISHED = 2,
386
387 /** 319 /**
388 * The flag that marks that friend is sending audio. 320 * The flag that marks that friend is sending audio.
389 */ 321 */
390 TOXAV_CALL_STATE_SENDING_A = 4, 322 TOXAV_CALL_STATE_SENDING_A = 4,
391
392 /** 323 /**
393 * The flag that marks that friend is sending video. 324 * The flag that marks that friend is sending video.
394 */ 325 */
395 TOXAV_CALL_STATE_SENDING_V = 8, 326 TOXAV_CALL_STATE_SENDING_V = 8,
396
397 /** 327 /**
398 * The flag that marks that friend is receiving audio. 328 * The flag that marks that friend is receiving audio.
399 */ 329 */
400 TOXAV_CALL_STATE_RECEIVING_A = 16, 330 TOXAV_CALL_STATE_RECEIVING_A = 16,
401
402 /** 331 /**
403 * The flag that marks that friend is receiving video. 332 * The flag that marks that friend is receiving video.
404 */ 333 */
405 TOXAV_CALL_STATE_RECEIVING_V = 32, 334 TOXAV_CALL_STATE_RECEIVING_V = 32,
406
407}; 335};
408 336
409 337
@@ -415,96 +343,72 @@ enum TOXAV_CALL_STATE {
415 * the previous state. The state is set to 0 when the call is paused. 343 * the previous state. The state is set to 0 when the call is paused.
416 */ 344 */
417typedef void toxav_call_state_cb(ToxAV *toxAV, uint32_t friend_number, uint32_t state, void *user_data); 345typedef void toxav_call_state_cb(ToxAV *toxAV, uint32_t friend_number, uint32_t state, void *user_data);
418
419
420/** 346/**
421 * Set the callback for the `call_state` event. Pass NULL to unset. 347 * Set the callback for the `call_state` event. Pass NULL to unset.
422 * 348 *
423 */ 349 */
424void toxav_callback_call_state(ToxAV *toxAV, toxav_call_state_cb *callback, void *user_data); 350void toxav_callback_call_state(ToxAV *toxAV, toxav_call_state_cb *callback, void *user_data);
425
426
427/******************************************************************************* 351/*******************************************************************************
428 * 352 *
429 * :: Call control 353 * :: Call control
430 * 354 *
431 ******************************************************************************/ 355 ******************************************************************************/
432
433
434
435typedef enum TOXAV_CALL_CONTROL { 356typedef enum TOXAV_CALL_CONTROL {
436
437 /** 357 /**
438 * Resume a previously paused call. Only valid if the pause was caused by this 358 * Resume a previously paused call. Only valid if the pause was caused by this
439 * client, if not, this control is ignored. Not valid before the call is accepted. 359 * client, if not, this control is ignored. Not valid before the call is accepted.
440 */ 360 */
441 TOXAV_CALL_CONTROL_RESUME, 361 TOXAV_CALL_CONTROL_RESUME,
442
443 /** 362 /**
444 * Put a call on hold. Not valid before the call is accepted. 363 * Put a call on hold. Not valid before the call is accepted.
445 */ 364 */
446 TOXAV_CALL_CONTROL_PAUSE, 365 TOXAV_CALL_CONTROL_PAUSE,
447
448 /** 366 /**
449 * Reject a call if it was not answered, yet. Cancel a call after it was 367 * Reject a call if it was not answered, yet. Cancel a call after it was
450 * answered. 368 * answered.
451 */ 369 */
452 TOXAV_CALL_CONTROL_CANCEL, 370 TOXAV_CALL_CONTROL_CANCEL,
453
454 /** 371 /**
455 * Request that the friend stops sending audio. Regardless of the friend's 372 * Request that the friend stops sending audio. Regardless of the friend's
456 * compliance, this will cause the audio_receive_frame event to stop being 373 * compliance, this will cause the audio_receive_frame event to stop being
457 * triggered on receiving an audio frame from the friend. 374 * triggered on receiving an audio frame from the friend.
458 */ 375 */
459 TOXAV_CALL_CONTROL_MUTE_AUDIO, 376 TOXAV_CALL_CONTROL_MUTE_AUDIO,
460
461 /** 377 /**
462 * Calling this control will notify client to start sending audio again. 378 * Calling this control will notify client to start sending audio again.
463 */ 379 */
464 TOXAV_CALL_CONTROL_UNMUTE_AUDIO, 380 TOXAV_CALL_CONTROL_UNMUTE_AUDIO,
465
466 /** 381 /**
467 * Request that the friend stops sending video. Regardless of the friend's 382 * Request that the friend stops sending video. Regardless of the friend's
468 * compliance, this will cause the video_receive_frame event to stop being 383 * compliance, this will cause the video_receive_frame event to stop being
469 * triggered on receiving an video frame from the friend. 384 * triggered on receiving an video frame from the friend.
470 */ 385 */
471 TOXAV_CALL_CONTROL_HIDE_VIDEO, 386 TOXAV_CALL_CONTROL_HIDE_VIDEO,
472
473 /** 387 /**
474 * Calling this control will notify client to start sending video again. 388 * Calling this control will notify client to start sending video again.
475 */ 389 */
476 TOXAV_CALL_CONTROL_SHOW_VIDEO, 390 TOXAV_CALL_CONTROL_SHOW_VIDEO,
477
478} TOXAV_CALL_CONTROL; 391} TOXAV_CALL_CONTROL;
479
480
481typedef enum TOXAV_ERR_CALL_CONTROL { 392typedef enum TOXAV_ERR_CALL_CONTROL {
482
483 /** 393 /**
484 * The function returned successfully. 394 * The function returned successfully.
485 */ 395 */
486 TOXAV_ERR_CALL_CONTROL_OK, 396 TOXAV_ERR_CALL_CONTROL_OK,
487
488 /** 397 /**
489 * The friend_number passed did not designate a valid friend. 398 * The friend_number passed did not designate a valid friend.
490 */ 399 */
491 TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND, 400 TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND,
492
493 /** 401 /**
494 * This client is currently not in a call with the friend. Before the call is 402 * This client is currently not in a call with the friend. Before the call is
495 * answered, only CANCEL is a valid control. 403 * answered, only CANCEL is a valid control.
496 */ 404 */
497 TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL, 405 TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL,
498
499 /** 406 /**
500 * Happens if user tried to pause an already paused call or if trying to 407 * Happens if user tried to pause an already paused call or if trying to
501 * resume a call that is not paused. 408 * resume a call that is not paused.
502 */ 409 */
503 TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION, 410 TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION,
504
505} TOXAV_ERR_CALL_CONTROL; 411} TOXAV_ERR_CALL_CONTROL;
506
507
508/** 412/**
509 * Sends a call control command to a friend. 413 * Sends a call control command to a friend.
510 * 414 *
@@ -515,41 +419,29 @@ typedef enum TOXAV_ERR_CALL_CONTROL {
515 * @return true on success. 419 * @return true on success.
516 */ 420 */
517bool toxav_call_control(ToxAV *toxAV, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error); 421bool toxav_call_control(ToxAV *toxAV, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error);
518
519
520/******************************************************************************* 422/*******************************************************************************
521 * 423 *
522 * :: Controlling bit rates 424 * :: Controlling bit rates
523 * 425 *
524 ******************************************************************************/ 426 ******************************************************************************/
525
526
527
528typedef enum TOXAV_ERR_SET_BIT_RATE { 427typedef enum TOXAV_ERR_SET_BIT_RATE {
529
530 /** 428 /**
531 * The function returned successfully. 429 * The function returned successfully.
532 */ 430 */
533 TOXAV_ERR_SET_BIT_RATE_OK, 431 TOXAV_ERR_SET_BIT_RATE_OK,
534
535 /** 432 /**
536 * The bit rate passed was not one of the supported values. 433 * The bit rate passed was not one of the supported values.
537 */ 434 */
538 TOXAV_ERR_SET_BIT_RATE_INVALID, 435 TOXAV_ERR_SET_BIT_RATE_INVALID,
539
540 /** 436 /**
541 * The friend_number passed did not designate a valid friend. 437 * The friend_number passed did not designate a valid friend.
542 */ 438 */
543 TOXAV_ERR_SET_BIT_RATE_FRIEND_NOT_FOUND, 439 TOXAV_ERR_SET_BIT_RATE_FRIEND_NOT_FOUND,
544
545 /** 440 /**
546 * This client is currently not in a call with the friend. 441 * This client is currently not in a call with the friend.
547 */ 442 */
548 TOXAV_ERR_SET_BIT_RATE_FRIEND_NOT_IN_CALL, 443 TOXAV_ERR_SET_BIT_RATE_FRIEND_NOT_IN_CALL,
549
550} TOXAV_ERR_SET_BIT_RATE; 444} TOXAV_ERR_SET_BIT_RATE;
551
552
553/** 445/**
554 * The function type for the audio_bit_rate_status callback. 446 * The function type for the audio_bit_rate_status callback.
555 * 447 *
@@ -564,14 +456,11 @@ typedef enum TOXAV_ERR_SET_BIT_RATE {
564 * @param bit_rate The bit rate in Kb/sec. 456 * @param bit_rate The bit rate in Kb/sec.
565 */ 457 */
566typedef void toxav_audio_bit_rate_status_cb(ToxAV *toxAV, uint32_t friend_number, bool stable, uint32_t bit_rate, void *user_data); 458typedef void toxav_audio_bit_rate_status_cb(ToxAV *toxAV, uint32_t friend_number, bool stable, uint32_t bit_rate, void *user_data);
567
568
569/** 459/**
570 * Set the callback for the `audio_bit_rate_status` event. Pass NULL to unset. 460 * Set the callback for the `audio_bit_rate_status` event. Pass NULL to unset.
571 * 461 *
572 */ 462 */
573void toxav_callback_audio_bit_rate_status(ToxAV *toxAV, toxav_audio_bit_rate_status_cb *callback, void *user_data); 463void toxav_callback_audio_bit_rate_status(ToxAV *toxAV, toxav_audio_bit_rate_status_cb *callback, void *user_data);
574
575/** 464/**
576 * Set the audio bit rate to be used in subsequent audio frames. If the passed 465 * Set the audio bit rate to be used in subsequent audio frames. If the passed
577 * bit rate is the same as the current bit rate this function will return true 466 * bit rate is the same as the current bit rate this function will return true
@@ -588,7 +477,6 @@ void toxav_callback_audio_bit_rate_status(ToxAV *toxAV, toxav_audio_bit_rate_sta
588 * 477 *
589 */ 478 */
590bool toxav_audio_bit_rate_set(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, bool force, TOXAV_ERR_SET_BIT_RATE *error); 479bool toxav_audio_bit_rate_set(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, bool force, TOXAV_ERR_SET_BIT_RATE *error);
591
592/** 480/**
593 * The function type for the video_bit_rate_status callback. 481 * The function type for the video_bit_rate_status callback.
594 * 482 *
@@ -603,14 +491,11 @@ bool toxav_audio_bit_rate_set(ToxAV *toxAV, uint32_t friend_number, uint32_t aud
603 * @param bit_rate The bit rate in Kb/sec. 491 * @param bit_rate The bit rate in Kb/sec.
604 */ 492 */
605typedef void toxav_video_bit_rate_status_cb(ToxAV *toxAV, uint32_t friend_number, bool stable, uint32_t bit_rate, void *user_data); 493typedef void toxav_video_bit_rate_status_cb(ToxAV *toxAV, uint32_t friend_number, bool stable, uint32_t bit_rate, void *user_data);
606
607
608/** 494/**
609 * Set the callback for the `video_bit_rate_status` event. Pass NULL to unset. 495 * Set the callback for the `video_bit_rate_status` event. Pass NULL to unset.
610 * 496 *
611 */ 497 */
612void toxav_callback_video_bit_rate_status(ToxAV *toxAV, toxav_video_bit_rate_status_cb *callback, void *user_data); 498void toxav_callback_video_bit_rate_status(ToxAV *toxAV, toxav_video_bit_rate_status_cb *callback, void *user_data);
613
614/** 499/**
615 * Set the video bit rate to be used in subsequent video frames. If the passed 500 * Set the video bit rate to be used in subsequent video frames. If the passed
616 * bit rate is the same as the current bit rate this function will return true 501 * bit rate is the same as the current bit rate this function will return true
@@ -627,53 +512,39 @@ void toxav_callback_video_bit_rate_status(ToxAV *toxAV, toxav_video_bit_rate_sta
627 * 512 *
628 */ 513 */
629bool toxav_video_bit_rate_set(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, bool force, TOXAV_ERR_SET_BIT_RATE *error); 514bool toxav_video_bit_rate_set(ToxAV *toxAV, uint32_t friend_number, uint32_t audio_bit_rate, bool force, TOXAV_ERR_SET_BIT_RATE *error);
630
631
632/******************************************************************************* 515/*******************************************************************************
633 * 516 *
634 * :: A/V sending 517 * :: A/V sending
635 * 518 *
636 ******************************************************************************/ 519 ******************************************************************************/
637
638
639
640typedef enum TOXAV_ERR_SEND_FRAME { 520typedef enum TOXAV_ERR_SEND_FRAME {
641
642 /** 521 /**
643 * The function returned successfully. 522 * The function returned successfully.
644 */ 523 */
645 TOXAV_ERR_SEND_FRAME_OK, 524 TOXAV_ERR_SEND_FRAME_OK,
646
647 /** 525 /**
648 * In case of video, one of Y, U, or V was NULL. In case of audio, the samples 526 * In case of video, one of Y, U, or V was NULL. In case of audio, the samples
649 * data pointer was NULL. 527 * data pointer was NULL.
650 */ 528 */
651 TOXAV_ERR_SEND_FRAME_NULL, 529 TOXAV_ERR_SEND_FRAME_NULL,
652
653 /** 530 /**
654 * The friend_number passed did not designate a valid friend. 531 * The friend_number passed did not designate a valid friend.
655 */ 532 */
656 TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND, 533 TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND,
657
658 /** 534 /**
659 * This client is currently not in a call with the friend. 535 * This client is currently not in a call with the friend.
660 */ 536 */
661 TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL, 537 TOXAV_ERR_SEND_FRAME_FRIEND_NOT_IN_CALL,
662
663 /** 538 /**
664 * One of the frame parameters was invalid. E.g. the resolution may be too 539 * One of the frame parameters was invalid. E.g. the resolution may be too
665 * small or too large, or the audio sampling rate may be unsupported. 540 * small or too large, or the audio sampling rate may be unsupported.
666 */ 541 */
667 TOXAV_ERR_SEND_FRAME_INVALID, 542 TOXAV_ERR_SEND_FRAME_INVALID,
668
669 /** 543 /**
670 * Failed to push frame through rtp interface. 544 * Failed to push frame through rtp interface.
671 */ 545 */
672 TOXAV_ERR_SEND_FRAME_RTP_FAILED, 546 TOXAV_ERR_SEND_FRAME_RTP_FAILED,
673
674} TOXAV_ERR_SEND_FRAME; 547} TOXAV_ERR_SEND_FRAME;
675
676
677/** 548/**
678 * Send an audio frame to a friend. 549 * Send an audio frame to a friend.
679 * 550 *
@@ -695,7 +566,6 @@ typedef enum TOXAV_ERR_SEND_FRAME {
695 * rates are 8000, 12000, 16000, 24000, or 48000. 566 * rates are 8000, 12000, 16000, 24000, or 48000.
696 */ 567 */
697bool toxav_audio_send_frame(ToxAV *toxAV, uint32_t friend_number, const int16_t *pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, TOXAV_ERR_SEND_FRAME *error); 568bool toxav_audio_send_frame(ToxAV *toxAV, uint32_t friend_number, const int16_t *pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, TOXAV_ERR_SEND_FRAME *error);
698
699/** 569/**
700 * Send a video frame to a friend. 570 * Send a video frame to a friend.
701 * 571 *
@@ -710,19 +580,13 @@ bool toxav_audio_send_frame(ToxAV *toxAV, uint32_t friend_number, const int16_t
710 * @param y Y (Luminance) plane data. 580 * @param y Y (Luminance) plane data.
711 * @param u U (Chroma) plane data. 581 * @param u U (Chroma) plane data.
712 * @param v V (Chroma) plane data. 582 * @param v V (Chroma) plane data.
713 * @param a A (Alpha) plane data.
714 */ 583 */
715bool toxav_video_send_frame(ToxAV *toxAV, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, const uint8_t *a, TOXAV_ERR_SEND_FRAME *error); 584bool toxav_video_send_frame(ToxAV *toxAV, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, TOXAV_ERR_SEND_FRAME *error);
716
717
718/******************************************************************************* 585/*******************************************************************************
719 * 586 *
720 * :: A/V receiving 587 * :: A/V receiving
721 * 588 *
722 ******************************************************************************/ 589 ******************************************************************************/
723
724
725
726/** 590/**
727 * The function type for the audio_receive_frame callback. 591 * The function type for the audio_receive_frame callback.
728 * 592 *
@@ -734,14 +598,11 @@ bool toxav_video_send_frame(ToxAV *toxAV, uint32_t friend_number, uint16_t width
734 * 598 *
735 */ 599 */
736typedef void toxav_audio_receive_frame_cb(ToxAV *toxAV, uint32_t friend_number, const int16_t *pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, void *user_data); 600typedef void toxav_audio_receive_frame_cb(ToxAV *toxAV, uint32_t friend_number, const int16_t *pcm, size_t sample_count, uint8_t channels, uint32_t sampling_rate, void *user_data);
737
738
739/** 601/**
740 * Set the callback for the `audio_receive_frame` event. Pass NULL to unset. 602 * Set the callback for the `audio_receive_frame` event. Pass NULL to unset.
741 * 603 *
742 */ 604 */
743void toxav_callback_audio_receive_frame(ToxAV *toxAV, toxav_audio_receive_frame_cb *callback, void *user_data); 605void toxav_callback_audio_receive_frame(ToxAV *toxAV, toxav_audio_receive_frame_cb *callback, void *user_data);
744
745/** 606/**
746 * The function type for the video_receive_frame callback. 607 * The function type for the video_receive_frame callback.
747 * 608 *
@@ -755,23 +616,18 @@ void toxav_callback_audio_receive_frame(ToxAV *toxAV, toxav_audio_receive_frame_
755 * Y = MAX(width, abs(ystride)) * height, 616 * Y = MAX(width, abs(ystride)) * height,
756 * U = MAX(width/2, abs(ustride)) * (height/2) and 617 * U = MAX(width/2, abs(ustride)) * (height/2) and
757 * V = MAX(width/2, abs(vstride)) * (height/2). 618 * V = MAX(width/2, abs(vstride)) * (height/2).
758 * A = MAX(width, abs(astride)) * height.
759 * @param ystride 619 * @param ystride
760 * @param ustride 620 * @param ustride
761 * @param vstride 621 * @param vstride Strides data. Strides represent padding for each plane
762 * @param astride Strides data. Strides represent padding for each plane
763 * that may or may not be present. You must handle strides in 622 * that may or may not be present. You must handle strides in
764 * your image processing code. Strides are negative if the 623 * your image processing code. Strides are negative if the
765 * image is bottom-up hence why you MUST abs() it when 624 * image is bottom-up hence why you MUST abs() it when
766 * calculating plane buffer size. 625 * calculating plane buffer size.
767 */ 626 */
768typedef void toxav_video_receive_frame_cb(ToxAV *toxAV, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, const uint8_t *a, int32_t ystride, int32_t ustride, int32_t vstride, int32_t astride, void *user_data); 627typedef void toxav_video_receive_frame_cb(ToxAV *toxAV, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, int32_t ystride, int32_t ustride, int32_t vstride, void *user_data);
769
770
771/** 628/**
772 * Set the callback for the `video_receive_frame` event. Pass NULL to unset. 629 * Set the callback for the `video_receive_frame` event. Pass NULL to unset.
773 * 630 *
774 */ 631 */
775void toxav_callback_video_receive_frame(ToxAV *toxAV, toxav_video_receive_frame_cb *callback, void *user_data); 632void toxav_callback_video_receive_frame(ToxAV *toxAV, toxav_video_receive_frame_cb *callback, void *user_data);
776
777#endif 633#endif
diff --git a/toxav/video.c b/toxav/video.c
index 690b3bd4..ee49c0a1 100644
--- a/toxav/video.c
+++ b/toxav/video.c
@@ -141,9 +141,8 @@ void vc_do(VCSession* vc)
141 for (; dest; dest = vpx_codec_get_frame(vc->decoder, &iter)) { 141 for (; dest; dest = vpx_codec_get_frame(vc->decoder, &iter)) {
142 if (vc->vcb.first) 142 if (vc->vcb.first)
143 vc->vcb.first(vc->av, vc->friend_number, dest->d_w, dest->d_h, 143 vc->vcb.first(vc->av, vc->friend_number, dest->d_w, dest->d_h,
144 (const uint8_t*)dest->planes[0], (const uint8_t*)dest->planes[1], 144 (const uint8_t*)dest->planes[0], (const uint8_t*)dest->planes[1], (const uint8_t*)dest->planes[2],
145 (const uint8_t*)dest->planes[2], (const uint8_t*)dest->planes[3], 145 dest->stride[0], dest->stride[1], dest->stride[2], vc->vcb.second);
146 dest->stride[0], dest->stride[1], dest->stride[2], dest->stride[3], vc->vcb.second);
147 146
148 vpx_img_free(dest); 147 vpx_img_free(dest);
149 } 148 }
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index dc0e605a..4d4b82c1 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -384,12 +384,12 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
384 clear_receipts(m, friendnumber); 384 clear_receipts(m, friendnumber);
385 remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk); 385 remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk);
386 friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0); 386 friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0);
387 kill_friend_connection(m->fr_c, m->friendlist[friendnumber].friendcon_id);
388 387
389 if (friend_con_connected(m->fr_c, m->friendlist[friendnumber].friendcon_id) == FRIENDCONN_STATUS_CONNECTED) { 388 if (friend_con_connected(m->fr_c, m->friendlist[friendnumber].friendcon_id) == FRIENDCONN_STATUS_CONNECTED) {
390 send_offline_packet(m, m->friendlist[friendnumber].friendcon_id); 389 send_offline_packet(m, m->friendlist[friendnumber].friendcon_id);
391 } 390 }
392 391
392 kill_friend_connection(m->fr_c, m->friendlist[friendnumber].friendcon_id);
393 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); 393 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
394 uint32_t i; 394 uint32_t i;
395 395
@@ -864,6 +864,11 @@ static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, ui
864 if (was_online) { 864 if (was_online) {
865 break_files(m, friendnumber); 865 break_files(m, friendnumber);
866 clear_receipts(m, friendnumber); 866 clear_receipts(m, friendnumber);
867 } else {
868 m->friendlist[friendnumber].name_sent = 0;
869 m->friendlist[friendnumber].userstatus_sent = 0;
870 m->friendlist[friendnumber].statusmessage_sent = 0;
871 m->friendlist[friendnumber].user_istyping_sent = 0;
867 } 872 }
868 873
869 m->friendlist[friendnumber].status = status; 874 m->friendlist[friendnumber].status = status;
@@ -1891,10 +1896,6 @@ static int handle_status(void *object, int i, uint8_t status)
1891 1896
1892 if (status) { /* Went online. */ 1897 if (status) { /* Went online. */
1893 send_online_packet(m, i); 1898 send_online_packet(m, i);
1894 m->friendlist[i].name_sent = 0;
1895 m->friendlist[i].userstatus_sent = 0;
1896 m->friendlist[i].statusmessage_sent = 0;
1897 m->friendlist[i].user_istyping_sent = 0;
1898 } else { /* Went offline. */ 1899 } else { /* Went offline. */
1899 if (m->friendlist[i].status == FRIEND_ONLINE) { 1900 if (m->friendlist[i].status == FRIEND_ONLINE) {
1900 set_friend_status(m, i, FRIEND_CONFIRMED); 1901 set_friend_status(m, i, FRIEND_CONFIRMED);
diff --git a/toxcore/assoc.c b/toxcore/assoc.c
index 3dbeba51..2e03dabe 100644
--- a/toxcore/assoc.c
+++ b/toxcore/assoc.c
@@ -510,20 +510,18 @@ static uint8_t candidates_create_new(const Assoc *assoc, hash_t hash, const uint
510 510
511static void client_id_self_update(Assoc *assoc) 511static void client_id_self_update(Assoc *assoc)
512{ 512{
513 if (assoc->self_hash || !assoc->self_client_id) 513 if (assoc->self_hash)
514 return; 514 return;
515 515
516 if (!assoc->self_hash) { 516 size_t i, sum = 0;
517 size_t i, sum = 0;
518 517
519 for (i = 0; i < crypto_box_PUBLICKEYBYTES; i++) 518 for (i = 0; i < crypto_box_PUBLICKEYBYTES; i++)
520 sum |= assoc->self_client_id[i]; 519 sum |= assoc->self_client_id[i];
521 520
522 if (!sum) 521 if (!sum)
523 return; 522 return;
524 523
525 assoc->self_hash = id_hash(assoc, assoc->self_client_id); 524 assoc->self_hash = id_hash(assoc, assoc->self_client_id);
526 }
527 525
528 LOGGER_DEBUG("id is now set, purging cache of self-references"); 526 LOGGER_DEBUG("id is now set, purging cache of self-references");
529 527
@@ -532,7 +530,7 @@ static void client_id_self_update(Assoc *assoc)
532 */ 530 */
533 bucket_t b_id = candidates_id_bucket(assoc, assoc->self_client_id); 531 bucket_t b_id = candidates_id_bucket(assoc, assoc->self_client_id);
534 candidates_bucket *cnd_bckt = &assoc->candidates[b_id]; 532 candidates_bucket *cnd_bckt = &assoc->candidates[b_id];
535 size_t i, pos = assoc->self_hash % assoc->candidates_bucket_size; 533 size_t pos = assoc->self_hash % assoc->candidates_bucket_size;
536 534
537 for (i = 0; i < HASH_COLLIDE_COUNT; pos = hash_collide(assoc, pos), i++) { 535 for (i = 0; i < HASH_COLLIDE_COUNT; pos = hash_collide(assoc, pos), i++) {
538 Client_entry *entry = &cnd_bckt->list[pos]; 536 Client_entry *entry = &cnd_bckt->list[pos];
diff --git a/toxcore/group.c b/toxcore/group.c
index c688ccff..af2cb492 100644
--- a/toxcore/group.c
+++ b/toxcore/group.c
@@ -1149,7 +1149,7 @@ int group_new_peer_send(const Group_Chats *g_c, int groupnumber, uint16_t peer_n
1149 * return 0 on success 1149 * return 0 on success
1150 * return -1 on failure 1150 * return -1 on failure
1151 */ 1151 */
1152int group_kill_peer_send(const Group_Chats *g_c, int groupnumber, uint16_t peer_num) 1152static int group_kill_peer_send(const Group_Chats *g_c, int groupnumber, uint16_t peer_num)
1153{ 1153{
1154 uint8_t packet[GROUP_MESSAGE_KILL_PEER_LENGTH]; 1154 uint8_t packet[GROUP_MESSAGE_KILL_PEER_LENGTH];
1155 1155
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 6d4f6a9b..96be059d 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -2006,7 +2006,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
2006#define PACKET_RESEND_MULTIPLIER 2 2006#define PACKET_RESEND_MULTIPLIER 2
2007 2007
2008/* Timeout for increasing speed after congestion event (in ms). */ 2008/* Timeout for increasing speed after congestion event (in ms). */
2009#define CONGESTION_EVENT_TIMEOUT 4000 2009#define CONGESTION_EVENT_TIMEOUT 2000
2010 2010
2011static void send_crypto_packets(Net_Crypto *c) 2011static void send_crypto_packets(Net_Crypto *c)
2012{ 2012{
@@ -2086,7 +2086,7 @@ static void send_crypto_packets(Net_Crypto *c)
2086 PACKET_COUNTER_AVERAGE_INTERVAL)); 2086 PACKET_COUNTER_AVERAGE_INTERVAL));
2087 2087
2088 if (conn->last_congestion_event + CONGESTION_EVENT_TIMEOUT < temp_time) { 2088 if (conn->last_congestion_event + CONGESTION_EVENT_TIMEOUT < temp_time) {
2089 conn->packet_send_rate = min_speed * 1.2; 2089 conn->packet_send_rate = min_speed * 1.25;
2090 } else { 2090 } else {
2091 conn->packet_send_rate = min_speed; 2091 conn->packet_send_rate = min_speed;
2092 } 2092 }
diff --git a/toxcore/tox.c b/toxcore/tox.c
index de615768..3e9db766 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -121,33 +121,46 @@ void tox_options_free(struct Tox_Options *options)
121 free(options); 121 free(options);
122} 122}
123 123
124Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t length, TOX_ERR_NEW *error) 124Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error)
125{ 125{
126 if (!logger_get_global()) 126 if (!logger_get_global())
127 logger_set_global(logger_new(LOGGER_OUTPUT_FILE, LOGGER_LEVEL, "toxcore")); 127 logger_set_global(logger_new(LOGGER_OUTPUT_FILE, LOGGER_LEVEL, "toxcore"));
128 128
129 if (data == NULL && length != 0) {
130 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_NULL);
131 return NULL;
132 }
133
134 if (data && length) {
135 if (length < TOX_ENC_SAVE_MAGIC_LENGTH) {
136 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
137 return NULL;
138 }
139
140 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) {
141 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED);
142 return NULL;
143 }
144 }
145
146 Messenger_Options m_options = {0}; 129 Messenger_Options m_options = {0};
147 130
131 _Bool load_savedata_sk = 0, load_savedata_tox = 0;
132
148 if (options == NULL) { 133 if (options == NULL) {
149 m_options.ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; 134 m_options.ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
150 } else { 135 } else {
136 if (options->savedata_type != TOX_SAVEDATA_TYPE_NONE) {
137 if (options->savedata_data == NULL || options->savedata_length == 0) {
138 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
139 return NULL;
140 }
141 }
142
143 if (options->savedata_type == TOX_SAVEDATA_TYPE_SECRET_KEY) {
144 if (options->savedata_length != TOX_SECRET_KEY_SIZE) {
145 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
146 return NULL;
147 }
148
149 load_savedata_sk = 1;
150 } else if (options->savedata_type == TOX_SAVEDATA_TYPE_TOX_SAVE) {
151 if (options->savedata_length < TOX_ENC_SAVE_MAGIC_LENGTH) {
152 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
153 return NULL;
154 }
155
156 if (memcmp(options->savedata_data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) {
157 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED);
158 return NULL;
159 }
160
161 load_savedata_tox = 1;
162 }
163
151 m_options.ipv6enabled = options->ipv6_enabled; 164 m_options.ipv6enabled = options->ipv6_enabled;
152 m_options.udp_disabled = !options->udp_enabled; 165 m_options.udp_disabled = !options->udp_enabled;
153 m_options.port_range[0] = options->start_port; 166 m_options.port_range[0] = options->start_port;
@@ -201,6 +214,8 @@ Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t leng
201 214
202 if (m_error == MESSENGER_ERROR_PORT) { 215 if (m_error == MESSENGER_ERROR_PORT) {
203 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PORT_ALLOC); 216 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PORT_ALLOC);
217 } else if (m_error == MESSENGER_ERROR_TCP_SERVER) {
218 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PORT_ALLOC);
204 } else { 219 } else {
205 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); 220 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
206 } 221 }
@@ -208,8 +223,11 @@ Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t leng
208 return NULL; 223 return NULL;
209 } 224 }
210 225
211 if (data && length && messenger_load(m, data, length) == -1) { 226 if (load_savedata_tox && messenger_load(m, options->savedata_data, options->savedata_length) == -1) {
212 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); 227 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
228 } else if (load_savedata_sk) {
229 load_secret_key(m->net_crypto, options->savedata_data);
230 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK);
213 } else { 231 } else {
214 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK); 232 SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK);
215 } 233 }
@@ -993,6 +1011,11 @@ void tox_callback_file_recv_control(Tox *tox, tox_file_recv_control_cb *function
993bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id, 1011bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id,
994 TOX_ERR_FILE_GET *error) 1012 TOX_ERR_FILE_GET *error)
995{ 1013{
1014 if (!file_id) {
1015 SET_ERROR_PARAMETER(error, TOX_ERR_FILE_GET_NULL);
1016 return 0;
1017 }
1018
996 const Messenger *m = tox; 1019 const Messenger *m = tox;
997 int ret = file_get_id(m, friend_number, file_number, file_id); 1020 int ret = file_get_id(m, friend_number, file_number, file_id);
998 1021
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 4afdf7c3..14c9f616 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -352,6 +352,29 @@ typedef enum TOX_PROXY_TYPE {
352 352
353 353
354/** 354/**
355 * Type of savedata to create the Tox instance from.
356 */
357typedef enum TOX_SAVEDATA_TYPE {
358
359 /**
360 * No savedata.
361 */
362 TOX_SAVEDATA_TYPE_NONE,
363
364 /**
365 * Savedata is one that was obtained from tox_get_savedata
366 */
367 TOX_SAVEDATA_TYPE_TOX_SAVE,
368
369 /**
370 * Savedata is a secret key of length TOX_SECRET_KEY_SIZE
371 */
372 TOX_SAVEDATA_TYPE_SECRET_KEY,
373
374} TOX_SAVEDATA_TYPE;
375
376
377/**
355 * This struct contains all the startup options for Tox. You can either allocate 378 * This struct contains all the startup options for Tox. You can either allocate
356 * this object yourself, and pass it to tox_options_default, or call 379 * this object yourself, and pass it to tox_options_default, or call
357 * tox_options_new to get a new default options object. 380 * tox_options_new to get a new default options object.
@@ -432,6 +455,24 @@ struct Tox_Options {
432 */ 455 */
433 uint16_t tcp_port; 456 uint16_t tcp_port;
434 457
458
459 /**
460 * The type of savedata to load from.
461 */
462 TOX_SAVEDATA_TYPE savedata_type;
463
464
465 /**
466 * The savedata.
467 */
468 const uint8_t *savedata_data;
469
470
471 /**
472 * The length of the savedata.
473 */
474 size_t savedata_length;
475
435}; 476};
436 477
437 478
@@ -561,21 +602,17 @@ typedef enum TOX_ERR_NEW {
561 * This function will bring the instance into a valid state. Running the event 602 * This function will bring the instance into a valid state. Running the event
562 * loop with a new instance will operate correctly. 603 * loop with a new instance will operate correctly.
563 * 604 *
564 * If the data parameter is not NULL, this function will load the Tox instance
565 * from a byte array previously filled by tox_get_savedata.
566 *
567 * If loading failed or succeeded only partially, the new or partially loaded 605 * If loading failed or succeeded only partially, the new or partially loaded
568 * instance is returned and an error code is set. 606 * instance is returned and an error code is set.
569 * 607 *
570 * @param options An options object as described above. If this parameter is 608 * @param options An options object as described above. If this parameter is
571 * NULL, the default options are used. 609 * NULL, the default options are used.
572 * @param data A byte array containing data previously stored by tox_get_savedata.
573 * @param length The length of the byte array data. If this parameter is 0, the
574 * data parameter is ignored.
575 * 610 *
576 * @see tox_iterate for the event loop. 611 * @see tox_iterate for the event loop.
612 *
613 * @return A new Tox instance pointer on success or NULL on failure.
577 */ 614 */
578Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t length, TOX_ERR_NEW *error); 615Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error);
579 616
580/** 617/**
581 * Releases all resources associated with the Tox instance and disconnects from 618 * Releases all resources associated with the Tox instance and disconnects from
@@ -642,13 +679,8 @@ typedef enum TOX_ERR_BOOTSTRAP {
642 * Sends a "get nodes" request to the given bootstrap node with IP, port, and 679 * Sends a "get nodes" request to the given bootstrap node with IP, port, and
643 * public key to setup connections. 680 * public key to setup connections.
644 * 681 *
645 * This function will attempt to connect to the node using UDP and TCP at the 682 * This function will attempt to connect to the node using UDP. You must use
646 * same time. 683 * this function even if Tox_Options.udp_enabled was set to false.
647 *
648 * Tox will use the node as a TCP relay in case Tox_Options.udp_enabled was
649 * false, and also to connect to friends that are in TCP-only mode. Tox will
650 * also use the TCP connection when NAT hole punching is slow, and later switch
651 * to UDP if hole punching succeeds.
652 * 684 *
653 * @param address The hostname or IP address (IPv4 or IPv6) of the node. 685 * @param address The hostname or IP address (IPv4 or IPv6) of the node.
654 * @param port The port on the host on which the bootstrap Tox instance is 686 * @param port The port on the host on which the bootstrap Tox instance is
@@ -1559,7 +1591,7 @@ enum TOX_FILE_KIND {
1559 TOX_FILE_KIND_DATA, 1591 TOX_FILE_KIND_DATA,
1560 1592
1561 /** 1593 /**
1562 * Avatar filename. This consists of tox_hash(image). 1594 * Avatar file_id. This consists of tox_hash(image).
1563 * Avatar data. This consists of the image data. 1595 * Avatar data. This consists of the image data.
1564 * 1596 *
1565 * Avatars can be sent at any time the client wishes. Generally, a client will 1597 * Avatars can be sent at any time the client wishes. Generally, a client will
@@ -1749,6 +1781,11 @@ typedef enum TOX_ERR_FILE_GET {
1749 TOX_ERR_FILE_GET_OK, 1781 TOX_ERR_FILE_GET_OK,
1750 1782
1751 /** 1783 /**
1784 * One of the arguments to the function was NULL when it was not expected.
1785 */
1786 TOX_ERR_FILE_GET_NULL,
1787
1788 /**
1752 * The friend_number passed did not designate a valid friend. 1789 * The friend_number passed did not designate a valid friend.
1753 */ 1790 */
1754 TOX_ERR_FILE_GET_FRIEND_NOT_FOUND, 1791 TOX_ERR_FILE_GET_FRIEND_NOT_FOUND,
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c
index e2f28a58..e6150ce2 100644
--- a/toxencryptsave/toxencryptsave.c
+++ b/toxencryptsave/toxencryptsave.c
@@ -82,7 +82,7 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt)
82 * 82 *
83 * returns true on success 83 * returns true on success
84 */ 84 */
85bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key, 85bool tox_derive_key_from_pass(const uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key,
86 TOX_ERR_KEY_DERIVATION *error) 86 TOX_ERR_KEY_DERIVATION *error)
87{ 87{
88 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 88 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
@@ -93,10 +93,10 @@ bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY
93/* Same as above, except with use the given salt for deterministic key derivation. 93/* Same as above, except with use the given salt for deterministic key derivation.
94 * The salt must be TOX_PASS_SALT_LENGTH bytes in length. 94 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
95 */ 95 */
96bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key, 96bool tox_derive_key_with_salt(const uint8_t *passphrase, size_t pplength, const uint8_t *salt, TOX_PASS_KEY *out_key,
97 TOX_ERR_KEY_DERIVATION *error) 97 TOX_ERR_KEY_DERIVATION *error)
98{ 98{
99 if (pplength == 0 || !passphrase || !salt || !out_key) { 99 if (!salt || !out_key || (!passphrase && pplength != 0)) {
100 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL); 100 SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL);
101 return 0; 101 return 0;
102 } 102 }
@@ -180,7 +180,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_K
180 * 180 *
181 * returns true on success 181 * returns true on success
182 */ 182 */
183bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out, 183bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out,
184 TOX_ERR_ENCRYPTION *error) 184 TOX_ERR_ENCRYPTION *error)
185{ 185{
186 TOX_PASS_KEY key; 186 TOX_PASS_KEY key;
@@ -252,10 +252,10 @@ bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY
252 * 252 *
253 * returns true on success 253 * returns true on success
254 */ 254 */
255bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out, 255bool tox_pass_decrypt(const uint8_t *data, size_t length, const uint8_t *passphrase, size_t pplength, uint8_t *out,
256 TOX_ERR_DECRYPTION *error) 256 TOX_ERR_DECRYPTION *error)
257{ 257{
258 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH || pplength == 0) { 258 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) {
259 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH); 259 SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH);
260 return 0; 260 return 0;
261 } 261 }
diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h
index c077d899..9e28b48e 100644
--- a/toxencryptsave/toxencryptsave.h
+++ b/toxencryptsave/toxencryptsave.h
@@ -143,7 +143,7 @@ typedef enum TOX_ERR_DECRYPTION {
143 * 143 *
144 * returns true on success 144 * returns true on success
145 */ 145 */
146bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out, 146bool tox_pass_encrypt(const uint8_t *data, size_t data_len, const uint8_t *passphrase, size_t pplength, uint8_t *out,
147 TOX_ERR_ENCRYPTION *error); 147 TOX_ERR_ENCRYPTION *error);
148 148
149 149
@@ -155,7 +155,7 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase,
155 * 155 *
156 * returns true on success 156 * returns true on success
157 */ 157 */
158bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out, 158bool tox_pass_decrypt(const uint8_t *data, size_t length, const uint8_t *passphrase, size_t pplength, uint8_t *out,
159 TOX_ERR_DECRYPTION *error); 159 TOX_ERR_DECRYPTION *error);
160 160
161 161
@@ -183,13 +183,13 @@ typedef struct {
183 * 183 *
184 * returns true on success 184 * returns true on success
185 */ 185 */
186bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key, 186bool tox_derive_key_from_pass(const uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key,
187 TOX_ERR_KEY_DERIVATION *error); 187 TOX_ERR_KEY_DERIVATION *error);
188 188
189/* Same as above, except use the given salt for deterministic key derivation. 189/* Same as above, except use the given salt for deterministic key derivation.
190 * The salt must be TOX_PASS_SALT_LENGTH bytes in length. 190 * The salt must be TOX_PASS_SALT_LENGTH bytes in length.
191 */ 191 */
192bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key, 192bool tox_derive_key_with_salt(const uint8_t *passphrase, size_t pplength, const uint8_t *salt, TOX_PASS_KEY *out_key,
193 TOX_ERR_KEY_DERIVATION *error); 193 TOX_ERR_KEY_DERIVATION *error);
194 194
195/* This retrieves the salt used to encrypt the given data, which can then be passed to 195/* This retrieves the salt used to encrypt the given data, which can then be passed to