2013-08-23 22:29:13 +08:00
|
|
|
/* tox.c
|
|
|
|
*
|
|
|
|
* The Tox public API.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 Tox project All Rights Reserved.
|
|
|
|
*
|
|
|
|
* This file is part of Tox.
|
|
|
|
*
|
|
|
|
* Tox is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Tox is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
2015-02-16 09:20:06 +08:00
|
|
|
|
2013-09-05 18:02:26 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2013-08-23 22:29:13 +08:00
|
|
|
#include "Messenger.h"
|
2014-09-27 01:25:52 +08:00
|
|
|
#include "group.h"
|
2014-04-28 01:21:26 +08:00
|
|
|
#include "logger.h"
|
2013-10-02 22:38:54 +08:00
|
|
|
|
2015-02-15 12:00:12 +08:00
|
|
|
#include "../toxencryptsave/defines.h"
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
#define TOX_DEFINED
|
2013-10-02 22:38:54 +08:00
|
|
|
typedef struct Messenger Tox;
|
|
|
|
|
|
|
|
#include "tox.h"
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}}
|
2014-09-06 09:31:35 +08:00
|
|
|
|
2015-03-18 04:02:46 +08:00
|
|
|
#if TOX_HASH_LENGTH != crypto_hash_sha256_BYTES
|
|
|
|
#error TOX_HASH_LENGTH is assumed to be equal to crypto_hash_sha256_BYTES
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if FILE_ID_LENGTH != crypto_box_KEYBYTES
|
|
|
|
#error FILE_ID_LENGTH is assumed to be equal to crypto_box_KEYBYTES
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if TOX_FILE_ID_LENGTH != crypto_box_KEYBYTES
|
|
|
|
#error TOX_FILE_ID_LENGTH is assumed to be equal to crypto_box_KEYBYTES
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if TOX_FILE_ID_LENGTH != TOX_HASH_LENGTH
|
|
|
|
#error TOX_FILE_ID_LENGTH is assumed to be equal to TOX_HASH_LENGTH
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if TOX_PUBLIC_KEY_SIZE != crypto_box_PUBLICKEYBYTES
|
|
|
|
#error TOX_PUBLIC_KEY_SIZE is assumed to be equal to crypto_box_PUBLICKEYBYTES
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if TOX_SECRET_KEY_SIZE != crypto_box_SECRETKEYBYTES
|
|
|
|
#error TOX_SECRET_KEY_SIZE is assumed to be equal to crypto_box_SECRETKEYBYTES
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if TOX_MAX_NAME_LENGTH != MAX_NAME_LENGTH
|
|
|
|
#error TOX_MAX_NAME_LENGTH is assumed to be equal to MAX_NAME_LENGTH
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if TOX_MAX_STATUS_MESSAGE_LENGTH != MAX_STATUSMESSAGE_LENGTH
|
|
|
|
#error TOX_MAX_STATUS_MESSAGE_LENGTH is assumed to be equal to MAX_STATUSMESSAGE_LENGTH
|
|
|
|
#endif
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
uint32_t tox_version_major(void)
|
2014-11-20 10:36:09 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
return 0;
|
2014-11-20 10:36:09 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
uint32_t tox_version_minor(void)
|
2014-10-15 07:43:54 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
return 0;
|
2014-10-15 07:43:54 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
uint32_t tox_version_patch(void)
|
2013-11-23 12:31:55 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
return 0;
|
2013-11-23 12:31:55 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch)
|
2013-11-19 12:05:35 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
//TODO
|
|
|
|
return 1;
|
2014-09-23 03:12:48 +08:00
|
|
|
}
|
|
|
|
|
2013-09-13 08:29:30 +08:00
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
void tox_options_default(struct Tox_Options *options)
|
2013-08-23 22:29:13 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
if (options) {
|
|
|
|
memset(options, 0, sizeof(struct Tox_Options));
|
2015-02-15 12:00:12 +08:00
|
|
|
options->ipv6_enabled = 1;
|
|
|
|
options->udp_enabled = 1;
|
|
|
|
options->proxy_type = TOX_PROXY_TYPE_NONE;
|
2014-05-20 06:10:40 +08:00
|
|
|
}
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
2013-10-02 22:38:54 +08:00
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error)
|
2013-09-10 01:17:21 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
struct Tox_Options *options = calloc(sizeof(struct Tox_Options), 1);
|
2014-09-21 22:12:55 +08:00
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
if (options) {
|
2015-03-15 19:47:59 +08:00
|
|
|
tox_options_default(options);
|
2015-02-14 05:18:02 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK);
|
|
|
|
return options;
|
2014-09-21 00:19:21 +08:00
|
|
|
}
|
2013-08-23 22:29:13 +08:00
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC);
|
|
|
|
return NULL;
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 05:18:02 +08:00
|
|
|
void tox_options_free(struct Tox_Options *options)
|
2014-05-31 01:20:36 +08:00
|
|
|
{
|
2015-02-14 05:18:02 +08:00
|
|
|
free(options);
|
2014-05-31 01:20:36 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t length, TOX_ERR_NEW *error)
|
2013-09-10 02:14:24 +08:00
|
|
|
{
|
2015-02-15 12:00:12 +08:00
|
|
|
if (!logger_get_global())
|
|
|
|
logger_set_global(logger_new(LOGGER_OUTPUT_FILE, LOGGER_LEVEL, "toxcore"));
|
|
|
|
|
2015-03-13 00:19:59 +08:00
|
|
|
if (data == NULL && length != 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-02-15 12:00:12 +08:00
|
|
|
if (data) {
|
2015-03-13 01:11:28 +08:00
|
|
|
if (length < TOX_ENC_SAVE_MAGIC_LENGTH) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-02-15 12:00:12 +08:00
|
|
|
if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger_Options m_options = {0};
|
|
|
|
|
|
|
|
if (options == NULL) {
|
|
|
|
m_options.ipv6enabled = TOX_ENABLE_IPV6_DEFAULT;
|
|
|
|
} else {
|
|
|
|
m_options.ipv6enabled = options->ipv6_enabled;
|
|
|
|
m_options.udp_disabled = !options->udp_enabled;
|
2015-02-28 01:58:00 +08:00
|
|
|
m_options.port_range[0] = options->start_port;
|
|
|
|
m_options.port_range[1] = options->end_port;
|
2015-02-15 12:00:12 +08:00
|
|
|
|
|
|
|
switch (options->proxy_type) {
|
|
|
|
case TOX_PROXY_TYPE_HTTP:
|
|
|
|
m_options.proxy_info.proxy_type = TCP_PROXY_HTTP;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TOX_PROXY_TYPE_SOCKS5:
|
|
|
|
m_options.proxy_info.proxy_type = TCP_PROXY_SOCKS5;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TOX_PROXY_TYPE_NONE:
|
|
|
|
m_options.proxy_info.proxy_type = TCP_PROXY_NONE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2015-03-16 10:25:06 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_TYPE);
|
2015-02-15 12:00:12 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) {
|
|
|
|
if (options->proxy_port == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ip_init(&m_options.proxy_info.ip_port.ip, m_options.ipv6enabled);
|
|
|
|
|
|
|
|
if (m_options.ipv6enabled)
|
|
|
|
m_options.proxy_info.ip_port.ip.family = AF_UNSPEC;
|
2014-08-15 06:34:20 +08:00
|
|
|
|
2015-03-16 10:25:06 +08:00
|
|
|
if (!addr_resolve_or_parse_ip(options->proxy_host, &m_options.proxy_info.ip_port.ip, NULL)) {
|
2015-02-15 12:00:12 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST);
|
|
|
|
//TODO: TOX_ERR_NEW_PROXY_NOT_FOUND if domain.
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_options.proxy_info.ip_port.port = htons(options->proxy_port);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-13 01:03:14 +08:00
|
|
|
unsigned int m_error;
|
|
|
|
Messenger *m = new_messenger(&m_options, &m_error);
|
2015-02-15 12:00:12 +08:00
|
|
|
|
|
|
|
if (!new_groupchats(m)) {
|
|
|
|
kill_messenger(m);
|
2015-03-13 01:03:14 +08:00
|
|
|
|
|
|
|
if (m_error == MESSENGER_ERROR_PORT) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PORT_ALLOC);
|
|
|
|
} else {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
|
|
|
}
|
|
|
|
|
2015-02-15 12:00:12 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-03-13 01:11:28 +08:00
|
|
|
if (data && length && messenger_load(m, data, length) == -1) {
|
2015-02-15 12:00:12 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
|
2015-03-13 00:19:59 +08:00
|
|
|
} else {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_OK);
|
2015-02-15 12:00:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return m;
|
2013-09-10 02:14:24 +08:00
|
|
|
}
|
2013-08-23 22:29:13 +08:00
|
|
|
|
2013-10-02 22:38:54 +08:00
|
|
|
void tox_kill(Tox *tox)
|
2013-08-23 22:29:13 +08:00
|
|
|
{
|
2015-02-15 12:00:12 +08:00
|
|
|
Messenger *m = tox;
|
|
|
|
kill_groupchats(m->group_chat_object);
|
|
|
|
kill_messenger(m);
|
|
|
|
logger_kill_global();
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
|
|
|
|
2015-03-18 04:20:38 +08:00
|
|
|
size_t tox_get_savedata_size(const Tox *tox)
|
2013-08-23 22:29:13 +08:00
|
|
|
{
|
2015-02-15 12:00:12 +08:00
|
|
|
const Messenger *m = tox;
|
|
|
|
return messenger_size(m);
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
|
|
|
|
2015-03-18 04:20:38 +08:00
|
|
|
void tox_get_savedata(const Tox *tox, uint8_t *data)
|
2013-08-23 22:29:13 +08:00
|
|
|
{
|
2015-02-17 09:57:44 +08:00
|
|
|
if (data) {
|
|
|
|
const Messenger *m = tox;
|
|
|
|
messenger_save(m, data);
|
|
|
|
}
|
2013-08-23 22:29:13 +08:00
|
|
|
}
|
2015-02-16 09:20:06 +08:00
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
static int address_to_ip(Messenger *m, const char *address, IP_Port *ip_port, IP_Port *ip_port_v4)
|
2015-02-16 09:20:06 +08:00
|
|
|
{
|
|
|
|
if (!addr_parse_ip(address, &ip_port->ip)) {
|
|
|
|
if (m->options.udp_disabled) { /* Disable DNS when udp is disabled. */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
IP *ip_extra = NULL;
|
|
|
|
ip_init(&ip_port->ip, m->options.ipv6enabled);
|
|
|
|
|
|
|
|
if (m->options.ipv6enabled && ip_port_v4) {
|
|
|
|
/* setup for getting BOTH: an IPv6 AND an IPv4 address */
|
|
|
|
ip_port->ip.family = AF_UNSPEC;
|
|
|
|
ip_reset(&ip_port_v4->ip);
|
|
|
|
ip_extra = &ip_port_v4->ip;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!addr_resolve(address, &ip_port->ip, ip_extra)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error)
|
2015-02-16 09:20:06 +08:00
|
|
|
{
|
2015-02-17 09:57:44 +08:00
|
|
|
if (!address || !public_key) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-02-16 09:20:06 +08:00
|
|
|
Messenger *m = tox;
|
|
|
|
bool ret = tox_add_tcp_relay(tox, address, port, public_key, error);
|
|
|
|
|
|
|
|
if (!ret) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m->options.udp_disabled) {
|
|
|
|
return ret;
|
|
|
|
} else { /* DHT only works on UDP. */
|
|
|
|
if (DHT_bootstrap_from_address(m->dht, address, m->options.ipv6enabled, htons(port), public_key) == 0) {
|
2015-03-16 10:25:06 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
|
2015-02-16 09:20:06 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key,
|
2015-02-16 09:20:06 +08:00
|
|
|
TOX_ERR_BOOTSTRAP *error)
|
|
|
|
{
|
2015-02-17 09:57:44 +08:00
|
|
|
if (!address || !public_key) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-02-16 09:20:06 +08:00
|
|
|
Messenger *m = tox;
|
|
|
|
IP_Port ip_port, ip_port_v4;
|
|
|
|
|
|
|
|
if (port == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (address_to_ip(m, address, &ip_port, &ip_port_v4) == -1) {
|
2015-03-16 10:25:06 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
|
2015-02-16 09:20:06 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ip_port.port = htons(port);
|
|
|
|
add_tcp_relay(m->net_crypto, ip_port, public_key);
|
|
|
|
onion_add_bs_path_node(m->onion_c, ip_port, public_key); //TODO: move this
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
TOX_CONNECTION tox_get_connection_status(const Tox *tox)
|
2015-02-16 09:20:06 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
|
2015-03-12 03:37:25 +08:00
|
|
|
unsigned int ret = onion_connection_status(m->onion_c);
|
2015-02-16 09:20:06 +08:00
|
|
|
|
2015-03-12 03:37:25 +08:00
|
|
|
if (ret == 2) {
|
|
|
|
return TOX_CONNECTION_UDP;
|
|
|
|
} else if (ret == 1) {
|
2015-02-16 09:20:06 +08:00
|
|
|
return TOX_CONNECTION_TCP;
|
2015-03-12 03:37:25 +08:00
|
|
|
} else {
|
|
|
|
return TOX_CONNECTION_NONE;
|
2015-02-16 09:20:06 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void tox_callback_connection_status(Tox *tox, tox_connection_status_cb *function, void *user_data)
|
|
|
|
{
|
2015-03-12 03:37:25 +08:00
|
|
|
Messenger *m = tox;
|
|
|
|
m_callback_core_connection(m, function, user_data);
|
2015-02-16 09:20:06 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
uint32_t tox_iteration_interval(const Tox *tox)
|
2015-02-16 09:20:06 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
return messenger_run_interval(m);
|
|
|
|
}
|
|
|
|
|
2015-03-12 06:26:25 +08:00
|
|
|
void tox_iterate(Tox *tox)
|
2015-02-16 09:20:06 +08:00
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
do_messenger(m);
|
|
|
|
do_groupchats(m->group_chat_object);
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
void tox_self_get_address(const Tox *tox, uint8_t *address)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
if (address) {
|
|
|
|
const Messenger *m = tox;
|
|
|
|
getaddress(m, address);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_self_set_nospam(Tox *tox, uint32_t nospam)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
set_nospam(&(m->fr), nospam);
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
uint32_t tox_self_get_nospam(const Tox *tox)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
return get_nospam(&(m->fr));
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
void tox_self_get_public_key(const Tox *tox, uint8_t *public_key)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
|
|
|
|
if (public_key)
|
|
|
|
memcpy(public_key, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES);
|
|
|
|
}
|
|
|
|
|
2015-03-16 10:25:06 +08:00
|
|
|
void tox_self_get_secret_key(const Tox *tox, uint8_t *secret_key)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
|
2015-03-16 10:25:06 +08:00
|
|
|
if (secret_key)
|
|
|
|
memcpy(secret_key, m->net_crypto->self_secret_key, crypto_box_SECRETKEYBYTES);
|
2015-02-17 09:57:44 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, TOX_ERR_SET_INFO *error)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
if (!name && length != 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = tox;
|
|
|
|
|
|
|
|
if (setname(m, name, length) == 0) {
|
|
|
|
//TODO: function to set different per group names?
|
|
|
|
send_name_all_groups(m->group_chat_object);
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_OK);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_TOO_LONG);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
size_t tox_self_get_name_size(const Tox *tox)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
return m_get_self_name_size(m);
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
void tox_self_get_name(const Tox *tox, uint8_t *name)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
if (name) {
|
|
|
|
const Messenger *m = tox;
|
|
|
|
getself_name(m, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
bool tox_self_set_status_message(Tox *tox, const uint8_t *status, size_t length, TOX_ERR_SET_INFO *error)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
if (!status && length != 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = tox;
|
|
|
|
|
|
|
|
if (m_set_statusmessage(m, status, length) == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_OK);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_SET_INFO_TOO_LONG);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
size_t tox_self_get_status_message_size(const Tox *tox)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
return m_get_self_statusmessage_size(m);
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
void tox_self_get_status_message(const Tox *tox, uint8_t *status)
|
2015-02-17 09:57:44 +08:00
|
|
|
{
|
|
|
|
if (status) {
|
|
|
|
const Messenger *m = tox;
|
|
|
|
m_copy_self_statusmessage(m, status);
|
|
|
|
}
|
|
|
|
}
|
2015-02-18 05:21:47 +08:00
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
void tox_self_set_status(Tox *tox, TOX_USER_STATUS user_status)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
m_set_userstatus(m, user_status);
|
|
|
|
}
|
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
TOX_USER_STATUS tox_self_get_status(const Tox *tox)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
return m_get_self_userstatus(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_friend_error(int32_t ret, TOX_ERR_FRIEND_ADD *error)
|
|
|
|
{
|
|
|
|
switch (ret) {
|
|
|
|
case FAERR_TOOLONG:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_TOO_LONG);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FAERR_NOMESSAGE:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_NO_MESSAGE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FAERR_OWNKEY:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OWN_KEY);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FAERR_ALREADYSENT:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_ALREADY_SENT);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FAERR_BADCHECKSUM:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_BAD_CHECKSUM);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FAERR_SETNEWNOSPAM:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FAERR_NOMEM:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_MALLOC);
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length,
|
2015-02-18 05:21:47 +08:00
|
|
|
TOX_ERR_FRIEND_ADD *error)
|
|
|
|
{
|
|
|
|
if (!address || !message) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_NULL);
|
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = tox;
|
|
|
|
int32_t ret = m_addfriend(m, address, message, length);
|
|
|
|
|
|
|
|
if (ret >= 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OK);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_friend_error(ret, error);
|
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_ADD *error)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
if (!public_key) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_NULL);
|
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = tox;
|
|
|
|
int32_t ret = m_addfriend_norequest(m, public_key);
|
|
|
|
|
|
|
|
if (ret >= 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OK);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_friend_error(ret, error);
|
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE *error)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
int ret = m_delfriend(m, friend_number);
|
|
|
|
|
|
|
|
//TODO handle if realloc fails?
|
|
|
|
if (ret == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_DELETE_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_BY_PUBLIC_KEY *error)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
if (!public_key) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL);
|
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Messenger *m = tox;
|
|
|
|
int32_t ret = getfriend_id(m, public_key);
|
|
|
|
|
|
|
|
if (ret == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND);
|
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key,
|
2015-02-18 05:21:47 +08:00
|
|
|
TOX_ERR_FRIEND_GET_PUBLIC_KEY *error)
|
|
|
|
{
|
|
|
|
if (!public_key) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Messenger *m = tox;
|
|
|
|
|
|
|
|
if (get_real_pk(m, friend_number, public_key) == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
bool tox_friend_exists(const Tox *tox, uint32_t friend_number)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
return m_friend_exists(m, friend_number);
|
|
|
|
}
|
|
|
|
|
2015-03-16 10:25:06 +08:00
|
|
|
size_t tox_self_get_friend_list_size(const Tox *tox)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
return count_friendlist(m);
|
|
|
|
}
|
|
|
|
|
2015-03-16 10:25:06 +08:00
|
|
|
void tox_self_get_friend_list(const Tox *tox, uint32_t *list)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
if (list) {
|
|
|
|
const Messenger *m = tox;
|
|
|
|
//TODO: size parameter?
|
2015-03-16 10:25:06 +08:00
|
|
|
copy_friendlist(m, list, tox_self_get_friend_list_size(tox));
|
2015-02-18 05:21:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
int ret = m_get_name_size(m, friend_number);
|
|
|
|
|
|
|
|
if (ret == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND);
|
|
|
|
return SIZE_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, TOX_ERR_FRIEND_QUERY *error)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
if (!name) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Messenger *m = tox;
|
|
|
|
int ret = getname(m, friend_number, name);
|
|
|
|
|
|
|
|
if (ret == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
2015-02-26 08:50:18 +08:00
|
|
|
m_callback_namechange(m, function, user_data);
|
2015-02-18 05:21:47 +08:00
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error)
|
2015-02-18 05:21:47 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
int ret = m_get_statusmessage_size(m, friend_number);
|
|
|
|
|
|
|
|
if (ret == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND);
|
|
|
|
return SIZE_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:24:39 +08:00
|
|
|
bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8_t *message,
|
2015-02-18 05:21:47 +08:00
|
|
|
TOX_ERR_FRIEND_QUERY *error)
|
|
|
|
{
|
|
|
|
if (!message) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Messenger *m = tox;
|
|
|
|
//TODO: size parameter?
|
|
|
|
int ret = m_copy_statusmessage(m, friend_number, message, m_get_statusmessage_size(m, friend_number));
|
|
|
|
|
|
|
|
if (ret == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
m_callback_statusmessage(m, function, user_data);
|
|
|
|
}
|
2015-02-20 05:54:49 +08:00
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
TOX_USER_STATUS tox_friend_get_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error)
|
2015-02-20 05:54:49 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
|
|
|
|
int ret = m_get_userstatus(m, friend_number);
|
|
|
|
|
|
|
|
if (ret == USERSTATUS_INVALID) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND);
|
2015-03-01 05:26:19 +08:00
|
|
|
return TOX_USER_STATUS_INVALID;
|
2015-02-20 05:54:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
m_callback_userstatus(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
2015-02-20 09:51:19 +08:00
|
|
|
TOX_CONNECTION tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error)
|
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
|
|
|
|
int ret = m_get_friend_connectionstatus(m, friend_number);
|
|
|
|
|
|
|
|
if (ret == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND);
|
|
|
|
return TOX_CONNECTION_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_status_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
m_callback_connectionstatus(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error)
|
2015-02-20 05:54:49 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
int ret = m_get_istyping(m, friend_number);
|
2015-02-20 09:51:19 +08:00
|
|
|
|
2015-02-20 05:54:49 +08:00
|
|
|
if (ret == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK);
|
|
|
|
return !!ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
m_callback_typingchange(m, function, user_data);
|
|
|
|
}
|
2015-02-21 06:24:24 +08:00
|
|
|
|
|
|
|
bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool is_typing, TOX_ERR_SET_TYPING *error)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
|
|
|
|
if (m_set_usertyping(m, friend_number, is_typing) == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_SET_TYPING_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
static void set_message_error(int ret, TOX_ERR_FRIEND_SEND_MESSAGE *error)
|
2015-02-21 06:24:24 +08:00
|
|
|
{
|
|
|
|
switch (ret) {
|
|
|
|
case 0:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_OK);
|
2015-02-21 06:24:24 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case -1:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND);
|
2015-02-21 06:24:24 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case -2:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG);
|
2015-02-21 06:24:24 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case -3:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED);
|
2015-02-21 06:24:24 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case -4:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ);
|
2015-02-21 06:24:24 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length,
|
2015-03-14 03:29:34 +08:00
|
|
|
TOX_ERR_FRIEND_SEND_MESSAGE *error)
|
2015-02-21 06:24:24 +08:00
|
|
|
{
|
|
|
|
if (!message) {
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_NULL);
|
2015-02-21 06:24:24 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!length) {
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY);
|
2015-02-21 06:24:24 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = tox;
|
|
|
|
uint32_t message_id = 0;
|
|
|
|
set_message_error(m_sendmessage(m, friend_number, message, length, &message_id), error);
|
|
|
|
return message_id;
|
|
|
|
}
|
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
uint32_t tox_friend_send_action(Tox *tox, uint32_t friend_number, const uint8_t *action, size_t length,
|
2015-03-14 03:29:34 +08:00
|
|
|
TOX_ERR_FRIEND_SEND_MESSAGE *error)
|
2015-02-21 06:24:24 +08:00
|
|
|
{
|
|
|
|
if (!action) {
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_NULL);
|
2015-02-21 06:24:24 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!length) {
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY);
|
2015-02-21 06:24:24 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = tox;
|
|
|
|
uint32_t message_id = 0;
|
|
|
|
set_message_error(m_sendaction(m, friend_number, action, length, &message_id), error);
|
|
|
|
return message_id;
|
|
|
|
}
|
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *function, void *user_data)
|
2015-02-21 06:24:24 +08:00
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
m_callback_read_receipt(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
2015-02-21 07:17:32 +08:00
|
|
|
void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
m_callback_friendrequest(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
m_callback_friendmessage(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_friend_action(Tox *tox, tox_friend_action_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
m_callback_action(m, function, user_data);
|
|
|
|
}
|
2015-02-21 06:24:24 +08:00
|
|
|
|
2015-03-11 05:31:50 +08:00
|
|
|
bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length)
|
|
|
|
{
|
|
|
|
if (!hash || !data) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
crypto_hash_sha256(hash, data, length);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-03-12 06:26:25 +08:00
|
|
|
bool tox_file_send_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control,
|
2015-03-14 03:29:34 +08:00
|
|
|
TOX_ERR_FILE_CONTROL *error)
|
2015-03-11 05:31:50 +08:00
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
int ret = file_control(m, friend_number, file_number, control);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (ret) {
|
|
|
|
case -1:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -2:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -3:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -4:
|
|
|
|
/* can't happen */
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -5:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_ALREADY_PAUSED);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -6:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_DENIED);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -7:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_NOT_PAUSED);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -8:
|
2015-03-18 05:13:25 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_SENDQ);
|
2015-03-11 05:31:50 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* can't happen */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-18 03:05:17 +08:00
|
|
|
bool tox_file_send_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
|
|
|
|
TOX_ERR_FILE_SEEK *error)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
int ret = file_seek(m, friend_number, file_number, position);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (ret) {
|
|
|
|
case -1:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -2:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -3:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -4:
|
|
|
|
case -5:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_DENIED);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -6:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_INVALID_POSITION);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -8:
|
2015-03-18 05:13:25 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_SENDQ);
|
2015-03-18 03:05:17 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* can't happen */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
void tox_callback_file_recv_control(Tox *tox, tox_file_recv_control_cb *function, void *user_data)
|
2015-03-11 05:31:50 +08:00
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
callback_file_control(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
2015-03-18 01:44:48 +08:00
|
|
|
bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id,
|
|
|
|
TOX_ERR_FILE_GET *error)
|
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
int ret = file_get_id(m, friend_number, file_number, file_id);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_GET_OK);
|
|
|
|
return 1;
|
|
|
|
} else if (ret == -1) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_GET_FRIEND_NOT_FOUND);
|
|
|
|
} else {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_GET_NOT_FOUND);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id,
|
|
|
|
const uint8_t *filename, size_t filename_length, TOX_ERR_FILE_SEND *error)
|
2015-03-11 05:31:50 +08:00
|
|
|
{
|
2015-03-18 01:47:09 +08:00
|
|
|
if (filename_length && !filename) {
|
2015-03-11 05:31:50 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_NULL);
|
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
2015-03-18 01:44:48 +08:00
|
|
|
uint8_t f_id[FILE_ID_LENGTH];
|
|
|
|
|
|
|
|
if (!file_id) {
|
|
|
|
/* Tox keys are 32 bytes like FILE_ID_LENGTH. */
|
|
|
|
new_symmetric_key(f_id);
|
|
|
|
file_id = f_id;
|
2015-03-11 05:31:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = tox;
|
2015-03-18 01:44:48 +08:00
|
|
|
long int file_num = new_filesender(m, friend_number, kind, file_size, file_id, filename, filename_length);
|
2015-03-11 05:31:50 +08:00
|
|
|
|
|
|
|
if (file_num >= 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_OK);
|
|
|
|
return file_num;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (file_num) {
|
|
|
|
case -1:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND);
|
|
|
|
return UINT32_MAX;
|
|
|
|
|
|
|
|
case -2:
|
2015-03-18 04:00:03 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_NAME_TOO_LONG);
|
2015-03-11 05:31:50 +08:00
|
|
|
return UINT32_MAX;
|
|
|
|
|
|
|
|
case -3:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_TOO_MANY);
|
|
|
|
return UINT32_MAX;
|
|
|
|
|
|
|
|
case -4:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED);
|
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* can't happen */
|
|
|
|
return UINT32_MAX;
|
|
|
|
}
|
|
|
|
|
2015-03-13 03:17:34 +08:00
|
|
|
bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data,
|
|
|
|
size_t length, TOX_ERR_FILE_SEND_CHUNK *error)
|
2015-03-11 05:31:50 +08:00
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
2015-03-13 03:17:34 +08:00
|
|
|
int ret = file_data(m, friend_number, file_number, position, data, length);
|
2015-03-11 05:31:50 +08:00
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_OK);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (ret) {
|
|
|
|
case -1:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -2:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -3:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -4:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -5:
|
2015-03-14 00:40:21 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH);
|
2015-03-11 05:31:50 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
case -6:
|
2015-03-16 10:25:06 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_SENDQ);
|
2015-03-11 05:31:50 +08:00
|
|
|
return 0;
|
2015-03-13 03:17:34 +08:00
|
|
|
|
|
|
|
case -7:
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION);
|
|
|
|
return 0;
|
2015-03-11 05:31:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* can't happen */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_file_request_chunk(Tox *tox, tox_file_request_chunk_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
callback_file_reqchunk(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
2015-03-19 00:54:00 +08:00
|
|
|
void tox_callback_file_recv(Tox *tox, tox_file_recv_cb *function, void *user_data)
|
2015-03-11 05:31:50 +08:00
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
callback_file_sendrequest(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
2015-03-19 00:54:00 +08:00
|
|
|
void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *function, void *user_data)
|
2015-03-11 05:31:50 +08:00
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
callback_file_data(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
static void set_custom_packet_error(int ret, TOX_ERR_FRIEND_CUSTOM_PACKET *error)
|
2015-02-27 02:17:22 +08:00
|
|
|
{
|
|
|
|
switch (ret) {
|
|
|
|
case 0:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_OK);
|
2015-02-27 02:17:22 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case -1:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND);
|
2015-02-27 02:17:22 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case -2:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG);
|
2015-02-27 02:17:22 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case -3:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID);
|
2015-02-27 02:17:22 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case -4:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED);
|
2015-02-27 02:17:22 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case -5:
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ);
|
2015-02-27 02:17:22 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
|
2015-03-14 03:29:34 +08:00
|
|
|
TOX_ERR_FRIEND_CUSTOM_PACKET *error)
|
2015-02-27 02:17:22 +08:00
|
|
|
{
|
|
|
|
if (!data) {
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_NULL);
|
2015-02-27 02:17:22 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = tox;
|
|
|
|
|
|
|
|
if (length == 0) {
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY);
|
2015-02-27 02:17:22 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data[0] < (PACKET_ID_LOSSY_RANGE_START + PACKET_LOSSY_AV_RESERVED)) {
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID);
|
2015-02-27 02:17:22 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ret = send_custom_lossy_packet(m, friend_number, data, length);
|
|
|
|
|
|
|
|
set_custom_packet_error(ret, error);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
custom_lossy_packet_registerhandler(m, function, user_data);
|
|
|
|
}
|
|
|
|
|
2015-03-01 05:26:19 +08:00
|
|
|
bool tox_friend_send_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
|
2015-03-14 03:29:34 +08:00
|
|
|
TOX_ERR_FRIEND_CUSTOM_PACKET *error)
|
2015-02-27 02:17:22 +08:00
|
|
|
{
|
|
|
|
if (!data) {
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_NULL);
|
2015-02-27 02:17:22 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Messenger *m = tox;
|
|
|
|
|
|
|
|
if (length == 0) {
|
2015-03-01 05:26:19 +08:00
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY);
|
2015-02-27 02:17:22 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ret = send_custom_lossless_packet(m, friend_number, data, length);
|
|
|
|
|
|
|
|
set_custom_packet_error(ret, error);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb *function, void *user_data)
|
|
|
|
{
|
|
|
|
Messenger *m = tox;
|
|
|
|
custom_lossless_packet_registerhandler(m, function, user_data);
|
|
|
|
}
|
2015-03-11 06:54:01 +08:00
|
|
|
|
2015-03-12 06:26:25 +08:00
|
|
|
void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id)
|
2015-03-11 20:09:45 +08:00
|
|
|
{
|
|
|
|
if (dht_id) {
|
|
|
|
const Messenger *m = tox;
|
|
|
|
memcpy(dht_id , m->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-12 06:26:25 +08:00
|
|
|
uint16_t tox_self_get_udp_port(const Tox *tox, TOX_ERR_GET_PORT *error)
|
2015-03-11 20:09:45 +08:00
|
|
|
{
|
|
|
|
const Messenger *m = tox;
|
|
|
|
uint16_t port = htons(m->net->port);
|
|
|
|
|
|
|
|
if (port) {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK);
|
|
|
|
} else {
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_NOT_BOUND);
|
|
|
|
}
|
|
|
|
|
|
|
|
return port;
|
|
|
|
}
|
|
|
|
|
2015-03-12 06:26:25 +08:00
|
|
|
uint16_t tox_self_get_tcp_port(const Tox *tox, TOX_ERR_GET_PORT *error)
|
2015-03-11 20:09:45 +08:00
|
|
|
{
|
|
|
|
/* TCP server not yet implemented in clients. */
|
|
|
|
SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_NOT_BOUND);
|
|
|
|
return 0;
|
|
|
|
}
|
2015-03-11 06:54:01 +08:00
|
|
|
|
2015-03-12 01:51:11 +08:00
|
|
|
#include "tox_old_code.h"
|