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 4e994a15..33af599d 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,33 @@ 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 - 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. */ 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 temp[1] = theid >> 24;
208 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); 224 temp[2] = theid >> 16;
225 temp[3] = theid >> 8;
226 temp[4] = theid;
227 memcpy(temp + 5, message, length);
228 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 5);
209} 229}
210 230
211/* send a name packet to friendnumber 231/* send a name packet to friendnumber
@@ -374,6 +394,16 @@ static void set_friend_userstatus_kind(int friendnumber, USERSTATUS_KIND k)
374 friendlist[friendnumber].userstatus_kind = k; 394 friendlist[friendnumber].userstatus_kind = k;
375} 395}
376 396
397/* Sets whether we send read receipts for friendnumber. */
398void m_set_sends_receipts(int friendnumber, int yesno)
399{
400 if (yesno < 0 || yesno > 1)
401 return;
402 if (friendnumber >= numfriends || friendnumber < 0)
403 return;
404 friendlist[friendnumber].receives_read_receipts = yesno;
405}
406
377/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); 407/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
378static uint8_t friend_request_isset = 0; */ 408static uint8_t friend_request_isset = 0; */
379/* set the function that will be executed when a friend request is received. */ 409/* set the function that will be executed when a friend request is received. */
@@ -408,6 +438,14 @@ void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uin
408 friend_statuschange_isset = 1; 438 friend_statuschange_isset = 1;
409} 439}
410 440
441static void (*read_receipt)(int, uint32_t);
442static uint8_t read_receipt_isset = 0;
443void m_callback_read_receipt(void (*function)(int, uint32_t))
444{
445 read_receipt = function;
446 read_receipt_isset = 1;
447}
448
411#define PORT 33445 449#define PORT 33445
412/* run this at startup */ 450/* run this at startup */
413int initMessenger(void) 451int initMessenger(void)
@@ -499,8 +537,23 @@ static void doFriends(void)
499 break; 537 break;
500 } 538 }
501 case PACKET_ID_MESSAGE: { 539 case PACKET_ID_MESSAGE: {
540 if (friendlist[i].receives_read_receipts) {
541 uint8_t *thepacket = malloc(5);
542 thepacket[0] = PACKET_ID_RECEIPT;
543 memcpy(thepacket + 1, temp + 1, 4);
544 write_cryptpacket(friendlist[i].crypt_connection_id, thepacket, 5);
545 free(thepacket);
546 }
502 if (friend_message_isset) 547 if (friend_message_isset)
503 (*friend_message)(i, temp + 1, len - 1); 548 (*friend_message)(i, temp + 5, len - 5);
549 break;
550 }
551 case PACKET_ID_RECEIPT: {
552 if (len < 5)
553 break;
554 uint32_t msgid = (temp[1] << 24) | (temp[2] << 16) | (temp[3] << 8) | temp[4];
555 if (read_receipt_isset)
556 (*read_receipt)(i, msgid);
504 break; 557 break;
505 } 558 }
506 } 559 }