diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/Messenger.c | 65 | ||||
-rw-r--r-- | core/Messenger.h | 25 |
2 files changed, 81 insertions, 9 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 | ||
43 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | 45 | uint8_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 */ |
200 | int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) | 206 | uint32_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 | |||
216 | uint32_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. */ | ||
404 | void 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); |
386 | static uint8_t friend_request_isset = 0; */ | 414 | static 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 | ||
455 | static void (*read_receipt)(int, uint32_t); | ||
456 | static uint8_t read_receipt_isset = 0; | ||
457 | void 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 */ |
429 | int initMessenger(void) | 465 | int 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 | } |
diff --git a/core/Messenger.h b/core/Messenger.h index aef652ff..d2fa8945 100644 --- a/core/Messenger.h +++ b/core/Messenger.h | |||
@@ -41,6 +41,7 @@ extern "C" { | |||
41 | #define PACKET_ID_NICKNAME 48 | 41 | #define PACKET_ID_NICKNAME 48 |
42 | #define PACKET_ID_STATUSMESSAGE 49 | 42 | #define PACKET_ID_STATUSMESSAGE 49 |
43 | #define PACKET_ID_USERSTATUS 50 | 43 | #define PACKET_ID_USERSTATUS 50 |
44 | #define PACKET_ID_RECEIPT 65 | ||
44 | #define PACKET_ID_MESSAGE 64 | 45 | #define PACKET_ID_MESSAGE 64 |
45 | 46 | ||
46 | /* status definitions */ | 47 | /* status definitions */ |
@@ -112,9 +113,14 @@ int m_delfriend(int friendnumber); | |||
112 | int m_friendstatus(int friendnumber); | 113 | int m_friendstatus(int friendnumber); |
113 | 114 | ||
114 | /* send a text chat message to an online friend | 115 | /* send a text chat message to an online friend |
115 | returns 1 if packet was successfully put into the send queue | 116 | returns the message id if packet was successfully put into the send queue |
116 | return 0 if it was not */ | 117 | return 0 if it was not |
117 | int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); | 118 | you will want to retain the return value, it will be passed to your read receipt callback |
119 | if one is received. | ||
120 | m_sendmessage_withid will send a message with the id of your choosing, | ||
121 | however we can generate an id for you by calling plain m_sendmessage. */ | ||
122 | uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); | ||
123 | uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length); | ||
118 | 124 | ||
119 | /* Set our nickname | 125 | /* Set our nickname |
120 | name must be a string of maximum MAX_NAME_LENGTH length. | 126 | name must be a string of maximum MAX_NAME_LENGTH length. |
@@ -160,6 +166,10 @@ int m_copy_self_statusmessage(uint8_t *buf, uint32_t maxlen); | |||
160 | USERSTATUS m_get_userstatus(int friendnumber); | 166 | USERSTATUS m_get_userstatus(int friendnumber); |
161 | USERSTATUS m_get_self_userstatus(void); | 167 | USERSTATUS m_get_self_userstatus(void); |
162 | 168 | ||
169 | /* Sets whether we send read receipts for friendnumber. | ||
170 | * This function is not lazy, and it will fail if yesno is not (0 or 1).*/ | ||
171 | void m_set_sends_receipts(int friendnumber, int yesno); | ||
172 | |||
163 | /* set the function that will be executed when a friend request is received. | 173 | /* set the function that will be executed when a friend request is received. |
164 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ | 174 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ |
165 | void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); | 175 | void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); |
@@ -178,6 +188,15 @@ void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)); | |||
178 | you are not responsible for freeing newstatus */ | 188 | you are not responsible for freeing newstatus */ |
179 | void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t)); | 189 | void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t)); |
180 | 190 | ||
191 | /* set the callback for read receipts | ||
192 | function(int friendnumber, uint32_t receipt) | ||
193 | if you are keeping a record of returns from m_sendmessage, | ||
194 | receipt might be one of those values, and that means the message | ||
195 | has been received on the other side. since core doesn't | ||
196 | track ids for you, receipt may not correspond to any message | ||
197 | in that case, you should discard it. */ | ||
198 | void m_callback_read_receipt(void (*function)(int, uint32_t)); | ||
199 | |||
181 | /* run this at startup | 200 | /* run this at startup |
182 | returns 0 if no connection problems | 201 | returns 0 if no connection problems |
183 | returns -1 if there are problems */ | 202 | returns -1 if there are problems */ |