Conflicts:
	core/Messenger.c
	core/Messenger.h
This commit is contained in:
Maxim Biro 2013-08-07 19:18:40 -04:00
commit f669b28a6c
5 changed files with 96 additions and 14 deletions

View File

@ -38,6 +38,8 @@ typedef struct {
USERSTATUS userstatus;
uint8_t userstatus_sent;
uint16_t info_size; /* length of the info */
uint32_t message_id; /* a semi-unique id used in read receipts */
uint8_t receives_read_receipts; /* shall we send read receipts to this person? */
} Friend;
uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
@ -129,6 +131,8 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
friendlist[i].userstatus = USERSTATUS_NONE;
memcpy(friendlist[i].info, data, length);
friendlist[i].info_size = length;
friendlist[i].message_id = 0;
friendlist[i].receives_read_receipts = 1; /* default: YES */
++numfriends;
return i;
@ -152,6 +156,8 @@ int m_addfriend_norequest(uint8_t * client_id)
friendlist[i].statusmessage = calloc(1, 1);
friendlist[i].statusmessage_length = 1;
friendlist[i].userstatus = USERSTATUS_NONE;
friendlist[i].message_id = 0;
friendlist[i].receives_read_receipts = 1; /* default: YES */
numfriends++;
return i;
}
@ -195,19 +201,31 @@ int m_friendstatus(int friendnumber)
}
/* send a text chat message to an online friend
return 1 if packet was successfully put into the send queue
return the message id if packet was successfully put into the send queue
return 0 if it was not */
int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length)
uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length)
{
if (friendnumber < 0 || friendnumber >= numfriends)
return 0;
if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != FRIEND_ONLINE)
uint32_t msgid = ++friendlist[friendnumber].message_id;
if (msgid == 0)
msgid = 1; /* otherwise, false error */
return m_sendmessage_withid(friendnumber, msgid, message, length);
}
uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length)
{
if (friendnumber < 0 || friendnumber >= numfriends)
return 0;
if (length >= (MAX_DATA_SIZE - sizeof(theid)) || friendlist[friendnumber].status != FRIEND_ONLINE)
/* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
return 0;
uint8_t temp[MAX_DATA_SIZE];
temp[0] = PACKET_ID_MESSAGE;
memcpy(temp + 1, message, length);
return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1);
theid = htonl(theid);
memcpy(temp + 1, &theid, sizeof(theid));
memcpy(temp + 1 + sizeof(theid), message, length);
return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1 + sizeof(theid));
}
/* send a name packet to friendnumber
@ -382,6 +400,16 @@ static void set_friend_userstatus(int friendnumber, USERSTATUS status)
friendlist[friendnumber].userstatus = status;
}
/* Sets whether we send read receipts for friendnumber. */
void m_set_sends_receipts(int friendnumber, int yesno)
{
if (yesno != 0 || yesno != 1)
return;
if (friendnumber >= numfriends || friendnumber < 0)
return;
friendlist[friendnumber].receives_read_receipts = yesno;
}
/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
static uint8_t friend_request_isset = 0; */
/* set the function that will be executed when a friend request is received. */
@ -424,6 +452,14 @@ void m_callback_userstatus(void (*function)(int, USERSTATUS))
friend_userstatuschange_isset = 1;
}
static void (*read_receipt)(int, uint32_t);
static uint8_t read_receipt_isset = 0;
void m_callback_read_receipt(void (*function)(int, uint32_t))
{
read_receipt = function;
read_receipt_isset = 1;
}
#define PORT 33445
/* run this at startup */
int initMessenger(void)
@ -521,8 +557,25 @@ static void doFriends(void)
break;
}
case PACKET_ID_MESSAGE: {
if (friendlist[i].receives_read_receipts) {
uint8_t *thepacket = malloc(5);
thepacket[0] = PACKET_ID_RECEIPT;
memcpy(thepacket + 1, temp + 1, 4);
write_cryptpacket(friendlist[i].crypt_connection_id, thepacket, 5);
free(thepacket);
}
if (friend_message_isset)
(*friend_message)(i, temp + 1, len - 1);
(*friend_message)(i, temp + 5, len - 5);
break;
}
case PACKET_ID_RECEIPT: {
uint32_t msgid;
if (len < 1 + sizeof(msgid))
break;
memcpy(&msgid, temp + 1, sizeof(msgid));
msgid = ntohl(msgid);
if (read_receipt_isset)
(*read_receipt)(i, msgid);
break;
}
}

View File

@ -41,6 +41,7 @@ extern "C" {
#define PACKET_ID_NICKNAME 48
#define PACKET_ID_STATUSMESSAGE 49
#define PACKET_ID_USERSTATUS 50
#define PACKET_ID_RECEIPT 65
#define PACKET_ID_MESSAGE 64
/* status definitions */
@ -112,9 +113,14 @@ int m_delfriend(int friendnumber);
int m_friendstatus(int friendnumber);
/* send a text chat message to an online friend
returns 1 if packet was successfully put into the send queue
return 0 if it was not */
int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
returns the message id if packet was successfully put into the send queue
return 0 if it was not
you will want to retain the return value, it will be passed to your read receipt callback
if one is received.
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 m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length);
/* Set our nickname
name must be a string of maximum MAX_NAME_LENGTH length.
@ -160,6 +166,10 @@ int m_copy_self_statusmessage(uint8_t *buf, uint32_t maxlen);
USERSTATUS m_get_userstatus(int friendnumber);
USERSTATUS m_get_self_userstatus(void);
/* 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 m_set_sends_receipts(int friendnumber, int yesno);
/* 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 m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
@ -178,6 +188,15 @@ void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t));
you are not responsible for freeing newstatus */
void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t));
/* set the callback for read receipts
function(int friendnumber, uint32_t receipt)
if you are keeping a record of returns from m_sendmessage,
receipt might be one of those values, and that means the message
has been received on the other side. since core doesn't
track ids for you, receipt may not correspond to any message
in that case, you should discard it. */
void m_callback_read_receipt(void (*function)(int, uint32_t));
/* run this at startup
returns 0 if no connection problems
returns -1 if there are problems */

View File

@ -57,7 +57,6 @@ static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
self->blink = true;
beep();
flash();
}
static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t len)
@ -121,7 +120,7 @@ static void chat_onKey(ToxWindow *self, int key)
wattroff(ctx->history, COLOR_PAIR(1));
wprintw(ctx->history, "%s\n", ctx->line);
}
if (m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) < 0) {
if (m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) == 0) {
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, " * Failed to send message.\n");
wattroff(ctx->history, COLOR_PAIR(3));

View File

@ -22,6 +22,7 @@ extern int add_req(uint8_t *public_key); // XXX
/* Holds status of chat windows */
char WINDOW_STATUS[MAX_WINDOW_SLOTS];
#define TOXICVER "0.1.0" //Will be moved to a -D flag later
static ToxWindow windows[MAX_WINDOW_SLOTS];
static ToxWindow* prompt;
@ -258,7 +259,7 @@ static void draw_bar()
move(LINES - 1, 0);
attron(COLOR_PAIR(4) | A_BOLD);
printw(" TOXIC 1.0 |");
printw(" TOXIC " TOXICVER " |");
attroff(COLOR_PAIR(4) | A_BOLD);
int i;

View File

@ -62,6 +62,16 @@ static void execute(ToxWindow *self, char *u_cmd)
if (!isspace(cmd[cmd_end]))
break;
cmd[cmd_end + 1] = '\0';
/* What is this supposed to do?
if (cmd[0] == '/') {
wprintw(self->window,"Warning: Run your command without the /, this may not work\n");
int i;
for (i = 1; i < strlen(cmd); i++) { //This doesn't work when it doesn't end with a space and another word
cmd[i - 1] = cmd[i]; //Still working on why
}
}
*/
if (!strcmp(cmd, "quit") || !strcmp(cmd, "exit") || !strcmp(cmd, "q")) {
endwin();
@ -287,7 +297,7 @@ static void execute(ToxWindow *self, char *u_cmd)
}
msg[0] = 0;
msg++;
if (m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) < 0)
if (m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) == 0)
wprintw(self->window, "Error occurred while sending message.\n");
else
wprintw(self->window, "Message successfully sent.\n");
@ -368,7 +378,7 @@ static void print_usage(ToxWindow *self)
wprintw(self->window, " myid : Print your ID\n");
wprintw(self->window, " quit/exit : Exit program\n");
wprintw(self->window, " help : Print this message again\n");
wprintw(self->window, " clear : Clear this window\n");
wprintw(self->window, " clear : Clear this window\n");
wattron(self->window, A_BOLD);
wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");