summaryrefslogtreecommitdiff
path: root/core/Messenger.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/Messenger.c')
-rw-r--r--core/Messenger.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/core/Messenger.c b/core/Messenger.c
index d8bf3413..a4195d58 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,30 @@ 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 return m_sendmessage_withid(friendnumber, friendlist[friendnumber].message_id++, message, length);
209}
210
211uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length)
212{
213 if (friendnumber < 0 || friendnumber >= numfriends)
214 return 0;
215 if (length >= (MAX_DATA_SIZE - 4) || 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. */ 216 /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */
204 return 0; 217 return 0;
205 uint8_t temp[MAX_DATA_SIZE]; 218 uint8_t temp[MAX_DATA_SIZE];
206 temp[0] = PACKET_ID_MESSAGE; 219 temp[0] = PACKET_ID_MESSAGE;
207 memcpy(temp + 1, message, length); 220 temp[1] = theid >> 24;
208 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); 221 temp[2] = theid >> 16;
222 temp[3] = theid >> 8;
223 temp[4] = theid;
224 memcpy(temp + 5, message, length);
225 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 5);
209} 226}
210 227
211/* send a name packet to friendnumber 228/* send a name packet to friendnumber
@@ -408,6 +425,14 @@ void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uin
408 friend_statuschange_isset = 1; 425 friend_statuschange_isset = 1;
409} 426}
410 427
428static void (*read_receipt)(int, uint32_t);
429static uint8_t read_receipt_isset = 0;
430void m_callback_read_receipt(void (*function)(int, uint32_t))
431{
432 read_receipt = function;
433 read_receipt_isset = 1;
434}
435
411#define PORT 33445 436#define PORT 33445
412/* run this at startup */ 437/* run this at startup */
413int initMessenger(void) 438int initMessenger(void)
@@ -499,8 +524,23 @@ static void doFriends(void)
499 break; 524 break;
500 } 525 }
501 case PACKET_ID_MESSAGE: { 526 case PACKET_ID_MESSAGE: {
527 if (friendlist[i].receives_read_receipts) {
528 uint8_t *thepacket = malloc(5);
529 thepacket[0] = PACKET_ID_RECEIPT;
530 memcpy(thepacket + 1, temp + 1, 4);
531 write_cryptpacket(friendlist[i].crypt_connection_id, thepacket, 5);
532 free(thepacket);
533 }
502 if (friend_message_isset) 534 if (friend_message_isset)
503 (*friend_message)(i, temp + 1, len - 1); 535 (*friend_message)(i, temp + 5, len - 5);
536 break;
537 }
538 case PACKET_ID_RECEIPT: {
539 if (len < 5)
540 break;
541 uint32_t msgid = (temp[1] << 24) | (temp[2] << 16) | (temp[3] << 8) | temp[4];
542 if (read_receipt_isset)
543 (*read_receipt)(i, msgid);
504 break; 544 break;
505 } 545 }
506 } 546 }