Merged normal message function and send action function into one

messaging function.

This removes code duplication and allows us to easily add new message
types to the api without having to add new functions.
pull/1294/head
irungentoo 2015-03-18 15:32:53 -04:00
parent b9e747fd50
commit d711362622
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
10 changed files with 86 additions and 169 deletions

View File

@ -50,10 +50,10 @@ START_TEST(test_m_sendmesage)
int bad_len = MAX_CRYPTO_PACKET_SIZE;
ck_assert(m_sendmessage(m, -1, (uint8_t *)message, good_len, 0) == -1);
ck_assert(m_sendmessage(m, REALLY_BIG_NUMBER, (uint8_t *)message, good_len, 0) == -1);
ck_assert(m_sendmessage(m, 17, (uint8_t *)message, good_len, 0) == -1);
ck_assert(m_sendmessage(m, friend_id_num, (uint8_t *)message, bad_len, 0) == -2);
ck_assert(m_send_message_generic(m, -1, MESSAGE_NORMAL, (uint8_t *)message, good_len, 0) == -1);
ck_assert(m_send_message_generic(m, REALLY_BIG_NUMBER, MESSAGE_NORMAL, (uint8_t *)message, good_len, 0) == -1);
ck_assert(m_send_message_generic(m, 17, MESSAGE_NORMAL, (uint8_t *)message, good_len, 0) == -1);
ck_assert(m_send_message_generic(m, friend_id_num, MESSAGE_NORMAL, (uint8_t *)message, bad_len, 0) == -2);
}
END_TEST

View File

@ -33,11 +33,16 @@ void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *dat
}
uint32_t messages_received;
void print_message(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata)
void print_message(Tox *m, uint32_t friendnumber, TOX_MESSAGE_TYPE type, const uint8_t *string, size_t length,
void *userdata)
{
if (*((uint32_t *)userdata) != 974536)
return;
if (type != TOX_MESSAGE_TYPE_MESSAGE) {
ck_abort_msg("Bad type");
}
uint8_t cmp_msg[TOX_MAX_MESSAGE_LENGTH];
memset(cmp_msg, 'G', sizeof(cmp_msg));
@ -395,9 +400,9 @@ START_TEST(test_few_clients)
uint8_t msgs[TOX_MAX_MESSAGE_LENGTH + 1];
memset(msgs, 'G', sizeof(msgs));
TOX_ERR_FRIEND_SEND_MESSAGE errm;
tox_friend_send_message(tox2, 0, msgs, TOX_MAX_MESSAGE_LENGTH + 1, &errm);
tox_friend_send_message(tox2, 0, TOX_MESSAGE_TYPE_MESSAGE, msgs, TOX_MAX_MESSAGE_LENGTH + 1, &errm);
ck_assert_msg(errm == TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG, "TOX_MAX_MESSAGE_LENGTH is too small\n");
tox_friend_send_message(tox2, 0, msgs, TOX_MAX_MESSAGE_LENGTH, &errm);
tox_friend_send_message(tox2, 0, TOX_MESSAGE_TYPE_MESSAGE, msgs, TOX_MAX_MESSAGE_LENGTH, &errm);
ck_assert_msg(errm == TOX_ERR_FRIEND_SEND_MESSAGE_OK, "TOX_MAX_MESSAGE_LENGTH is too big\n");
while (1) {

View File

@ -56,10 +56,11 @@
#endif
void print_message(Messenger *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata)
void print_message(Messenger *m, uint32_t friendnumber, unsigned int type, const uint8_t *string, size_t length,
void *userdata)
{
printf("Message with length %lu received from %u: %s \n", length, friendnumber, string);
m_sendmessage(m, friendnumber, (uint8_t *)"Test1", 6, 0);
m_send_message_generic(m, friendnumber, type, (uint8_t *)"Test1", 6, 0);
}
/* FIXME needed as print_request has to match the interface expected by
@ -184,7 +185,7 @@ int main(int argc, char *argv[])
getname(m, num, name);
printf("%s\n", name);
m_sendmessage(m, num, (uint8_t *)"Test", 5, 0);
m_send_message_generic(m, num, MESSAGE_NORMAL, (uint8_t *)"Test", 5, 0);
do_messenger(m);
c_sleep(30);
FILE *file = fopen("Save.bak", "wb");

View File

@ -89,7 +89,8 @@ static void callback_group_invite(Tox *tox, int fid, uint8_t type, const uint8_t
current_group = tox_join_groupchat(tox, fid, data, length);
}
void callback_friend_message(Tox *tox, uint32_t fid, const uint8_t *message, size_t length, void *userdata)
void callback_friend_message(Tox *tox, uint32_t fid, TOX_MESSAGE_TYPE type, const uint8_t *message, size_t length,
void *userdata)
{
if (length == 1 && *message == 'c') {
if (tox_del_groupchat(tox, current_group) == 0)

View File

@ -395,7 +395,7 @@ void line_eval(Tox *m, char *line)
int num = strtoul(line + prompt_offset, posi, 0);
if (**posi != 0) {
if (tox_friend_send_message(m, num, (uint8_t *) *posi + 1, strlen(*posi + 1), NULL) < 1) {
if (tox_friend_send_message(m, num, TOX_MESSAGE_TYPE_MESSAGE, (uint8_t *) *posi + 1, strlen(*posi + 1), NULL) < 1) {
char sss[256];
sprintf(sss, "[i] could not send message to friend num %u", num);
new_lines(sss);
@ -607,7 +607,7 @@ void line_eval(Tox *m, char *line)
if (conversation_default != 0) {
if (conversation_default > 0) {
int friendnumber = conversation_default - 1;
uint32_t res = tox_friend_send_message(m, friendnumber, (uint8_t *)line, strlen(line), NULL);
uint32_t res = tox_friend_send_message(m, friendnumber, TOX_MESSAGE_TYPE_MESSAGE, (uint8_t *)line, strlen(line), NULL);
if (res == 0) {
char sss[128];
@ -881,7 +881,8 @@ void print_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_
do_refresh();
}
void print_message(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata)
void print_message(Tox *m, uint32_t friendnumber, TOX_MESSAGE_TYPE type, const uint8_t *string, size_t length,
void *userdata)
{
/* ensure null termination */
uint8_t null_string[length + 1];
@ -1204,7 +1205,7 @@ void print_online(Tox *tox, uint32_t friendnumber, TOX_CONNECTION status, void *
unsigned int i;
for (i = 0; i < NUM_FILE_SENDERS; ++i)
if (file_senders[i].file != 0 && file_senders[i].friendnum == friend_number) {
if (file_senders[i].file != 0 && file_senders[i].friendnum == friendnumber) {
fclose(file_senders[i].file);
file_senders[i].file = 0;
}
@ -1290,7 +1291,7 @@ int main(int argc, char *argv[])
tox_callback_file_recv(m, file_request_accept, NULL);
tox_callback_file_request_chunk(m, tox_file_request_chunk, NULL);
tox_callback_group_namelist_change(m, print_groupnamelistchange, NULL);
tox_callback_friend_connection_status(tox, print_online, NULL);
tox_callback_friend_connection_status(m, print_online, NULL);
initscr();
noecho();

View File

@ -53,7 +53,8 @@ void print_online(Tox *tox, uint32_t friendnumber, TOX_CONNECTION status, void *
printf("\nOther went offline.\n");
}
void print_message(Tox *tox, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata)
void print_message(Tox *tox, uint32_t friendnumber, TOX_MESSAGE_TYPE type, const uint8_t *string, size_t length,
void *userdata)
{
int master = *((int *)userdata);
write(master, string, length);
@ -148,7 +149,7 @@ int main(int argc, char *argv[])
if (ret <= 0)
break;
tox_friend_send_message(tox, num, buf, ret, 0);
tox_friend_send_message(tox, num, TOX_MESSAGE_TYPE_MESSAGE, buf, ret, 0);
}
tox_iterate(tox);

View File

@ -455,17 +455,21 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber)
return 1;
}
/* Send a packet_id message.
/* Send a message of type.
*
* return -1 if friend not valid.
* return -2 if too large.
* return -3 if friend not online.
* return -4 if send failed (because queue is full).
* return -5 if bad type.
* return 0 if success.
*/
static int send_message_generic(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length,
uint8_t packet_id, uint32_t *message_id)
int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, const uint8_t *message, uint32_t length,
uint32_t *message_id)
{
if (type > MESSAGE_ACTION)
return -5;
if (friend_not_valid(m, friendnumber))
return -1;
@ -476,7 +480,7 @@ static int send_message_generic(Messenger *m, int32_t friendnumber, const uint8_
return -3;
uint8_t packet[length + 1];
packet[0] = packet_id;
packet[0] = type + PACKET_ID_MESSAGE;
if (length != 0)
memcpy(packet + 1, message, length);
@ -501,16 +505,6 @@ static int send_message_generic(Messenger *m, int32_t friendnumber, const uint8_
return 0;
}
int m_sendmessage(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length, uint32_t *message_id)
{
return send_message_generic(m, friendnumber, message, length, PACKET_ID_MESSAGE, message_id);
}
int m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length, uint32_t *message_id)
{
return send_message_generic(m, friendnumber, action, length, PACKET_ID_ACTION, message_id);
}
/* Send a name packet to friendnumber.
* length is the length with the NULL terminator.
*/
@ -812,20 +806,13 @@ void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const
}
/* Set the function that will be executed when a message from a friend is received. */
void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, size_t, void *),
void *userdata)
void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, const uint8_t *,
size_t, void *), void *userdata)
{
m->friend_message = function;
m->friend_message_userdata = userdata;
}
void m_callback_action(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, size_t, void *),
void *userdata)
{
m->friend_action = function;
m->friend_action_userdata = userdata;
}
void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, size_t, void *),
void *userdata)
{
@ -2012,7 +1999,8 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
break;
}
case PACKET_ID_MESSAGE: {
case PACKET_ID_MESSAGE:
case PACKET_ID_ACTION: {
const uint8_t *message_id = data;
if (data_length == 0)
@ -2025,30 +2013,10 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
uint8_t message_terminated[message_length + 1];
memcpy(message_terminated, message, message_length);
message_terminated[message_length] = 0;
uint8_t type = packet_id - PACKET_ID_MESSAGE;
if (m->friend_message)
(*m->friend_message)(m, i, message_terminated, message_length, m->friend_message_userdata);
break;
}
case PACKET_ID_ACTION: {
const uint8_t *message_id = data;
if (data_length == 0)
break;
const uint8_t *action = data;
uint16_t action_length = data_length;
/* Make sure the NULL terminator is present. */
uint8_t action_terminated[action_length + 1];
memcpy(action_terminated, action, action_length);
action_terminated[action_length] = 0;
if (m->friend_action)
(*m->friend_action)(m, i, action_terminated, action_length, m->friend_action_userdata);
(*m->friend_message)(m, i, type, message_terminated, message_length, m->friend_message_userdata);
break;
}

View File

@ -37,6 +37,11 @@
#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))
enum {
MESSAGE_NORMAL,
MESSAGE_ACTION
};
/* NOTE: Packet ids below 17 must never be used. */
#define PACKET_ID_SHARE_RELAYS 17
#define PACKET_ID_ONLINE 24
@ -46,7 +51,7 @@
#define PACKET_ID_USERSTATUS 50
#define PACKET_ID_TYPING 51
#define PACKET_ID_MESSAGE 64
#define PACKET_ID_ACTION 65
#define PACKET_ID_ACTION (PACKET_ID_MESSAGE + MESSAGE_ACTION) /* 65 */
#define PACKET_ID_MSI 69
#define PACKET_ID_FILE_SENDREQUEST 80
#define PACKET_ID_FILE_CONTROL 81
@ -101,6 +106,7 @@ enum {
FAERR_NOMEM = -8
};
/* Default start timeout in seconds between friend requests. */
#define FRIENDREQUEST_TIMEOUT 5;
@ -241,10 +247,8 @@ struct Messenger {
uint8_t has_added_relays; // If the first connection has occurred in do_messenger
Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config
void (*friend_message)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *);
void (*friend_message)(struct Messenger *m, uint32_t, unsigned int, const uint8_t *, size_t, void *);
void *friend_message_userdata;
void (*friend_action)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *);
void *friend_action_userdata;
void (*friend_namechange)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *);
void *friend_namechange_userdata;
void (*friend_statusmessagechange)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *);
@ -363,29 +367,20 @@ int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber);
*/
int m_friend_exists(const Messenger *m, int32_t friendnumber);
/* Send a text chat message to an online friend.
/* Send a message of type to an online friend.
*
* return -1 if friend not valid.
* return -2 if too large.
* return -3 if friend not online.
* return -4 if send failed (because queue is full).
* return -5 if bad type.
* return 0 if success.
*
* the value in message_id will be passed to your read_receipt callback when the other receives the message.
*/
int m_sendmessage(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length, uint32_t *message_id);
int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, const uint8_t *message, uint32_t length,
uint32_t *message_id);
/* Send an action to an online friend.
*
* return -1 if friend not valid.
* return -2 if too large.
* return -3 if friend not online.
* return -4 if send failed (because queue is full).
* return 0 if success.
*
* the value in message_id will be passed to your read_receipt callback when the other receives the message.
*/
int m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length, uint32_t *message_id);
/* Set the name and name_length of a friend.
* name must be a string of maximum MAX_NAME_LENGTH length.
@ -492,16 +487,10 @@ void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const
void *), void *userdata);
/* Set the function that will be executed when a message from a friend is received.
* Function format is: function(uint32_t friendnumber, uint8_t * message, uint32_t length)
* Function format is: function(uint32_t friendnumber, unsigned int type, uint8_t * message, uint32_t length)
*/
void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, size_t, void *),
void *userdata);
/* Set the function that will be executed when an action from a friend is received.
* Function format is: function(uint32_t friendnumber, uint8_t * action, uint32_t length)
*/
void m_callback_action(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, size_t, void *),
void *userdata);
void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, const uint8_t *,
size_t, void *), void *userdata);
/* Set the callback for name changes.
* Function(uint32_t friendnumber, uint8_t *newname, size_t length)

View File

@ -791,11 +791,15 @@ static void set_message_error(int ret, TOX_ERR_FRIEND_SEND_MESSAGE *error)
case -4:
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ);
break;
case -5:
/* can't happen */
break;
}
}
uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length,
TOX_ERR_FRIEND_SEND_MESSAGE *error)
uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
size_t length, TOX_ERR_FRIEND_SEND_MESSAGE *error)
{
if (!message) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_NULL);
@ -809,26 +813,7 @@ uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, const uint8_t
Messenger *m = tox;
uint32_t message_id = 0;
set_message_error(m_sendmessage(m, friend_number, message, length, &message_id), error);
return message_id;
}
uint32_t tox_friend_send_action(Tox *tox, uint32_t friend_number, const uint8_t *action, size_t length,
TOX_ERR_FRIEND_SEND_MESSAGE *error)
{
if (!action) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_NULL);
return 0;
}
if (!length) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY);
return 0;
}
Messenger *m = tox;
uint32_t message_id = 0;
set_message_error(m_sendaction(m, friend_number, action, length, &message_id), error);
set_message_error(m_send_message_generic(m, friend_number, type, message, length, &message_id), error);
return message_id;
}
@ -850,12 +835,6 @@ void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *function, void
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);
}
bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length)
{
if (!hash || !data) {

View File

@ -296,6 +296,21 @@ typedef enum TOX_USER_STATUS {
TOX_USER_STATUS_INVALID
} TOX_USER_STATUS;
/**
* Represents message types for friend messages and group chat
* messages.
*/
typedef enum TOX_MESSAGE_TYPE {
/**
* Normal text message. Similar to PRIVMSG on IRC.
*/
TOX_MESSAGE_TYPE_MESSAGE,
/**
* A message describing an user action. This is similar to /me (CTCP ACTION)
* on IRC.
*/
TOX_MESSAGE_TYPE_ACTION
} TOX_MESSAGE_TYPE;
/*******************************************************************************
*
@ -1274,6 +1289,8 @@ typedef enum TOX_ERR_FRIEND_SEND_MESSAGE {
* This function creates a chat message packet and pushes it into the send
* queue.
*
* Type corresponds to the message type, for a list of valid types see TOX_MESSAGE_TYPE.
*
* The message length may not exceed TOX_MAX_MESSAGE_LENGTH. Larger messages
* must be split by the client and sent as separate messages. Other clients can
* then reassemble the fragments. Messages may not be empty.
@ -1285,24 +1302,8 @@ typedef enum TOX_ERR_FRIEND_SEND_MESSAGE {
* incremented by 1 each time a message is sent. If UINT32_MAX messages were
* sent, the next message ID is 0.
*/
uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length,
TOX_ERR_FRIEND_SEND_MESSAGE *error);
/**
* Send an action to an online friend.
*
* This is similar to /me (CTCP ACTION) on IRC.
*
* Message ID space is shared between tox_send_message and tox_send_action. This
* means that sending a message will cause the next message ID from sending an
* action will be incremented.
*
* @see tox_friend_send_message for more details.
*/
uint32_t tox_friend_send_action(Tox *tox, uint32_t friend_number, const uint8_t *action, size_t length,
TOX_ERR_FRIEND_SEND_MESSAGE *error);
uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
size_t length, TOX_ERR_FRIEND_SEND_MESSAGE *error);
/**
* The function type for the `read_receipt` callback.
@ -1336,16 +1337,11 @@ void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *func
* The function type for the `friend_request` callback.
*
* @param public_key The Public Key of the user who sent the friend request.
* @param time_delta A delta in seconds between when the message was composed
* and when it is being transmitted. For messages that are sent immediately,
* it will be 0. If a message was written and couldn't be sent immediately
* (due to a connection failure, for example), the time_delta is an
* approximation of when it was composed.
* @param message The message they sent along with the request.
* @param length The size of the message byte array.
*/
typedef void tox_friend_request_cb(Tox *tox, const uint8_t *public_key, /*uint32_t time_delta, */const uint8_t *message,
size_t length, void *user_data);
typedef void tox_friend_request_cb(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length,
void *user_data);
/**
* Set the callback for the `friend_request` event. Pass NULL to unset.
@ -1359,13 +1355,11 @@ void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *function, void
* The function type for the `friend_message` callback.
*
* @param friend_number The friend number of the friend who sent the message.
* @param time_delta Time between composition and sending.
* @param type The message type, for a list of valid types see TOX_MESSAGE_TYPE.
* @param message The message data they sent.
* @param length The size of the message byte array.
*
* @see tox_friend_request_cb for more information on time_delta.
*/
typedef void tox_friend_message_cb(Tox *tox, uint32_t friend_number, /*uint32_t time_delta, */const uint8_t *message,
typedef void tox_friend_message_cb(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
size_t length, void *user_data);
/**
@ -1376,28 +1370,6 @@ typedef void tox_friend_message_cb(Tox *tox, uint32_t friend_number, /*uint32_t
void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *function, void *user_data);
/**
* The function type for the `friend_action` callback.
*
* @param friend_number The friend number of the friend who sent the action.
* @param time_delta Time between composition and sending.
* @param action The action message data they sent.
* @param length The size of the action byte array.
*
* @see tox_friend_request_cb for more information on time_delta.
*/
typedef void tox_friend_action_cb(Tox *tox, uint32_t friend_number, /*uint32_t time_delta, */const uint8_t *action,
size_t length, void *user_data);
/**
* Set the callback for the `friend_action` event. Pass NULL to unset.
*
* This event is triggered when an action from a friend is received.
*/
void tox_callback_friend_action(Tox *tox, tox_friend_action_cb *function, void *user_data);
/*******************************************************************************
*
* :: File transmission: common between sending and receiving