Merge pull request #609 from FullName/wait

Add tox_wait() for socket, allow tox.h include in tox.c
This commit is contained in:
irungentoo 2013-10-07 14:13:07 -07:00
commit 3658c372a4
10 changed files with 314 additions and 86 deletions

View File

@ -253,7 +253,7 @@ START_TEST(test_dht_state_saveloadsave)
char msg[128];
size_t offset = res >> 4;
uint8_t *ptr = buffer + extra + offset;
sprintf(msg, "Failed to load back stored buffer: 0x%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx @%u/%u, code %d",
sprintf(msg, "Failed to load back stored buffer: 0x%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx @%zu/%zu, code %d",
ptr[-2], ptr[-1], ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], offset, size, res & 0x0F);
ck_assert_msg(res == 0, msg);
}
@ -295,7 +295,7 @@ START_TEST(test_messenger_state_saveloadsave)
char msg[128];
size_t offset = res >> 4;
uint8_t *ptr = buffer + extra + offset;
sprintf(msg, "Failed to load back stored buffer: 0x%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx @%u/%u, code %d",
sprintf(msg, "Failed to load back stored buffer: 0x%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx @%zu/%zu, code %d",
ptr[-2], ptr[-1], ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], offset, size, res & 0x0F);
ck_assert_msg(res == 0, msg);
}

View File

@ -464,6 +464,20 @@ uint32_t sendqueue(Lossless_UDP *ludp, int connection_id)
return connection->sendbuff_packetnum - connection->successful_sent;
}
/* return number of packets in all queues waiting to be successfully sent. */
uint32_t sendqueue_total(Lossless_UDP *ludp)
{
uint32_t total = 0;
int i;
for(i = 0; i < ludp->connections.len; i++) {
Connection *connection = &tox_array_get(&ludp->connections, i, Connection);
if (connection->status != 0)
total += connection->sendbuff_packetnum - connection->successful_sent;
}
return total;
}
/* return the number of packets in the queue waiting to be successfully read with read_packet(...). */
uint32_t recvqueue(Lossless_UDP *ludp, int connection_id)
{

View File

@ -236,6 +236,9 @@ int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t
/* return number of packets in the queue waiting to be successfully sent. */
uint32_t sendqueue(Lossless_UDP *ludp, int connection_id);
/* return number of packets in all queues waiting to be successfully sent. */
uint32_t sendqueue_total(Lossless_UDP *ludp);
/*
* return number of packets in the queue waiting to be successfully
* read with read_packet(...).

View File

@ -26,6 +26,7 @@
#endif
#include "Messenger.h"
#include "network.h"
#include "util.h"
#define MIN(a,b) (((a)<(b))?(a):(b))
@ -1755,6 +1756,24 @@ void doMessenger(Messenger *m)
#endif
}
/*
* functions to avoid excessive polling
*/
int waitprepareMessenger(Messenger *m, uint8_t *data, uint16_t *lenptr)
{
return networking_wait_prepare(m->net, sendqueue_total(m->net_crypto->lossless_udp), data, lenptr);
}
int waitexecuteMessenger(Messenger *m, uint8_t *data, uint16_t len, uint16_t milliseconds)
{
return networking_wait_execute(data, len, milliseconds);
};
void waitcleanupMessenger(Messenger *m, uint8_t *data, uint16_t len)
{
networking_wait_cleanup(m->net, data, len);
}
/* return size of the messenger data (for saving) */
uint32_t Messenger_size_old(Messenger *m)
{

View File

@ -557,6 +557,13 @@ void cleanupMessenger(Messenger *M);
/* The main loop that needs to be run at least 20 times per second. */
void doMessenger(Messenger *m);
/*
* functions to avoid excessive polling
*/
int waitprepareMessenger(Messenger *m, uint8_t *data, uint16_t *lenptr);
int waitexecuteMessenger(Messenger *m, uint8_t *data, uint16_t len, uint16_t milliseconds);
void waitcleanupMessenger(Messenger *m, uint8_t *data, uint16_t len);
/* SAVING AND LOADING FUNCTIONS: */
/* return size of the messenger data (for saving). */
@ -589,3 +596,4 @@ uint32_t copy_friendlist(Messenger *m, int *out_list, uint32_t list_size);
int get_friendlist(Messenger *m, int **out_list, uint32_t *out_list_length);
#endif

View File

@ -25,6 +25,10 @@
#include "config.h"
#endif
#ifndef WIN32
#include <errno.h>
#endif
#include "network.h"
#include "util.h"
@ -205,6 +209,12 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
#ifdef LOGGING
loglogdata("O=>", data, length, &ip_port, res);
#endif
if (res == length)
net->send_fail_eagain = 0;
else if ((res < 0) && (errno == EAGAIN))
net->send_fail_eagain = current_time();
return res;
}
@ -299,6 +309,100 @@ void networking_poll(Networking_Core *net)
}
}
/*
* function to avoid excessive polling
*/
typedef struct
{
sock_t sock;
uint32_t sendqueue_length;
uint16_t send_fail_reset;
uint64_t send_fail_eagain;
} select_info;
int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr)
{
if ((data == NULL) || (*lenptr < sizeof(select_info)))
{
*lenptr = sizeof(select_info);
return 0;
}
*lenptr = sizeof(select_info);
select_info *s = (select_info *)data;
s->sock = net->sock;
s->sendqueue_length = sendqueue_length;
s->send_fail_reset = 0;
s->send_fail_eagain = net->send_fail_eagain;
return 1;
}
int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds)
{
/* WIN32: supported since Win2K, but might need some adjustements */
/* UNIX: this should work for any remotely Unix'ish system */
select_info *s = (select_info *)data;
/* add only if we had a failed write */
int writefds_add = 0;
if (s->send_fail_eagain != 0)
{
// current_time(): microseconds
uint64_t now = current_time();
/* s->sendqueue_length: might be used to guess how long we keep checking */
/* for now, threshold is hardcoded to 500ms, too long for a really really
* fast link, but too short for a sloooooow link... */
if (now - s->send_fail_eagain < 500000)
writefds_add = 1;
}
int nfds = 1 + s->sock;
/* the FD_ZERO calls might be superfluous */
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(s->sock, &readfds);
fd_set writefds;
FD_ZERO(&writefds);
if (writefds_add)
FD_SET(s->sock, &writefds);
fd_set exceptfds;
FD_ZERO(&exceptfds);
FD_SET(s->sock, &exceptfds);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = milliseconds * 1000;
#ifdef LOGGING
errno = 0;
#endif
/* returns -1 on error, 0 on timeout, the socket on activity */
int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
#ifdef LOGGING
sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno,
strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds),
FD_ISSET(s->sock, &exceptfds));
loglog(logbuffer);
#endif
if (FD_ISSET(s->sock, &writefds))
s->send_fail_reset = 1;
return res > 0 ? 1 : 0;
};
void networking_wait_cleanup(Networking_Core *net, uint8_t *data, uint16_t len)
{
select_info *s = (select_info *)data;
if (s->send_fail_reset)
net->send_fail_eagain = 0;
}
uint8_t at_startup_ran = 0;
static int at_startup(void)
@ -448,6 +552,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
{
char ipv6only = 0;
#ifdef LOGGING
errno = 0;
int res =
#endif
setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only));
@ -471,6 +576,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01;
mreq.ipv6mr_interface = 0;
#ifdef LOGGING
errno = 0;
res =
#endif
setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
@ -920,26 +1026,27 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
};
#ifdef LOGGING
static char errmsg_ok[3] = "OK";
static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res)
{
uint16_t port = ntohs(ip_port->port);
uint32_t data[2];
data[0] = buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0;
data[1] = buflen > 7 ? ntohl(*(uint32_t *)&buffer[5]) : 0;
if (res < 0)
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n",
buffer[0], message, buflen < 999 ? buflen : 999, 'E',
ip_ntoa(&ip_port->ip), ntohs(ip_port->port), errno,
strerror(errno), buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
{
int written = snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x\n",
buffer[0], message, (buflen < 999 ? (uint16_t)buflen : 999), 'E',
ip_ntoa(&ip_port->ip), port, errno, strerror(errno), data[0], data[1]);
}
else if ((res > 0) && ((size_t)res <= buflen))
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x\n",
buffer[0], message, res < 999 ? res : 999, (size_t)res < buflen ? '<' : '=',
ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0,
"OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3zu%c %s:%hu (%u: %s) | %04x%04x\n",
buffer[0], message, (res < 999 ? (size_t)res : 999), ((size_t)res < buflen ? '<' : '='),
ip_ntoa(&ip_port->ip), port, 0, errmsg_ok, data[0], data[1]);
else /* empty or overwrite */
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %u%c%u %s:%u (%u: %s) | %04x%04x\n",
buffer[0], message, res, !res ? '!' : '>', buflen,
ip_ntoa(&ip_port->ip), ntohs(ip_port->port), 0,
"OK", buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0,
buflen > 7 ? ntohl(*(uint32_t *)(&buffer[5])) : 0);
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %zu%c%zu %s:%hu (%u: %s) | %04x%04x\n",
buffer[0], message, (size_t)res, (!res ? '!' : '>'), buflen,
ip_ntoa(&ip_port->ip), port, 0, errmsg_ok, data[0], data[1]);
logbuffer[sizeof(logbuffer) - 1] = 0;
loglog(logbuffer);

View File

@ -244,6 +244,7 @@ typedef struct {
sa_family_t family;
uint16_t port;
sock_t sock;
uint64_t send_fail_eagain;
} Networking_Core;
/* return current time in milleseconds since the epoch. */
@ -264,6 +265,13 @@ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handl
/* Call this several times a second. */
void networking_poll(Networking_Core *net);
/*
* functions to avoid excessive polling
*/
int networking_wait_prepare(Networking_Core *net, uint32_t sendqueue_length, uint8_t *data, uint16_t *lenptr);
int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds);
void networking_wait_cleanup(Networking_Core *net, uint8_t *data, uint16_t len);
/* Initialize networking.
* bind to ip and port.
* ip must be in network order EX: 127.0.0.1 = (7F000001).

View File

@ -26,12 +26,18 @@
#endif
#include "Messenger.h"
#define __TOX_DEFINED__
typedef struct Messenger Tox;
#include "tox.h"
/*
* returns a FRIEND_ADDRESS_SIZE byte address to give to others.
* Format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
*
*/
void tox_getaddress(void *tox, uint8_t *address)
void tox_getaddress(Tox *tox, uint8_t *address)
{
Messenger *m = tox;
getaddress(m, address);
@ -54,7 +60,7 @@ void tox_getaddress(void *tox, uint8_t *address)
* (the nospam for that friend was set to the new one).
* return FAERR_NOMEM if increasing the friend list size fails.
*/
int tox_addfriend(void *tox, uint8_t *address, uint8_t *data, uint16_t length)
int tox_addfriend(Tox *tox, uint8_t *address, uint8_t *data, uint16_t length)
{
Messenger *m = tox;
return m_addfriend(m, address, data, length);
@ -65,7 +71,7 @@ int tox_addfriend(void *tox, uint8_t *address, uint8_t *data, uint16_t length)
* return the friend number if success.
* return -1 if failure.
*/
int tox_addfriend_norequest(void *tox, uint8_t *client_id)
int tox_addfriend_norequest(Tox *tox, uint8_t *client_id)
{
Messenger *m = tox;
return m_addfriend_norequest(m, client_id);
@ -74,7 +80,7 @@ int tox_addfriend_norequest(void *tox, uint8_t *client_id)
/* return the friend id associated to that client id.
* return -1 if no such friend.
*/
int tox_getfriend_id(void *tox, uint8_t *client_id)
int tox_getfriend_id(Tox *tox, uint8_t *client_id)
{
Messenger *m = tox;
return getfriend_id(m, client_id);
@ -86,14 +92,14 @@ int tox_getfriend_id(void *tox, uint8_t *client_id)
* return 0 if success.
* return -1 if failure.
*/
int tox_getclient_id(void *tox, int friend_id, uint8_t *client_id)
int tox_getclient_id(Tox *tox, int friend_id, uint8_t *client_id)
{
Messenger *m = tox;
return getclient_id(m, friend_id, client_id);
}
/* Remove a friend. */
int tox_delfriend(void *tox, int friendnumber)
int tox_delfriend(Tox *tox, int friendnumber)
{
Messenger *m = tox;
return m_delfriend(m, friendnumber);
@ -105,7 +111,7 @@ int tox_delfriend(void *tox, int friendnumber)
* return 0 if friend is not connected to us (Offline).
* return -1 on failure.
*/
int tox_get_friend_connectionstatus(void *tox, int friendnumber)
int tox_get_friend_connectionstatus(Tox *tox, int friendnumber)
{
Messenger *m = tox;
return m_get_friend_connectionstatus(m, friendnumber);
@ -116,7 +122,7 @@ int tox_get_friend_connectionstatus(void *tox, int friendnumber)
* return 1 if friend exists.
* return 0 if friend doesn't exist.
*/
int tox_friend_exists(void *tox, int friendnumber)
int tox_friend_exists(Tox *tox, int friendnumber)
{
Messenger *m = tox;
return m_friend_exists(m, friendnumber);
@ -131,13 +137,13 @@ int tox_friend_exists(void *tox, int friendnumber)
* m_sendmessage_withid will send a message with the id of your choosing,
* however we can generate an id for you by calling plain m_sendmessage.
*/
uint32_t tox_sendmessage(void *tox, int friendnumber, uint8_t *message, uint32_t length)
uint32_t tox_sendmessage(Tox *tox, int friendnumber, uint8_t *message, uint32_t length)
{
Messenger *m = tox;
return m_sendmessage(m, friendnumber, message, length);
}
uint32_t tox_sendmessage_withid(void *tox, int friendnumber, uint32_t theid, uint8_t *message, uint32_t length)
uint32_t tox_sendmessage_withid(Tox *tox, int friendnumber, uint32_t theid, uint8_t *message, uint32_t length)
{
Messenger *m = tox;
return m_sendmessage_withid(m, friendnumber, theid, message, length);
@ -147,7 +153,7 @@ uint32_t tox_sendmessage_withid(void *tox, int friendnumber, uint32_t theid, uin
* return 1 if packet was successfully put into the send queue.
* return 0 if it was not.
*/
int tox_sendaction(void *tox, int friendnumber, uint8_t *action, uint32_t length)
int tox_sendaction(Tox *tox, int friendnumber, uint8_t *action, uint32_t length)
{
Messenger *m = tox;
return m_sendaction(m, friendnumber, action, length);
@ -161,7 +167,7 @@ int tox_sendaction(void *tox, int friendnumber, uint8_t *action, uint32_t length
* return 0 if success.
* return -1 if failure.
*/
int tox_setfriendname(void *tox, int friendnumber, uint8_t *name, uint16_t length)
int tox_setfriendname(Tox *tox, int friendnumber, uint8_t *name, uint16_t length)
{
Messenger *m = tox;
return setfriendname(m, friendnumber, name, length);
@ -175,7 +181,7 @@ int tox_setfriendname(void *tox, int friendnumber, uint8_t *name, uint16_t lengt
* return 0 if success.
* return -1 if failure.
*/
int tox_setname(void *tox, uint8_t *name, uint16_t length)
int tox_setname(Tox *tox, uint8_t *name, uint16_t length)
{
Messenger *m = tox;
return setname(m, name, length);
@ -189,7 +195,7 @@ int tox_setname(void *tox, uint8_t *name, uint16_t length)
* return length of the name.
* return 0 on error.
*/
uint16_t tox_getselfname(void *tox, uint8_t *name, uint16_t nlen)
uint16_t tox_getselfname(Tox *tox, uint8_t *name, uint16_t nlen)
{
Messenger *m = tox;
return getself_name(m, name, nlen);
@ -201,7 +207,7 @@ uint16_t tox_getselfname(void *tox, uint8_t *name, uint16_t nlen)
* return length of name (with the NULL terminator) if success.
* return -1 if failure.
*/
int tox_getname(void *tox, int friendnumber, uint8_t *name)
int tox_getname(Tox *tox, int friendnumber, uint8_t *name)
{
Messenger *m = tox;
return getname(m, friendnumber, name);
@ -212,22 +218,22 @@ int tox_getname(void *tox, int friendnumber, uint8_t *name)
*
* return 0 on success, -1 on failure.
*/
int tox_set_statusmessage(void *tox, uint8_t *status, uint16_t length)
int tox_set_statusmessage(Tox *tox, uint8_t *status, uint16_t length)
{
Messenger *m = tox;
return m_set_statusmessage(m, status, length);
}
int tox_set_userstatus(void *tox, USERSTATUS status)
int tox_set_userstatus(Tox *tox, TOX_USERSTATUS status)
{
Messenger *m = tox;
return m_set_userstatus(m, status);
return m_set_userstatus(m, (USERSTATUS)status);
}
/* return the length of friendnumber's status message, including null.
* Pass it into malloc.
*/
int tox_get_statusmessage_size(void *tox, int friendnumber)
int tox_get_statusmessage_size(Tox *tox, int friendnumber)
{
Messenger *m = tox;
return m_get_statusmessage_size(m, friendnumber);
@ -237,13 +243,13 @@ int tox_get_statusmessage_size(void *tox, int friendnumber)
* Get the size you need to allocate from m_get_statusmessage_size.
* The self variant will copy our own status message.
*/
int tox_copy_statusmessage(void *tox, int friendnumber, uint8_t *buf, uint32_t maxlen)
int tox_copy_statusmessage(Tox *tox, int friendnumber, uint8_t *buf, uint32_t maxlen)
{
Messenger *m = tox;
return m_copy_statusmessage(m, friendnumber, buf, maxlen);
}
int tox_copy_self_statusmessage(void *tox, uint8_t *buf, uint32_t maxlen)
int tox_copy_self_statusmessage(Tox *tox, uint8_t *buf, uint32_t maxlen)
{
Messenger *m = tox;
return m_copy_self_statusmessage(m, buf, maxlen);
@ -254,23 +260,23 @@ int tox_copy_self_statusmessage(void *tox, uint8_t *buf, uint32_t maxlen)
* As above, the self variant will return our own USERSTATUS.
* If friendnumber is invalid, this shall return USERSTATUS_INVALID.
*/
USERSTATUS tox_get_userstatus(void *tox, int friendnumber)
TOX_USERSTATUS tox_get_userstatus(Tox *tox, int friendnumber)
{
Messenger *m = tox;
return m_get_userstatus(m, friendnumber);
return (TOX_USERSTATUS)m_get_userstatus(m, friendnumber);
}
USERSTATUS tox_get_selfuserstatus(void *tox)
TOX_USERSTATUS tox_get_selfuserstatus(Tox *tox)
{
Messenger *m = tox;
return m_get_self_userstatus(m);
return (TOX_USERSTATUS)m_get_self_userstatus(m);
}
/* Sets whether we send read receipts for friendnumber.
* This function is not lazy, and it will fail if yesno is not (0 or 1).
*/
void tox_set_sends_receipts(void *tox, int friendnumber, int yesno)
void tox_set_sends_receipts(Tox *tox, int friendnumber, int yesno)
{
Messenger *m = tox;
m_set_sends_receipts(m, friendnumber, yesno);
@ -279,7 +285,7 @@ void tox_set_sends_receipts(void *tox, int friendnumber, int yesno)
/* Return the number of friends in the instance m.
* You should use this to determine how much memory to allocate
* for copy_friendlist. */
uint32_t tox_count_friendlist(void *tox)
uint32_t tox_count_friendlist(Tox *tox)
{
Messenger *m = tox;
return count_friendlist(m);
@ -290,7 +296,7 @@ uint32_t tox_count_friendlist(void *tox)
* Otherwise, returns the number of elements copied.
* If the array was too small, the contents
* of out_list will be truncated to list_size. */
uint32_t tox_copy_friendlist(void *tox, int *out_list, uint32_t list_size)
uint32_t tox_copy_friendlist(Tox *tox, int *out_list, uint32_t list_size)
{
Messenger *m = tox;
return copy_friendlist(m, out_list, list_size);
@ -299,7 +305,7 @@ uint32_t tox_copy_friendlist(void *tox, int *out_list, uint32_t list_size)
/* Set the function that will be executed when a friend request is received.
* Function format is function(uint8_t * public_key, uint8_t * data, uint16_t length)
*/
void tox_callback_friendrequest(void *tox, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
void tox_callback_friendrequest(Tox *tox, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
{
Messenger *m = tox;
m_callback_friendrequest(m, function, userdata);
@ -309,7 +315,7 @@ void tox_callback_friendrequest(void *tox, void (*function)(uint8_t *, uint8_t *
/* Set the function that will be executed when a message from a friend is received.
* Function format is: function(int friendnumber, uint8_t * message, uint32_t length)
*/
void tox_callback_friendmessage(void *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *),
void tox_callback_friendmessage(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *),
void *userdata)
{
Messenger *m = tox;
@ -319,7 +325,7 @@ void tox_callback_friendmessage(void *tox, void (*function)(Messenger *tox, int,
/* Set the function that will be executed when an action from a friend is received.
* function format is: function(int friendnumber, uint8_t * action, uint32_t length)
*/
void tox_callback_action(void *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *), void *userdata)
void tox_callback_action(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *), void *userdata)
{
Messenger *m = tox;
m_callback_action(m, function, userdata);
@ -329,7 +335,7 @@ void tox_callback_action(void *tox, void (*function)(Messenger *tox, int, uint8_
* function(int friendnumber, uint8_t *newname, uint16_t length)
* You are not responsible for freeing newname.
*/
void tox_callback_namechange(void *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *),
void tox_callback_namechange(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *),
void *userdata)
{
Messenger *m = tox;
@ -340,7 +346,7 @@ void tox_callback_namechange(void *tox, void (*function)(Messenger *tox, int, ui
* function(int friendnumber, uint8_t *newstatus, uint16_t length)
* You are not responsible for freeing newstatus.
*/
void tox_callback_statusmessage(void *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *),
void tox_callback_statusmessage(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *),
void *userdata)
{
Messenger *m = tox;
@ -350,9 +356,11 @@ void tox_callback_statusmessage(void *tox, void (*function)(Messenger *tox, int,
/* Set the callback for status type changes.
* function(int friendnumber, USERSTATUS kind)
*/
void tox_callback_userstatus(void *tox, void (*function)(Messenger *tox, int, USERSTATUS, void *), void *userdata)
void tox_callback_userstatus(Tox *tox, void (*_function)(Tox *tox, int, TOX_USERSTATUS, void *), void *userdata)
{
Messenger *m = tox;
typedef void (*function_type)(Messenger *, int, USERSTATUS, void *);
function_type function = (function_type)_function;
m_callback_userstatus(m, function, userdata);
}
@ -365,7 +373,7 @@ void tox_callback_userstatus(void *tox, void (*function)(Messenger *tox, int, US
* Since core doesn't track ids for you, receipt may not correspond to any message.
* in that case, you should discard it.
*/
void tox_callback_read_receipt(void *tox, void (*function)(Messenger *tox, int, uint32_t, void *), void *userdata)
void tox_callback_read_receipt(Tox *tox, void (*function)(Messenger *tox, int, uint32_t, void *), void *userdata)
{
Messenger *m = tox;
m_callback_read_receipt(m, function, userdata);
@ -382,7 +390,7 @@ void tox_callback_read_receipt(void *tox, void (*function)(Messenger *tox, int,
* being previously online" part. It's assumed that when adding friends,
* their connection status is offline.
*/
void tox_callback_connectionstatus(void *tox, void (*function)(Messenger *tox, int, uint8_t, void *), void *userdata)
void tox_callback_connectionstatus(Tox *tox, void (*function)(Messenger *tox, int, uint8_t, void *), void *userdata)
{
Messenger *m = tox;
m_callback_connectionstatus(m, function, userdata);
@ -394,7 +402,7 @@ void tox_callback_connectionstatus(void *tox, void (*function)(Messenger *tox, i
*
* Function(Tox *tox, int friendnumber, uint8_t *group_public_key, void *userdata)
*/
void tox_callback_group_invite(void *tox, void (*function)(Messenger *tox, int, uint8_t *, void *), void *userdata)
void tox_callback_group_invite(Tox *tox, void (*function)(Messenger *tox, int, uint8_t *, void *), void *userdata)
{
Messenger *m = tox;
m_callback_group_invite(m, function, userdata);
@ -403,7 +411,7 @@ void tox_callback_group_invite(void *tox, void (*function)(Messenger *tox, int,
*
* Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
*/
void tox_callback_group_message(void *tox, void (*function)(Messenger *tox, int, int, uint8_t *, uint16_t, void *),
void tox_callback_group_message(Tox *tox, void (*function)(Messenger *tox, int, int, uint8_t *, uint16_t, void *),
void *userdata)
{
Messenger *m = tox;
@ -414,7 +422,7 @@ void tox_callback_group_message(void *tox, void (*function)(Messenger *tox, int,
* return group number on success.
* return -1 on failure.
*/
int tox_add_groupchat(void *tox)
int tox_add_groupchat(Tox *tox)
{
Messenger *m = tox;
return add_groupchat(m);
@ -424,7 +432,7 @@ int tox_add_groupchat(void *tox)
* return 0 on success.
* return -1 if failure.
*/
int tox_del_groupchat(void *tox, int groupnumber)
int tox_del_groupchat(Tox *tox, int groupnumber)
{
Messenger *m = tox;
return del_groupchat(m, groupnumber);
@ -436,7 +444,7 @@ int tox_del_groupchat(void *tox, int groupnumber)
* return length of name if success
* return -1 if failure
*/
int tox_group_peername(void *tox, int groupnumber, int peernumber, uint8_t *name)
int tox_group_peername(Tox *tox, int groupnumber, int peernumber, uint8_t *name)
{
Messenger *m = tox;
return m_group_peername(m, groupnumber, peernumber, name);
@ -445,7 +453,7 @@ int tox_group_peername(void *tox, int groupnumber, int peernumber, uint8_t *name
* return 0 on success
* return -1 on failure
*/
int tox_invite_friend(void *tox, int friendnumber, int groupnumber)
int tox_invite_friend(Tox *tox, int friendnumber, int groupnumber)
{
Messenger *m = tox;
return invite_friend(m, friendnumber, groupnumber);
@ -455,7 +463,7 @@ int tox_invite_friend(void *tox, int friendnumber, int groupnumber)
* returns group number on success
* returns -1 on failure.
*/
int tox_join_groupchat(void *tox, int friendnumber, uint8_t *friend_group_public_key)
int tox_join_groupchat(Tox *tox, int friendnumber, uint8_t *friend_group_public_key)
{
Messenger *m = tox;
return join_groupchat(m, friendnumber, friend_group_public_key);
@ -465,7 +473,7 @@ int tox_join_groupchat(void *tox, int friendnumber, uint8_t *friend_group_public
* return 0 on success
* return -1 on failure
*/
int tox_group_message_send(void *tox, int groupnumber, uint8_t *message, uint32_t length)
int tox_group_message_send(Tox *tox, int groupnumber, uint8_t *message, uint32_t length)
{
Messenger *m = tox;
return group_message_send(m, groupnumber, message, length);
@ -480,7 +488,7 @@ int tox_group_message_send(void *tox, int groupnumber, uint8_t *message, uint32_
*
* Function(Tox *tox, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata)
*/
void tox_callback_file_sendrequest(void *tox, void (*function)(Messenger *tox, int, uint8_t, uint64_t, uint8_t *,
void tox_callback_file_sendrequest(Tox *tox, void (*function)(Messenger *tox, int, uint8_t, uint64_t, uint8_t *,
uint16_t,
void *), void *userdata)
{
@ -492,7 +500,7 @@ void tox_callback_file_sendrequest(void *tox, void (*function)(Messenger *tox, i
* Function(Tox *tox, int friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata)
*
*/
void tox_callback_file_control(void *tox, void (*function)(Messenger *tox, int, uint8_t, uint8_t, uint8_t, uint8_t *,
void tox_callback_file_control(Tox *tox, void (*function)(Messenger *tox, int, uint8_t, uint8_t, uint8_t, uint8_t *,
uint16_t, void *), void *userdata)
{
Messenger *m = tox;
@ -503,7 +511,7 @@ void tox_callback_file_control(void *tox, void (*function)(Messenger *tox, int,
* Function(Tox *tox, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata)
*
*/
void tox_callback_file_data(void *tox, void (*function)(Messenger *tox, int, uint8_t, uint8_t *, uint16_t length,
void tox_callback_file_data(Tox *tox, void (*function)(Messenger *tox, int, uint8_t, uint8_t *, uint16_t length,
void *),
void *userdata)
@ -516,7 +524,7 @@ void tox_callback_file_data(void *tox, void (*function)(Messenger *tox, int, uin
* return file number on success
* return -1 on failure
*/
int tox_new_filesender(void *tox, int friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length)
int tox_new_filesender(Tox *tox, int friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length)
{
Messenger *m = tox;
return new_filesender(m, friendnumber, filesize, filename, filename_length);
@ -527,7 +535,7 @@ int tox_new_filesender(void *tox, int friendnumber, uint64_t filesize, uint8_t *
* return 1 on success
* return 0 on failure
*/
int tox_file_sendcontrol(void *tox, int friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id,
int tox_file_sendcontrol(Tox *tox, int friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id,
uint8_t *data, uint16_t length)
{
Messenger *m = tox;
@ -538,7 +546,7 @@ int tox_file_sendcontrol(void *tox, int friendnumber, uint8_t send_receive, uint
* return 1 on success
* return 0 on failure
*/
int tox_file_senddata(void *tox, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length)
int tox_file_senddata(Tox *tox, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length)
{
Messenger *m = tox;
return file_data(m, friendnumber, filenumber, data, length);
@ -550,7 +558,7 @@ int tox_file_senddata(void *tox, int friendnumber, uint8_t filenumber, uint8_t *
* return number of bytes remaining to be sent/received on success
* return 0 on failure
*/
uint64_t tox_file_dataremaining(void *tox, int friendnumber, uint8_t filenumber, uint8_t send_receive)
uint64_t tox_file_dataremaining(Tox *tox, int friendnumber, uint8_t filenumber, uint8_t send_receive)
{
Messenger *m = tox;
return file_dataremaining(m, friendnumber, filenumber, send_receive);
@ -561,12 +569,15 @@ uint64_t tox_file_dataremaining(void *tox, int friendnumber, uint8_t filenumber,
/* Use these functions to bootstrap the client.
* Sends a get nodes request to the given node with ip port and public_key.
*/
void tox_bootstrap_from_ip(void *tox, IP_Port ip_port, uint8_t *public_key)
void tox_bootstrap_from_ip(Tox *tox, tox_IP_Port _ip_port, uint8_t *public_key)
{
Messenger *m = tox;
IP_Port ip_port;
memcpy(&ip_port, &_ip_port, sizeof(IP_Port));
DHT_bootstrap(m->dht, ip_port, public_key);
}
int tox_bootstrap_from_address(void *tox, const char *address,
int tox_bootstrap_from_address(Tox *tox, const char *address,
uint8_t ipv6enabled, uint16_t port, uint8_t *public_key)
{
Messenger *m = tox;
@ -576,7 +587,7 @@ int tox_bootstrap_from_address(void *tox, const char *address,
/* return 0 if we are not connected to the DHT.
* return 1 if we are.
*/
int tox_isconnected(void *tox)
int tox_isconnected(Tox *tox)
{
Messenger *m = tox;
return DHT_isconnected(m->dht);
@ -587,7 +598,7 @@ int tox_isconnected(void *tox)
* return allocated instance of tox on success.
* return 0 if there are problems.
*/
void *tox_new(uint8_t ipv6enabled)
Tox *tox_new(uint8_t ipv6enabled)
{
return initMessenger(ipv6enabled);
}
@ -595,37 +606,58 @@ void *tox_new(uint8_t ipv6enabled)
/* Run this before closing shop.
* Free all datastructures.
*/
void tox_kill(void *tox)
void tox_kill(Tox *tox)
{
Messenger *m = tox;
cleanupMessenger(m);
}
/* The main loop that needs to be run at least 20 times per second. */
void tox_do(void *tox)
void tox_do(Tox *tox)
{
Messenger *m = tox;
doMessenger(m);
}
/*
* functions to avoid excessive polling
*/
int tox_wait_prepare(Tox *tox, uint8_t *data, uint16_t *lenptr)
{
Messenger *m = tox;
return waitprepareMessenger(m, data, lenptr);
}
int tox_wait_execute(Tox *tox, uint8_t *data, uint16_t len, uint16_t milliseconds)
{
Messenger *m = tox;
return waitexecuteMessenger(m, data, len, milliseconds);
}
void tox_wait_cleanup(Tox *tox, uint8_t *data, uint16_t len)
{
Messenger *m = tox;
waitcleanupMessenger(m, data, len);
}
/* SAVING AND LOADING FUNCTIONS: */
/* return size of the messenger data (for saving). */
uint32_t tox_size(void *tox)
uint32_t tox_size(Tox *tox)
{
Messenger *m = tox;
return Messenger_size(m);
}
/* Save the messenger in data (must be allocated memory of size Messenger_size()). */
void tox_save(void *tox, uint8_t *data)
void tox_save(Tox *tox, uint8_t *data)
{
Messenger *m = tox;
Messenger_save(m, data);
}
/* Load the messenger from data of size length. */
int tox_load(void *tox, uint8_t *data, uint32_t length)
int tox_load(Tox *tox, uint8_t *data, uint32_t length)
{
Messenger *m = tox;
return Messenger_load(m, data, length);

View File

@ -140,7 +140,10 @@ typedef enum {
}
TOX_USERSTATUS;
typedef void Tox;
#ifndef __TOX_DEFINED__
#define __TOX_DEFINED__
typedef struct Tox Tox;
#endif
/* return FRIEND_ADDRESS_SIZE byte address to give to others.
* format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
@ -229,7 +232,7 @@ int tox_sendaction(Tox *tox, int friendnumber, uint8_t *action, uint32_t length)
* return 0 if success.
* return -1 if failure.
*/
int tox_setfriendname(void *tox, int friendnumber, uint8_t *name, uint16_t length);
int tox_setfriendname(Tox *tox, int friendnumber, uint8_t *name, uint16_t length);
/* Set our nickname.
* name must be a string of maximum MAX_NAME_LENGTH length.
@ -300,14 +303,14 @@ void tox_set_sends_receipts(Tox *tox, int friendnumber, int yesno);
/* Return the number of friends in the instance m.
* You should use this to determine how much memory to allocate
* for copy_friendlist. */
uint32_t tox_count_friendlist(void *tox);
uint32_t tox_count_friendlist(Tox *tox);
/* Copy a list of valid friend IDs into the array out_list.
* If out_list is NULL, returns 0.
* Otherwise, returns the number of elements copied.
* If the array was too small, the contents
* of out_list will be truncated to list_size. */
uint32_t tox_copy_friendlist(void *tox, int *out_list, uint32_t list_size);
uint32_t tox_copy_friendlist(Tox *tox, int *out_list, uint32_t list_size);
/* Set the function that will be executed when a friend request is received.
* Function format is function(uint8_t * public_key, uint8_t * data, uint16_t length)
@ -524,6 +527,7 @@ uint64_t tox_file_dataremaining(Tox *tox, int friendnumber, uint8_t filenumber,
* to setup connections
*/
void tox_bootstrap_from_ip(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key);
/* Resolves address into an IP address. If successful, sends a "get nodes"
* request to the given node with ip, port and public_key to setup connections
*
@ -565,6 +569,39 @@ void tox_kill(Tox *tox);
/* The main loop that needs to be run at least 20 times per second. */
void tox_do(Tox *tox);
/*
* tox_wait_prepare(): function should be called under lock
* Prepares the data required to call tox_wait_execute() asynchronously
*
* data[] is reserved and kept by the caller
* len is in/out: in = reserved data[], out = required data[]
*
* returns 1 on success
* returns 0 on failure (length is insufficient)
*
*
* tox_wait_execute(): function can be called asynchronously
* Waits for something to happen on the socket for up to milliseconds milliseconds.
* *** Function MUSTN'T poll. ***
* The function mustn't modify anything at all, so it can be called completely
* asynchronously without any worry.
*
* returns 1 if there is socket activity (i.e. tox_do() should be called)
* returns 0 if the timeout was reached
* returns -1 if data was NULL or len too short
*
*
* tox_wait_cleanup(): function should be called under lock
* Stores results from tox_wait_execute().
*
* data[]/len shall be the exact same as given to tox_wait_execute()
*
*/
int tox_wait_prepare(Tox *tox, uint8_t *data, uint16_t *lenptr);
int tox_wait_execute(Tox *tox, uint8_t *data, uint16_t len, uint16_t milliseconds);
void tox_wait_cleanup(Tox *tox, uint8_t *data, uint16_t len);
/* SAVING AND LOADING FUNCTIONS: */
/* return size of messenger data (for saving). */
@ -582,3 +619,4 @@ int tox_load(Tox *tox, uint8_t *data, uint32_t length);
#endif
#endif

View File

@ -118,7 +118,7 @@ void loginit(uint16_t port)
if (logbufferpredata) {
if (logfile)
fprintf(logfile, logbufferpredata);
fprintf(logfile, "%s", logbufferpredata);
free(logbufferpredata);
logbufferpredata = NULL;
@ -128,8 +128,7 @@ void loginit(uint16_t port)
void loglog(char *text)
{
if (logfile) {
fprintf(logfile, "%4u ", (uint32_t)(now() - starttime));
fprintf(logfile, text);
fprintf(logfile, "%4u %s", (uint32_t)(now() - starttime), text);
fflush(logfile);
return;
@ -158,8 +157,7 @@ void loglog(char *text)
logbufferprelen = lennew;
}
size_t written;
sprintf(logbufferprehead, "%4u %s%n", (uint32_t)(now() - starttime), text, &written);
int written = sprintf(logbufferprehead, "%4u %s", (uint32_t)(now() - starttime), text);
logbufferprehead += written;
}
@ -171,3 +169,4 @@ void logexit()
}
};
#endif