diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b774f8362..f3d880cfd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -299,6 +299,7 @@ apidsl( toxcore/tox.api.h) add_module(toxcore toxcore/misc_tools.h + toxcore/tox_api.c toxcore/tox.c toxcore/tox.h) target_link_modules(toxcore toxgroup) diff --git a/auto_tests/encryptsave_test.c b/auto_tests/encryptsave_test.c index ec98797c50..22c585ed9e 100644 --- a/auto_tests/encryptsave_test.c +++ b/auto_tests/encryptsave_test.c @@ -77,14 +77,12 @@ START_TEST(test_save_friend) ck_assert_msg(ret, "failed to encrypted save: %u", error1); ck_assert_msg(tox_is_data_encrypted(enc_data), "magic number missing"); - struct Tox_Options options; - tox_options_default(&options); - options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; - options.savedata_data = enc_data; - options.savedata_length = size2; + struct Tox_Options *options = tox_options_new(NULL); + tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); + tox_options_set_savedata_data(options, enc_data, size2); TOX_ERR_NEW err2; - Tox *tox3 = tox_new_log(&options, &err2, 0); + Tox *tox3 = tox_new_log(options, &err2, 0); ck_assert_msg(err2 == TOX_ERR_NEW_LOAD_ENCRYPTED, "wrong error! %u. should fail with %u", err2, TOX_ERR_NEW_LOAD_ENCRYPTED); ck_assert_msg(tox3 == NULL, "tox_new with error should return NULL"); @@ -92,9 +90,8 @@ START_TEST(test_save_friend) TOX_ERR_DECRYPTION err3; ret = tox_pass_decrypt(enc_data, size2, (const uint8_t *)"correcthorsebatterystaple", 25, dec_data, &err3); ck_assert_msg(ret, "failed to decrypt save: %u", err3); - options.savedata_data = dec_data; - options.savedata_length = size; - tox3 = tox_new_log(&options, &err2, 0); + tox_options_set_savedata_data(options, dec_data, size); + tox3 = tox_new_log(options, &err2, 0); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to load from decrypted data: %u", err2); uint8_t address2[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox3, 0, address2, 0); @@ -123,9 +120,8 @@ START_TEST(test_save_friend) // and now with the code in use (I only bothered with manually to debug this, and it seems a waste // to remove the manual check now that it's there) - options.savedata_data = out1; - options.savedata_length = size; - Tox *tox4 = tox_new_log(&options, &err2, 0); + tox_options_set_savedata_data(options, out1, size); + Tox *tox4 = tox_new_log(options, &err2, 0); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to new the third"); uint8_t address5[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox4, 0, address5, 0); @@ -133,6 +129,7 @@ START_TEST(test_save_friend) ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match! the third"); tox_pass_key_free(key); + tox_options_free(options); tox_kill(tox1); tox_kill(tox2); diff --git a/auto_tests/helpers.h b/auto_tests/helpers.h index 99930e90d0..5cec575c3a 100644 --- a/auto_tests/helpers.h +++ b/auto_tests/helpers.h @@ -3,6 +3,7 @@ #include "../toxcore/tox.h" +#include <assert.h> #include <check.h> #include <stdio.h> @@ -50,16 +51,22 @@ static void print_debug_log(Tox *m, TOX_LOG_LEVEL level, const char *path, uint3 Tox *tox_new_log(struct Tox_Options *options, TOX_ERR_NEW *err, void *log_user_data) { - struct Tox_Options *my_options = tox_options_new(NULL); + struct Tox_Options *log_options = options; - if (options != NULL) { - *my_options = *options; + if (log_options == NULL) { + log_options = tox_options_new(NULL); + } + + assert(log_options != NULL); + + tox_options_set_log_callback(log_options, &print_debug_log); + tox_options_set_log_user_data(log_options, log_user_data); + Tox *tox = tox_new(log_options, err); + + if (options == NULL) { + tox_options_free(log_options); } - tox_options_set_log_callback(my_options, &print_debug_log); - tox_options_set_log_user_data(my_options, log_user_data); - Tox *tox = tox_new(my_options, err); - tox_options_free(my_options); return tox; } diff --git a/auto_tests/save_friend_test.c b/auto_tests/save_friend_test.c index db59a24ad0..9d36ff2d18 100644 --- a/auto_tests/save_friend_test.c +++ b/auto_tests/save_friend_test.c @@ -1,7 +1,7 @@ /* Auto Tests: Save and load friends. */ -#include "../toxcore/tox.h" +#include "helpers.h" #include <assert.h> #include <stdio.h> @@ -51,8 +51,8 @@ void statuschange_callback(Tox *tox, uint32_t friend_number, const uint8_t *mess int main(int argc, char *argv[]) { - Tox *tox1 = tox_new(tox_options_new(NULL), 0); - Tox *tox2 = tox_new(tox_options_new(NULL), 0); + Tox *tox1 = tox_new_log(0, 0, 0); + Tox *tox2 = tox_new_log(0, 0, 0); struct test_data to_compare = { { 0 } }; @@ -106,13 +106,11 @@ int main(int argc, char *argv[]) uint8_t savedata[save_size]; tox_get_savedata(tox1, savedata); - struct Tox_Options options; - tox_options_default(&options); - options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; - options.savedata_data = savedata; - options.savedata_length = save_size; + struct Tox_Options *options = tox_options_new(NULL); + tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); + tox_options_set_savedata_data(options, savedata, save_size); - Tox *tox_to_compare = tox_new(&options, 0); + Tox *tox_to_compare = tox_new(options, 0); tox_friend_get_name(tox_to_compare, 0, to_compare.name, 0); tox_friend_get_status_message(tox_to_compare, 0, to_compare.status_message, 0); @@ -120,6 +118,7 @@ int main(int argc, char *argv[]) assert(memcmp(reference_name, to_compare.name, TOX_MAX_NAME_LENGTH) == 0); assert(memcmp(reference_status, to_compare.status_message, TOX_MAX_STATUS_MESSAGE_LENGTH) == 0); + tox_options_free(options); tox_kill(tox1); tox_kill(tox2); tox_kill(tox_to_compare); diff --git a/auto_tests/tox_many_tcp_test.c b/auto_tests/tox_many_tcp_test.c index f802bf57c5..197c6e477e 100644 --- a/auto_tests/tox_many_tcp_test.c +++ b/auto_tests/tox_many_tcp_test.c @@ -55,17 +55,16 @@ START_TEST(test_many_clients_tcp) uint32_t to_comp = 974536; for (i = 0; i < NUM_TOXES_TCP; ++i) { - struct Tox_Options opts; - tox_options_default(&opts); + struct Tox_Options *opts = tox_options_new(NULL); if (i == 0) { - opts.tcp_port = TCP_RELAY_PORT; + tox_options_set_tcp_port(opts, TCP_RELAY_PORT); } else { - opts.udp_enabled = 0; + tox_options_set_udp_enabled(opts, 0); } index[i] = i + 1; - toxes[i] = tox_new_log(&opts, 0, &index[i]); + toxes[i] = tox_new_log(opts, 0, &index[i]); ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i); tox_callback_friend_request(toxes[i], accept_friend_request); uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; @@ -74,6 +73,8 @@ START_TEST(test_many_clients_tcp) ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, TCP_RELAY_PORT, dpk, &error), "add relay error, %i, %i", i, error); ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, 33445, dpk, 0), "Bootstrap error"); + + tox_options_free(opts); } { @@ -156,17 +157,16 @@ START_TEST(test_many_clients_tcp_b) uint32_t to_comp = 974536; for (i = 0; i < NUM_TOXES_TCP; ++i) { - struct Tox_Options opts; - tox_options_default(&opts); + struct Tox_Options *opts = tox_options_new(NULL); if (i < NUM_TCP_RELAYS) { - opts.tcp_port = TCP_RELAY_PORT + i; + tox_options_set_tcp_port(opts, TCP_RELAY_PORT + i); } else { - opts.udp_enabled = 0; + tox_options_set_udp_enabled(opts, 0); } index[i] = i + 1; - toxes[i] = tox_new_log(&opts, 0, &index[i]); + toxes[i] = tox_new_log(opts, 0, &index[i]); ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i); tox_callback_friend_request(toxes[i], accept_friend_request); uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; @@ -175,6 +175,8 @@ START_TEST(test_many_clients_tcp_b) "add relay error"); tox_self_get_dht_id(toxes[0], dpk); ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, 33445, dpk, 0), "Bootstrap error"); + + tox_options_free(opts); } { diff --git a/auto_tests/tox_one_test.c b/auto_tests/tox_one_test.c index ca5fde01e4..8726d5c535 100644 --- a/auto_tests/tox_one_test.c +++ b/auto_tests/tox_one_test.c @@ -29,16 +29,6 @@ static void set_random_name_and_status_message(Tox *tox, uint8_t *name, uint8_t START_TEST(test_one) { - { - TOX_ERR_OPTIONS_NEW o_err; - struct Tox_Options *o1 = tox_options_new(&o_err); - struct Tox_Options o2; - tox_options_default(&o2); - ck_assert_msg(o_err == TOX_ERR_OPTIONS_NEW_OK, "tox_options_new wrong error"); - ck_assert_msg(memcmp(o1, &o2, sizeof(struct Tox_Options)) == 0, "tox_options_new error"); - tox_options_free(o1); - } - uint8_t name[TOX_MAX_NAME_LENGTH]; uint8_t status_message[TOX_MAX_STATUS_MESSAGE_LENGTH]; @@ -93,12 +83,10 @@ START_TEST(test_one) tox_kill(tox2); TOX_ERR_NEW err_n; - struct Tox_Options options; - tox_options_default(&options); - options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; - options.savedata_data = data; - options.savedata_length = save_size; - tox2 = tox_new_log(&options, &err_n, &index[1]); + struct Tox_Options *options = tox_options_new(NULL); + tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); + tox_options_set_savedata_data(options, data, save_size); + tox2 = tox_new_log(options, &err_n, &index[1]); ck_assert_msg(err_n == TOX_ERR_NEW_OK, "Load failed"); ck_assert_msg(tox_self_get_name_size(tox2) == sizeof name, "Wrong name size."); @@ -123,11 +111,10 @@ START_TEST(test_one) tox_self_get_secret_key(tox2, sk); tox_kill(tox2); - tox_options_default(&options); - options.savedata_type = TOX_SAVEDATA_TYPE_SECRET_KEY; - options.savedata_data = sk; - options.savedata_length = sizeof(sk); - tox2 = tox_new_log(&options, &err_n, &index[1]); + tox_options_default(options); + tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_SECRET_KEY); + tox_options_set_savedata_data(options, sk, sizeof(sk)); + tox2 = tox_new_log(options, &err_n, &index[1]); ck_assert_msg(err_n == TOX_ERR_NEW_OK, "Load failed"); uint8_t address3[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address3); @@ -142,6 +129,7 @@ START_TEST(test_one) ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error"); } + tox_options_free(options); tox_kill(tox1); tox_kill(tox2); } diff --git a/auto_tests/tox_test.c b/auto_tests/tox_test.c index 2faa8cad32..dfd1d80a30 100644 --- a/auto_tests/tox_test.c +++ b/auto_tests/tox_test.c @@ -418,12 +418,10 @@ START_TEST(test_few_clients) tox_get_savedata(tox2, save1); tox_kill(tox2); - struct Tox_Options options; - tox_options_default(&options); - options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; - options.savedata_data = save1; - options.savedata_length = save_size1; - tox2 = tox_new_log(&options, NULL, &index[1]); + struct Tox_Options *options = tox_options_new(NULL); + tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); + tox_options_set_savedata_data(options, save1, save_size1); + tox2 = tox_new_log(options, NULL, &index[1]); cur_time = time(NULL); off = 1; @@ -727,6 +725,7 @@ START_TEST(test_few_clients) printf("test_few_clients succeeded, took %llu seconds\n", time(NULL) - cur_time); + tox_options_free(options); tox_kill(tox1); tox_kill(tox2); tox_kill(tox3); diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index f8f6f9cf2a..84e24ebda2 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc @@ -27,6 +27,7 @@ libtoxcore_la_SOURCES = ../toxcore/DHT.h \ ../toxcore/ping.c \ ../toxcore/tox.h \ ../toxcore/tox.c \ + ../toxcore/tox_api.c \ ../toxcore/util.h \ ../toxcore/util.c \ ../toxcore/group.h \ diff --git a/toxcore/tox.c b/toxcore/tox.c index 7a9a708cfd..37298ce23c 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -69,20 +69,6 @@ typedef struct Messenger Tox; #error TOX_MAX_STATUS_MESSAGE_LENGTH is assumed to be equal to MAX_STATUSMESSAGE_LENGTH #endif -uint32_t tox_version_major(void) -{ - return TOX_VERSION_MAJOR; -} - -uint32_t tox_version_minor(void) -{ - return TOX_VERSION_MINOR; -} - -uint32_t tox_version_patch(void) -{ - return TOX_VERSION_PATCH; -} bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch) { @@ -90,93 +76,6 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch) } -#define CONST_FUNCTION(lowercase, uppercase) \ -uint32_t tox_##lowercase(void) \ -{ \ - return TOX_##uppercase; \ -} - -CONST_FUNCTION(public_key_size, PUBLIC_KEY_SIZE) -CONST_FUNCTION(secret_key_size, SECRET_KEY_SIZE) -CONST_FUNCTION(address_size, ADDRESS_SIZE) -CONST_FUNCTION(max_name_length, MAX_NAME_LENGTH) -CONST_FUNCTION(max_status_message_length, MAX_STATUS_MESSAGE_LENGTH) -CONST_FUNCTION(max_friend_request_length, MAX_FRIEND_REQUEST_LENGTH) -CONST_FUNCTION(max_message_length, MAX_MESSAGE_LENGTH) -CONST_FUNCTION(max_custom_packet_size, MAX_CUSTOM_PACKET_SIZE) -CONST_FUNCTION(hash_length, HASH_LENGTH) -CONST_FUNCTION(file_id_length, FILE_ID_LENGTH) -CONST_FUNCTION(max_filename_length, MAX_FILENAME_LENGTH) - - -#define ACCESSORS(type, ns, name) \ -type tox_options_get_##ns##name(const struct Tox_Options *options) \ -{ \ - return options->ns##name; \ -} \ -void tox_options_set_##ns##name(struct Tox_Options *options, type name) \ -{ \ - options->ns##name = name; \ -} - -ACCESSORS(bool, , ipv6_enabled) -ACCESSORS(bool, , udp_enabled) -ACCESSORS(TOX_PROXY_TYPE, proxy_ , type) -ACCESSORS(const char *, proxy_ , host) -ACCESSORS(uint16_t, proxy_ , port) -ACCESSORS(uint16_t, , start_port) -ACCESSORS(uint16_t, , end_port) -ACCESSORS(uint16_t, , tcp_port) -ACCESSORS(bool, , hole_punching_enabled) -ACCESSORS(TOX_SAVEDATA_TYPE, savedata_, type) -ACCESSORS(size_t, savedata_, length) -ACCESSORS(tox_log_cb *, log_, callback) -ACCESSORS(void *, log_, user_data) -ACCESSORS(bool, , local_discovery_enabled) - -const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options) -{ - return options->savedata_data; -} - -void tox_options_set_savedata_data(struct Tox_Options *options, const uint8_t *data, size_t length) -{ - options->savedata_data = data; - options->savedata_length = length; -} - - -void tox_options_default(struct Tox_Options *options) -{ - if (options) { - memset(options, 0, sizeof(struct Tox_Options)); - options->ipv6_enabled = 1; - options->udp_enabled = 1; - options->proxy_type = TOX_PROXY_TYPE_NONE; - options->hole_punching_enabled = true; - options->local_discovery_enabled = true; - } -} - -struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error) -{ - struct Tox_Options *options = (struct Tox_Options *)calloc(sizeof(struct Tox_Options), 1); - - if (options) { - tox_options_default(options); - SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK); - return options; - } - - SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC); - return NULL; -} - -void tox_options_free(struct Tox_Options *options) -{ - free(options); -} - Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error) { Messenger_Options m_options = {0}; @@ -186,27 +85,27 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error) if (options == NULL) { m_options.ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; } else { - if (options->savedata_type != TOX_SAVEDATA_TYPE_NONE) { - if (options->savedata_data == NULL || options->savedata_length == 0) { + if (tox_options_get_savedata_type(options) != TOX_SAVEDATA_TYPE_NONE) { + if (tox_options_get_savedata_data(options) == NULL || tox_options_get_savedata_length(options) == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); return NULL; } } - if (options->savedata_type == TOX_SAVEDATA_TYPE_SECRET_KEY) { - if (options->savedata_length != TOX_SECRET_KEY_SIZE) { + if (tox_options_get_savedata_type(options) == TOX_SAVEDATA_TYPE_SECRET_KEY) { + if (tox_options_get_savedata_length(options) != TOX_SECRET_KEY_SIZE) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); return NULL; } load_savedata_sk = 1; - } else if (options->savedata_type == TOX_SAVEDATA_TYPE_TOX_SAVE) { - if (options->savedata_length < TOX_ENC_SAVE_MAGIC_LENGTH) { + } else if (tox_options_get_savedata_type(options) == TOX_SAVEDATA_TYPE_TOX_SAVE) { + if (tox_options_get_savedata_length(options) < TOX_ENC_SAVE_MAGIC_LENGTH) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); return NULL; } - if (crypto_memcmp(options->savedata_data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) { + if (crypto_memcmp(tox_options_get_savedata_data(options), TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED); return NULL; } @@ -214,18 +113,18 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error) load_savedata_tox = 1; } - m_options.ipv6enabled = options->ipv6_enabled; - m_options.udp_disabled = !options->udp_enabled; - m_options.port_range[0] = options->start_port; - m_options.port_range[1] = options->end_port; - m_options.tcp_server_port = options->tcp_port; - m_options.hole_punching_enabled = options->hole_punching_enabled; - m_options.local_discovery_enabled = options->local_discovery_enabled; + m_options.ipv6enabled = tox_options_get_ipv6_enabled(options); + m_options.udp_disabled = !tox_options_get_udp_enabled(options); + m_options.port_range[0] = tox_options_get_start_port(options); + m_options.port_range[1] = tox_options_get_end_port(options); + m_options.tcp_server_port = tox_options_get_tcp_port(options); + m_options.hole_punching_enabled = tox_options_get_hole_punching_enabled(options); + m_options.local_discovery_enabled = tox_options_get_local_discovery_enabled(options); - m_options.log_callback = (logger_cb *)options->log_callback; - m_options.log_user_data = options->log_user_data; + m_options.log_callback = (logger_cb *)tox_options_get_log_callback(options); + m_options.log_user_data = tox_options_get_log_user_data(options); - switch (options->proxy_type) { + switch (tox_options_get_proxy_type(options)) { case TOX_PROXY_TYPE_HTTP: m_options.proxy_info.proxy_type = TCP_PROXY_HTTP; break; @@ -244,7 +143,7 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error) } if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) { - if (options->proxy_port == 0) { + if (tox_options_get_proxy_port(options) == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT); return NULL; } @@ -255,13 +154,13 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error) m_options.proxy_info.ip_port.ip.family = AF_UNSPEC; } - if (!addr_resolve_or_parse_ip(options->proxy_host, &m_options.proxy_info.ip_port.ip, NULL)) { + if (!addr_resolve_or_parse_ip(tox_options_get_proxy_host(options), &m_options.proxy_info.ip_port.ip, NULL)) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST); // TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain. return NULL; } - m_options.proxy_info.ip_port.port = htons(options->proxy_port); + m_options.proxy_info.ip_port.port = htons(tox_options_get_proxy_port(options)); } } @@ -282,10 +181,11 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error) return NULL; } - if (load_savedata_tox && messenger_load(m, options->savedata_data, options->savedata_length) == -1) { + if (load_savedata_tox + && messenger_load(m, tox_options_get_savedata_data(options), tox_options_get_savedata_length(options)) == -1) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); } else if (load_savedata_sk) { - load_secret_key(m->net_crypto, options->savedata_data); + load_secret_key(m->net_crypto, tox_options_get_savedata_data(options)); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK); } else { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK); diff --git a/toxcore/tox_api.c b/toxcore/tox_api.c new file mode 100644 index 0000000000..b6c8c38618 --- /dev/null +++ b/toxcore/tox_api.c @@ -0,0 +1,97 @@ +#include "tox.h" + +#include <stdlib.h> +#include <string.h> + +#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} + + +#define CONST_FUNCTION(lowercase, uppercase) \ +uint32_t tox_##lowercase(void) \ +{ \ + return TOX_##uppercase; \ +} + +CONST_FUNCTION(version_major, VERSION_MAJOR) +CONST_FUNCTION(version_minor, VERSION_MINOR) +CONST_FUNCTION(version_patch, VERSION_PATCH) +CONST_FUNCTION(public_key_size, PUBLIC_KEY_SIZE) +CONST_FUNCTION(secret_key_size, SECRET_KEY_SIZE) +CONST_FUNCTION(address_size, ADDRESS_SIZE) +CONST_FUNCTION(max_name_length, MAX_NAME_LENGTH) +CONST_FUNCTION(max_status_message_length, MAX_STATUS_MESSAGE_LENGTH) +CONST_FUNCTION(max_friend_request_length, MAX_FRIEND_REQUEST_LENGTH) +CONST_FUNCTION(max_message_length, MAX_MESSAGE_LENGTH) +CONST_FUNCTION(max_custom_packet_size, MAX_CUSTOM_PACKET_SIZE) +CONST_FUNCTION(hash_length, HASH_LENGTH) +CONST_FUNCTION(file_id_length, FILE_ID_LENGTH) +CONST_FUNCTION(max_filename_length, MAX_FILENAME_LENGTH) + + +#define ACCESSORS(type, ns, name) \ +type tox_options_get_##ns##name(const struct Tox_Options *options) \ +{ \ + return options->ns##name; \ +} \ +void tox_options_set_##ns##name(struct Tox_Options *options, type name) \ +{ \ + options->ns##name = name; \ +} + +ACCESSORS(bool, , ipv6_enabled) +ACCESSORS(bool, , udp_enabled) +ACCESSORS(TOX_PROXY_TYPE, proxy_ , type) +ACCESSORS(const char *, proxy_ , host) +ACCESSORS(uint16_t, proxy_ , port) +ACCESSORS(uint16_t, , start_port) +ACCESSORS(uint16_t, , end_port) +ACCESSORS(uint16_t, , tcp_port) +ACCESSORS(bool, , hole_punching_enabled) +ACCESSORS(TOX_SAVEDATA_TYPE, savedata_, type) +ACCESSORS(size_t, savedata_, length) +ACCESSORS(tox_log_cb *, log_, callback) +ACCESSORS(void *, log_, user_data) +ACCESSORS(bool, , local_discovery_enabled) + +const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options) +{ + return options->savedata_data; +} + +void tox_options_set_savedata_data(struct Tox_Options *options, const uint8_t *data, size_t length) +{ + options->savedata_data = data; + options->savedata_length = length; +} + +void tox_options_default(struct Tox_Options *options) +{ + if (options) { + struct Tox_Options default_options = { 0 }; + *options = default_options; + tox_options_set_ipv6_enabled(options, true); + tox_options_set_udp_enabled(options, true); + tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE); + tox_options_set_hole_punching_enabled(options, true); + tox_options_set_local_discovery_enabled(options, true); + } +} + +struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error) +{ + struct Tox_Options *options = (struct Tox_Options *)malloc(sizeof(struct Tox_Options)); + + if (options) { + tox_options_default(options); + SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK); + return options; + } + + SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC); + return NULL; +} + +void tox_options_free(struct Tox_Options *options) +{ + free(options); +}