summaryrefslogtreecommitdiff
path: root/core/Messenger.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/Messenger.c')
-rw-r--r--core/Messenger.c65
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
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 }