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 4e994a15..b29bd1f1 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -37,6 +37,8 @@ typedef struct {
37 uint8_t userstatus_sent; 37 uint8_t userstatus_sent;
38 USERSTATUS_KIND userstatus_kind; 38 USERSTATUS_KIND userstatus_kind;
39 uint16_t info_size; /* length of the info */ 39 uint16_t info_size; /* length of the info */
40 uint32_t message_id; /* a semi-unique id used in read receipts */
41 uint8_t receives_read_receipts; /* shall we send read receipts to this person? */
40} Friend; 42} Friend;
41 43
42uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 44uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
@@ -128,6 +130,8 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
128 friendlist[i].userstatus_kind = USERSTATUS_KIND_OFFLINE; 130 friendlist[i].userstatus_kind = USERSTATUS_KIND_OFFLINE;
129 memcpy(friendlist[i].info, data, length); 131 memcpy(friendlist[i].info, data, length);
130 friendlist[i].info_size = length; 132 friendlist[i].info_size = length;
133 friendlist[i].message_id = 0;
134 friendlist[i].receives_read_receipts = 1; /* default: YES */
131 135
132 ++numfriends; 136 ++numfriends;
133 return i; 137 return i;
@@ -150,6 +154,8 @@ int m_addfriend_norequest(uint8_t * client_id)
150 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); 154 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
151 friendlist[i].userstatus = calloc(1, 1); 155 friendlist[i].userstatus = calloc(1, 1);
152 friendlist[i].userstatus_length = 1; 156 friendlist[i].userstatus_length = 1;
157 friendlist[i].message_id = 0;
158 friendlist[i].receives_read_receipts = 1; /* default: YES */
153 numfriends++; 159 numfriends++;
154 return i; 160 return i;
155 } 161 }
@@ -193,19 +199,31 @@ int m_friendstatus(int friendnumber)
193} 199}
194 200
195/* send a text chat message to an online friend 201/* send a text chat message to an online friend
196 return 1 if packet was successfully put into the send queue 202 return the message id if packet was successfully put into the send queue
197 return 0 if it was not */ 203 return 0 if it was not */
198int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) 204uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length)
199{ 205{
200 if (friendnumber < 0 || friendnumber >= numfriends) 206 if (friendnumber < 0 || friendnumber >= numfriends)
201 return 0; 207 return 0;
202 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != FRIEND_ONLINE) 208 uint32_t msgid = ++friendlist[friendnumber].message_id;
209 if (msgid == 0)
210 msgid = 1; /* otherwise, false error */
211 return m_sendmessage_withid(friendnumber, msgid, message, length);
212}
213
214uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length)
215{
216 if (friendnumber < 0 || friendnumber >= numfriends)
217 return 0;
218 if (length >= (MAX_DATA_SIZE - sizeof(theid)) || friendlist[friendnumber].status != FRIEND_ONLINE)
203 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ 219 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
204 return 0; 220 return 0;
205 uint8_t temp[MAX_DATA_SIZE]; 221 uint8_t temp[MAX_DATA_SIZE];
206 temp[0] = PACKET_ID_MESSAGE; 222 temp[0] = PACKET_ID_MESSAGE;
207 memcpy(temp + 1, message, length); 223 theid = htonl(theid);
208 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); 224 memcpy(temp + 1, &theid, sizeof(theid));
225 memcpy(temp + 1 + sizeof(theid), message, length);
226 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1 + sizeof(theid));
209} 227}
210 228
211/* send a name packet to friendnumber 229/* send a name packet to friendnumber
@@ -374,6 +392,16 @@ static void set_friend_userstatus_kind(int friendnumber, USERSTATUS_KIND k)
374 friendlist[friendnumber].userstatus_kind = k; 392 friendlist[friendnumber].userstatus_kind = k;
375} 393}
376 394
395/* Sets whether we send read receipts for friendnumber. */
396void m_set_sends_receipts(int friendnumber, int yesno)
397{
398 if (yesno != 0 || yesno != 1)
399 return;
400 if (friendnumber >= numfriends || friendnumber < 0)
401 return;
402 friendlist[friendnumber].receives_read_receipts = yesno;
403}
404
377/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); 405/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
378static uint8_t friend_request_isset = 0; */ 406static uint8_t friend_request_isset = 0; */
379/* set the function that will be executed when a friend request is received. */ 407/* set the function that will be executed when a friend request is received. */
@@ -408,6 +436,14 @@ void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uin
408 friend_statuschange_isset = 1; 436 friend_statuschange_isset = 1;
409} 437}
410 438
439static void (*read_receipt)(int, uint32_t);
440static uint8_t read_receipt_isset = 0;
441void m_callback_read_receipt(void (*function)(int, uint32_t))
442{
443 read_receipt = function;
444 read_receipt_isset = 1;
445}
446
411#define PORT 33445 447#define PORT 33445
412/* run this at startup */ 448/* run this at startup */
413int initMessenger(void) 449int initMessenger(void)
@@ -499,8 +535,25 @@ static void doFriends(void)
499 break; 535 break;
500 } 536 }
501 case PACKET_ID_MESSAGE: { 537 case PACKET_ID_MESSAGE: {
538 if (friendlist[i].receives_read_receipts) {
539 uint8_t *thepacket = malloc(5);
540 thepacket[0] = PACKET_ID_RECEIPT;
541 memcpy(thepacket + 1, temp + 1, 4);
542 write_cryptpacket(friendlist[i].crypt_connection_id, thepacket, 5);
543 free(thepacket);
544 }
502 if (friend_message_isset) 545 if (friend_message_isset)
503 (*friend_message)(i, temp + 1, len - 1); 546 (*friend_message)(i, temp + 5, len - 5);
547 break;
548 }
549 case PACKET_ID_RECEIPT: {
550 uint32_t msgid;
551 if (len < 1 + sizeof(msgid))
552 break;
553 memcpy(&msgid, temp + 1, sizeof(msgid));
554 msgid = ntohl(msgid);
555 if (read_receipt_isset)
556 (*read_receipt)(i, msgid);
504 break; 557 break;
505 } 558 }
506 } 559 }
diff --git a/core/Messenger.h b/core/Messenger.h
index 8940aadd..f0444b91 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -40,6 +40,7 @@ extern "C" {
40 40
41#define PACKET_ID_NICKNAME 48 41#define PACKET_ID_NICKNAME 48
42#define PACKET_ID_USERSTATUS 49 42#define PACKET_ID_USERSTATUS 49
43#define PACKET_ID_RECEIPT 65
43#define PACKET_ID_MESSAGE 64 44#define PACKET_ID_MESSAGE 64
44 45
45/* status definitions */ 46/* status definitions */
@@ -117,9 +118,14 @@ int m_delfriend(int friendnumber);
117int m_friendstatus(int friendnumber); 118int m_friendstatus(int friendnumber);
118 119
119/* send a text chat message to an online friend 120/* send a text chat message to an online friend
120 returns 1 if packet was successfully put into the send queue 121 returns the message id if packet was successfully put into the send queue
121 return 0 if it was not */ 122 return 0 if it was not
122int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); 123 you will want to retain the return value, it will be passed to your read receipt callback
124 if one is received.
125 m_sendmessage_withid will send a message with the id of your choosing,
126 however we can generate an id for you by calling plain m_sendmessage. */
127uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
128uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length);
123 129
124/* Set our nickname 130/* Set our nickname
125 name must be a string of maximum MAX_NAME_LENGTH length. 131 name must be a string of maximum MAX_NAME_LENGTH length.
@@ -165,6 +171,10 @@ int m_copy_self_userstatus(uint8_t *buf, uint32_t maxlen);
165USERSTATUS_KIND m_get_userstatus_kind(int friendnumber); 171USERSTATUS_KIND m_get_userstatus_kind(int friendnumber);
166USERSTATUS_KIND m_get_self_userstatus_kind(void); 172USERSTATUS_KIND m_get_self_userstatus_kind(void);
167 173
174/* Sets whether we send read receipts for friendnumber.
175 * This function is not lazy, and it will fail if yesno is not (0 or 1).*/
176void m_set_sends_receipts(int friendnumber, int yesno);
177
168/* set the function that will be executed when a friend request is received. 178/* set the function that will be executed when a friend request is received.
169 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 179 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
170void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); 180void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
@@ -183,6 +193,15 @@ void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t));
183 you are not responsible for freeing newstatus */ 193 you are not responsible for freeing newstatus */
184void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uint16_t)); 194void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uint16_t));
185 195
196/* set the callback for read receipts
197 function(int friendnumber, uint32_t receipt)
198 if you are keeping a record of returns from m_sendmessage,
199 receipt might be one of those values, and that means the message
200 has been received on the other side. since core doesn't
201 track ids for you, receipt may not correspond to any message
202 in that case, you should discard it. */
203void m_callback_read_receipt(void (*function)(int, uint32_t));
204
186/* run this at startup 205/* run this at startup
187 returns 0 if no connection problems 206 returns 0 if no connection problems
188 returns -1 if there are problems */ 207 returns -1 if there are problems */
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
index 20c01620..b870e9c2 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 8de76244..27e3d858 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 d79d061f..486273d3 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();
@@ -291,7 +301,7 @@ static void execute(ToxWindow *self, char *u_cmd)
291 } 301 }
292 msg[0] = 0; 302 msg[0] = 0;
293 msg++; 303 msg++;
294 if (m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) < 0) 304 if (m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) == 0)
295 wprintw(self->window, "Error occurred while sending message.\n"); 305 wprintw(self->window, "Error occurred while sending message.\n");
296 else 306 else
297 wprintw(self->window, "Message successfully sent.\n"); 307 wprintw(self->window, "Message successfully sent.\n");
@@ -372,7 +382,7 @@ static void print_usage(ToxWindow *self)
372 wprintw(self->window, " myid : Print your ID\n"); 382 wprintw(self->window, " myid : Print your ID\n");
373 wprintw(self->window, " quit/exit : Exit program\n"); 383 wprintw(self->window, " quit/exit : Exit program\n");
374 wprintw(self->window, " help : Print this message again\n"); 384 wprintw(self->window, " help : Print this message again\n");
375 wprintw(self->window, " clear : Clear this window\n"); 385 wprintw(self->window, " clear : Clear this window\n");
376 386
377 wattron(self->window, A_BOLD); 387 wattron(self->window, A_BOLD);
378 wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); 388 wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");