diff options
Diffstat (limited to 'core/Messenger.c')
-rw-r--r-- | core/Messenger.c | 65 |
1 files changed, 59 insertions, 6 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 | ||
43 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 45 | 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) | |||
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 */ |
200 | int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) | 206 | uint32_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 | |||
216 | uint32_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. */ | ||
404 | void 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); |
386 | static uint8_t friend_request_isset = 0; */ | 414 | static 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 | ||
455 | static void (*read_receipt)(int, uint32_t); | ||
456 | static uint8_t read_receipt_isset = 0; | ||
457 | void 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 */ |
429 | int initMessenger(void) | 465 | int 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 | } |