summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-08-07 13:51:58 -0400
committerirungentoo <irungentoo@gmail.com>2013-08-07 13:51:58 -0400
commit59f873fd6842634bd589640c7d63e1e0e0ecefaf (patch)
tree76370462b6c2f293d4fd1c37fa0ac1ee6b0dc68f /core
parent5a8da17e61f59f189a8534f75d56c0e98f9caf39 (diff)
parentc0828667e70fdd92fd01c581ce04dfc451e01860 (diff)
Merge branch 'read-receipt' of https://github.com/stal888/ProjectTox-Core into pull-requests
Conflicts: testing/toxic/chat.c testing/toxic/prompt.c
Diffstat (limited to 'core')
-rw-r--r--core/Messenger.c65
-rw-r--r--core/Messenger.h25
2 files changed, 81 insertions, 9 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 }
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 */