summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/Messenger.c65
-rw-r--r--core/Messenger.h25
-rw-r--r--testing/toxic/chat.c3
-rw-r--r--testing/toxic/main.c3
-rw-r--r--testing/toxic/prompt.c14
5 files changed, 96 insertions, 14 deletions
diff --git a/core/Messenger.c b/core/Messenger.c
index 3ad9097c..f1d8b35e 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -38,6 +38,8 @@ typedef struct {
38 USERSTATUS userstatus; 38 USERSTATUS userstatus;
39 uint8_t userstatus_sent; 39 uint8_t userstatus_sent;
40 uint16_t info_size; /* length of the info */ 40 uint16_t info_size; /* length of the info */
41 uint32_t message_id; /* a semi-unique id used in read receipts */
42 uint8_t receives_read_receipts; /* shall we send read receipts to this person? */
41} Friend; 43} Friend;
42 44
43uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 45uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
@@ -129,6 +131,8 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
129 friendlist[i].userstatus = USERSTATUS_NONE; 131 friendlist[i].userstatus = USERSTATUS_NONE;
130 memcpy(friendlist[i].info, data, length); 132 memcpy(friendlist[i].info, data, length);
131 friendlist[i].info_size = length; 133 friendlist[i].info_size = length;
134 friendlist[i].message_id = 0;
135 friendlist[i].receives_read_receipts = 1; /* default: YES */
132 136
133 ++numfriends; 137 ++numfriends;
134 return i; 138 return i;
@@ -152,6 +156,8 @@ int m_addfriend_norequest(uint8_t * client_id)
152 friendlist[i].statusmessage = calloc(1, 1); 156 friendlist[i].statusmessage = calloc(1, 1);
153 friendlist[i].statusmessage_length = 1; 157 friendlist[i].statusmessage_length = 1;
154 friendlist[i].userstatus = USERSTATUS_NONE; 158 friendlist[i].userstatus = USERSTATUS_NONE;
159 friendlist[i].message_id = 0;
160 friendlist[i].receives_read_receipts = 1; /* default: YES */
155 numfriends++; 161 numfriends++;
156 return i; 162 return i;
157 } 163 }
@@ -195,19 +201,31 @@ int m_friendstatus(int friendnumber)
195} 201}
196 202
197/* send a text chat message to an online friend 203/* send a text chat message to an online friend
198 return 1 if packet was successfully put into the send queue 204 return the message id if packet was successfully put into the send queue
199 return 0 if it was not */ 205 return 0 if it was not */
200int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) 206uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length)
201{ 207{
202 if (friendnumber < 0 || friendnumber >= numfriends) 208 if (friendnumber < 0 || friendnumber >= numfriends)
203 return 0; 209 return 0;
204 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != FRIEND_ONLINE) 210 uint32_t msgid = ++friendlist[friendnumber].message_id;
211 if (msgid == 0)
212 msgid = 1; /* otherwise, false error */
213 return m_sendmessage_withid(friendnumber, msgid, message, length);
214}
215
216uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length)
217{
218 if (friendnumber < 0 || friendnumber >= numfriends)
219 return 0;
220 if (length >= (MAX_DATA_SIZE - sizeof(theid)) || friendlist[friendnumber].status != FRIEND_ONLINE)
205 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ 221 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
206 return 0; 222 return 0;
207 uint8_t temp[MAX_DATA_SIZE]; 223 uint8_t temp[MAX_DATA_SIZE];
208 temp[0] = PACKET_ID_MESSAGE; 224 temp[0] = PACKET_ID_MESSAGE;
209 memcpy(temp + 1, message, length); 225 theid = htonl(theid);
210 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); 226 memcpy(temp + 1, &theid, sizeof(theid));
227 memcpy(temp + 1 + sizeof(theid), message, length);
228 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1 + sizeof(theid));
211} 229}
212 230
213/* send a name packet to friendnumber 231/* send a name packet to friendnumber
@@ -382,6 +400,16 @@ static void set_friend_userstatus(int friendnumber, USERSTATUS status)
382 friendlist[friendnumber].userstatus = status; 400 friendlist[friendnumber].userstatus = status;
383} 401}
384 402
403/* Sets whether we send read receipts for friendnumber. */
404void m_set_sends_receipts(int friendnumber, int yesno)
405{
406 if (yesno != 0 || yesno != 1)
407 return;
408 if (friendnumber >= numfriends || friendnumber < 0)
409 return;
410 friendlist[friendnumber].receives_read_receipts = yesno;
411}
412
385/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); 413/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
386static uint8_t friend_request_isset = 0; */ 414static uint8_t friend_request_isset = 0; */
387/* set the function that will be executed when a friend request is received. */ 415/* 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))
424 friend_userstatuschange_isset = 1; 452 friend_userstatuschange_isset = 1;
425} 453}
426 454
455static void (*read_receipt)(int, uint32_t);
456static uint8_t read_receipt_isset = 0;
457void m_callback_read_receipt(void (*function)(int, uint32_t))
458{
459 read_receipt = function;
460 read_receipt_isset = 1;
461}
462
427#define PORT 33445 463#define PORT 33445
428/* run this at startup */ 464/* run this at startup */
429int initMessenger(void) 465int initMessenger(void)
@@ -521,8 +557,25 @@ static void doFriends(void)
521 break; 557 break;
522 } 558 }
523 case PACKET_ID_MESSAGE: { 559 case PACKET_ID_MESSAGE: {
560 if (friendlist[i].receives_read_receipts) {
561 uint8_t *thepacket = malloc(5);
562 thepacket[0] = PACKET_ID_RECEIPT;
563 memcpy(thepacket + 1, temp + 1, 4);
564 write_cryptpacket(friendlist[i].crypt_connection_id, thepacket, 5);
565 free(thepacket);
566 }
524 if (friend_message_isset) 567 if (friend_message_isset)
525 (*friend_message)(i, temp + 1, len - 1); 568 (*friend_message)(i, temp + 5, len - 5);
569 break;
570 }
571 case PACKET_ID_RECEIPT: {
572 uint32_t msgid;
573 if (len < 1 + sizeof(msgid))
574 break;
575 memcpy(&msgid, temp + 1, sizeof(msgid));
576 msgid = ntohl(msgid);
577 if (read_receipt_isset)
578 (*read_receipt)(i, msgid);
526 break; 579 break;
527 } 580 }
528 } 581 }
diff --git a/core/Messenger.h b/core/Messenger.h
index aef652ff..d2fa8945 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -41,6 +41,7 @@ extern "C" {
41#define PACKET_ID_NICKNAME 48 41#define PACKET_ID_NICKNAME 48
42#define PACKET_ID_STATUSMESSAGE 49 42#define PACKET_ID_STATUSMESSAGE 49
43#define PACKET_ID_USERSTATUS 50 43#define PACKET_ID_USERSTATUS 50
44#define PACKET_ID_RECEIPT 65
44#define PACKET_ID_MESSAGE 64 45#define PACKET_ID_MESSAGE 64
45 46
46/* status definitions */ 47/* status definitions */
@@ -112,9 +113,14 @@ int m_delfriend(int friendnumber);
112int m_friendstatus(int friendnumber); 113int m_friendstatus(int friendnumber);
113 114
114/* send a text chat message to an online friend 115/* send a text chat message to an online friend
115 returns 1 if packet was successfully put into the send queue 116 returns the message id if packet was successfully put into the send queue
116 return 0 if it was not */ 117 return 0 if it was not
117int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); 118 you will want to retain the return value, it will be passed to your read receipt callback
119 if one is received.
120 m_sendmessage_withid will send a message with the id of your choosing,
121 however we can generate an id for you by calling plain m_sendmessage. */
122uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
123uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length);
118 124
119/* Set our nickname 125/* Set our nickname
120 name must be a string of maximum MAX_NAME_LENGTH length. 126 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);
160USERSTATUS m_get_userstatus(int friendnumber); 166USERSTATUS m_get_userstatus(int friendnumber);
161USERSTATUS m_get_self_userstatus(void); 167USERSTATUS m_get_self_userstatus(void);
162 168
169/* Sets whether we send read receipts for friendnumber.
170 * This function is not lazy, and it will fail if yesno is not (0 or 1).*/
171void m_set_sends_receipts(int friendnumber, int yesno);
172
163/* set the function that will be executed when a friend request is received. 173/* set the function that will be executed when a friend request is received.
164 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 174 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
165void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); 175void 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));
178 you are not responsible for freeing newstatus */ 188 you are not responsible for freeing newstatus */
179void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t)); 189void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t));
180 190
191/* set the callback for read receipts
192 function(int friendnumber, uint32_t receipt)
193 if you are keeping a record of returns from m_sendmessage,
194 receipt might be one of those values, and that means the message
195 has been received on the other side. since core doesn't
196 track ids for you, receipt may not correspond to any message
197 in that case, you should discard it. */
198void m_callback_read_receipt(void (*function)(int, uint32_t));
199
181/* run this at startup 200/* run this at startup
182 returns 0 if no connection problems 201 returns 0 if no connection problems
183 returns -1 if there are problems */ 202 returns -1 if there are problems */
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
index 2563fa9c..28c5de6c 100644
--- a/testing/toxic/chat.c
+++ b/testing/toxic/chat.c
@@ -57,7 +57,6 @@ static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
57 57
58 self->blink = true; 58 self->blink = true;
59 beep(); 59 beep();
60 flash();
61} 60}
62 61
63static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t len) 62static 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)
121 wattroff(ctx->history, COLOR_PAIR(1)); 120 wattroff(ctx->history, COLOR_PAIR(1));
122 wprintw(ctx->history, "%s\n", ctx->line); 121 wprintw(ctx->history, "%s\n", ctx->line);
123 } 122 }
124 if (m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) < 0) { 123 if (m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) == 0) {
125 wattron(ctx->history, COLOR_PAIR(3)); 124 wattron(ctx->history, COLOR_PAIR(3));
126 wprintw(ctx->history, " * Failed to send message.\n"); 125 wprintw(ctx->history, " * Failed to send message.\n");
127 wattroff(ctx->history, COLOR_PAIR(3)); 126 wattroff(ctx->history, COLOR_PAIR(3));
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index 59333004..b2310c80 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -22,6 +22,7 @@ extern int add_req(uint8_t *public_key); // XXX
22 22
23/* Holds status of chat windows */ 23/* Holds status of chat windows */
24char WINDOW_STATUS[MAX_WINDOW_SLOTS]; 24char WINDOW_STATUS[MAX_WINDOW_SLOTS];
25#define TOXICVER "0.1.0" //Will be moved to a -D flag later
25 26
26static ToxWindow windows[MAX_WINDOW_SLOTS]; 27static ToxWindow windows[MAX_WINDOW_SLOTS];
27static ToxWindow* prompt; 28static ToxWindow* prompt;
@@ -258,7 +259,7 @@ static void draw_bar()
258 move(LINES - 1, 0); 259 move(LINES - 1, 0);
259 260
260 attron(COLOR_PAIR(4) | A_BOLD); 261 attron(COLOR_PAIR(4) | A_BOLD);
261 printw(" TOXIC 1.0 |"); 262 printw(" TOXIC " TOXICVER " |");
262 attroff(COLOR_PAIR(4) | A_BOLD); 263 attroff(COLOR_PAIR(4) | A_BOLD);
263 264
264 int i; 265 int i;
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index 01261cce..661d881f 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -62,6 +62,16 @@ static void execute(ToxWindow *self, char *u_cmd)
62 if (!isspace(cmd[cmd_end])) 62 if (!isspace(cmd[cmd_end]))
63 break; 63 break;
64 cmd[cmd_end + 1] = '\0'; 64 cmd[cmd_end + 1] = '\0';
65
66/* What is this supposed to do?
67 if (cmd[0] == '/') {
68 wprintw(self->window,"Warning: Run your command without the /, this may not work\n");
69 int i;
70 for (i = 1; i < strlen(cmd); i++) { //This doesn't work when it doesn't end with a space and another word
71 cmd[i - 1] = cmd[i]; //Still working on why
72 }
73 }
74*/
65 75
66 if (!strcmp(cmd, "quit") || !strcmp(cmd, "exit") || !strcmp(cmd, "q")) { 76 if (!strcmp(cmd, "quit") || !strcmp(cmd, "exit") || !strcmp(cmd, "q")) {
67 endwin(); 77 endwin();
@@ -287,7 +297,7 @@ static void execute(ToxWindow *self, char *u_cmd)
287 } 297 }
288 msg[0] = 0; 298 msg[0] = 0;
289 msg++; 299 msg++;
290 if (m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) < 0) 300 if (m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) == 0)
291 wprintw(self->window, "Error occurred while sending message.\n"); 301 wprintw(self->window, "Error occurred while sending message.\n");
292 else 302 else
293 wprintw(self->window, "Message successfully sent.\n"); 303 wprintw(self->window, "Message successfully sent.\n");
@@ -368,7 +378,7 @@ static void print_usage(ToxWindow *self)
368 wprintw(self->window, " myid : Print your ID\n"); 378 wprintw(self->window, " myid : Print your ID\n");
369 wprintw(self->window, " quit/exit : Exit program\n"); 379 wprintw(self->window, " quit/exit : Exit program\n");
370 wprintw(self->window, " help : Print this message again\n"); 380 wprintw(self->window, " help : Print this message again\n");
371 wprintw(self->window, " clear : Clear this window\n"); 381 wprintw(self->window, " clear : Clear this window\n");
372 382
373 wattron(self->window, A_BOLD); 383 wattron(self->window, A_BOLD);
374 wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); 384 wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");