summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorSebastian Stal <stal@pyboard.net>2013-08-07 09:53:52 -0700
committerSebastian Stal <stal@pyboard.net>2013-08-07 09:53:52 -0700
commit105e2fa4a38de07493f9388ab23acba2b2969458 (patch)
tree54a86786e6cff98ae003f3e0f2f4f76d2f5bc7a3 /core
parent39a213a58c8a98384b0813eb1e0f035606a7a305 (diff)
Add read receipts using packet ID 65.
Diffstat (limited to 'core')
-rw-r--r--core/Messenger.c52
-rw-r--r--core/Messenger.h14
2 files changed, 57 insertions, 9 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 }
diff --git a/core/Messenger.h b/core/Messenger.h
index 8940aadd..0e4eabe0 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.
@@ -183,6 +189,8 @@ void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t));
183 you are not responsible for freeing newstatus */ 189 you are not responsible for freeing newstatus */
184void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uint16_t)); 190void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uint16_t));
185 191
192void m_callback_read_receipt(void (*function)(int, uint32_t));
193
186/* run this at startup 194/* run this at startup
187 returns 0 if no connection problems 195 returns 0 if no connection problems
188 returns -1 if there are problems */ 196 returns -1 if there are problems */