summaryrefslogtreecommitdiff
path: root/core/Messenger.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/Messenger.c')
-rw-r--r--core/Messenger.c172
1 files changed, 99 insertions, 73 deletions
diff --git a/core/Messenger.c b/core/Messenger.c
index b29bd1f1..3d991e63 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -32,10 +32,11 @@ typedef struct {
32 uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */ 32 uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */
33 uint8_t name[MAX_NAME_LENGTH]; 33 uint8_t name[MAX_NAME_LENGTH];
34 uint8_t name_sent; /* 0 if we didn't send our name to this friend 1 if we have. */ 34 uint8_t name_sent; /* 0 if we didn't send our name to this friend 1 if we have. */
35 uint8_t *userstatus; 35 uint8_t *statusmessage;
36 uint16_t userstatus_length; 36 uint16_t statusmessage_length;
37 uint8_t statusmessage_sent;
38 USERSTATUS userstatus;
37 uint8_t userstatus_sent; 39 uint8_t userstatus_sent;
38 USERSTATUS_KIND userstatus_kind;
39 uint16_t info_size; /* length of the info */ 40 uint16_t info_size; /* length of the info */
40 uint32_t message_id; /* a semi-unique id used in read receipts */ 41 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? */ 42 uint8_t receives_read_receipts; /* shall we send read receipts to this person? */
@@ -46,9 +47,9 @@ uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
46static uint8_t self_name[MAX_NAME_LENGTH]; 47static uint8_t self_name[MAX_NAME_LENGTH];
47static uint16_t self_name_length; 48static uint16_t self_name_length;
48 49
49static uint8_t *self_userstatus; 50static uint8_t *self_statusmessage;
50static uint16_t self_userstatus_len; 51static uint16_t self_statusmessage_len;
51static USERSTATUS_KIND self_userstatus_kind; 52static USERSTATUS self_userstatus;
52 53
53#define MAX_NUM_FRIENDS 256 54#define MAX_NUM_FRIENDS 256
54 55
@@ -125,9 +126,9 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
125 friendlist[i].crypt_connection_id = -1; 126 friendlist[i].crypt_connection_id = -1;
126 friendlist[i].friend_request_id = -1; 127 friendlist[i].friend_request_id = -1;
127 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); 128 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
128 friendlist[i].userstatus = calloc(1, 1); 129 friendlist[i].statusmessage = calloc(1, 1);
129 friendlist[i].userstatus_length = 1; 130 friendlist[i].statusmessage_length = 1;
130 friendlist[i].userstatus_kind = USERSTATUS_KIND_OFFLINE; 131 friendlist[i].userstatus = USERSTATUS_NONE;
131 memcpy(friendlist[i].info, data, length); 132 memcpy(friendlist[i].info, data, length);
132 friendlist[i].info_size = length; 133 friendlist[i].info_size = length;
133 friendlist[i].message_id = 0; 134 friendlist[i].message_id = 0;
@@ -152,8 +153,9 @@ int m_addfriend_norequest(uint8_t * client_id)
152 friendlist[i].crypt_connection_id = -1; 153 friendlist[i].crypt_connection_id = -1;
153 friendlist[i].friend_request_id = -1; 154 friendlist[i].friend_request_id = -1;
154 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); 155 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
155 friendlist[i].userstatus = calloc(1, 1); 156 friendlist[i].statusmessage = calloc(1, 1);
156 friendlist[i].userstatus_length = 1; 157 friendlist[i].statusmessage_length = 1;
158 friendlist[i].userstatus = USERSTATUS_NONE;
157 friendlist[i].message_id = 0; 159 friendlist[i].message_id = 0;
158 friendlist[i].receives_read_receipts = 1; /* default: YES */ 160 friendlist[i].receives_read_receipts = 1; /* default: YES */
159 numfriends++; 161 numfriends++;
@@ -173,7 +175,7 @@ int m_delfriend(int friendnumber)
173 175
174 DHT_delfriend(friendlist[friendnumber].client_id); 176 DHT_delfriend(friendlist[friendnumber].client_id);
175 crypto_kill(friendlist[friendnumber].crypt_connection_id); 177 crypto_kill(friendlist[friendnumber].crypt_connection_id);
176 free(friendlist[friendnumber].userstatus); 178 free(friendlist[friendnumber].statusmessage);
177 memset(&friendlist[friendnumber], 0, sizeof(Friend)); 179 memset(&friendlist[friendnumber], 0, sizeof(Friend));
178 uint32_t i; 180 uint32_t i;
179 181
@@ -290,33 +292,28 @@ int getname(int friendnumber, uint8_t * name)
290 return 0; 292 return 0;
291} 293}
292 294
293int m_set_userstatus(USERSTATUS_KIND kind, uint8_t *status, uint16_t length) 295int m_set_statusmessage(uint8_t *status, uint16_t length)
294{ 296{
295 if (length > MAX_USERSTATUS_LENGTH) 297 if (length > MAX_STATUSMESSAGE_LENGTH)
296 return -1; 298 return -1;
297 if (kind != USERSTATUS_KIND_RETAIN) {
298 self_userstatus_kind = kind;
299 }
300 uint8_t *newstatus = calloc(length, 1); 299 uint8_t *newstatus = calloc(length, 1);
301 memcpy(newstatus, status, length); 300 memcpy(newstatus, status, length);
302 free(self_userstatus); 301 free(self_statusmessage);
303 self_userstatus = newstatus; 302 self_statusmessage = newstatus;
304 self_userstatus_len = length; 303 self_statusmessage_len = length;
305 304
306 uint32_t i; 305 uint32_t i;
307 for (i = 0; i < numfriends; ++i) 306 for (i = 0; i < numfriends; ++i)
308 friendlist[i].userstatus_sent = 0; 307 friendlist[i].statusmessage_sent = 0;
309 return 0; 308 return 0;
310} 309}
311 310
312int m_set_userstatus_kind(USERSTATUS_KIND kind) { 311int m_set_userstatus(USERSTATUS status)
313 if (kind >= USERSTATUS_KIND_INVALID) { 312{
313 if (status >= USERSTATUS_INVALID) {
314 return -1; 314 return -1;
315 } 315 }
316 if (kind == USERSTATUS_KIND_RETAIN) { 316 self_userstatus = status;
317 return 0;
318 }
319 self_userstatus_kind = kind;
320 uint32_t i; 317 uint32_t i;
321 for (i = 0; i < numfriends; ++i) 318 for (i = 0; i < numfriends; ++i)
322 friendlist[i].userstatus_sent = 0; 319 friendlist[i].userstatus_sent = 0;
@@ -324,72 +321,83 @@ int m_set_userstatus_kind(USERSTATUS_KIND kind) {
324} 321}
325 322
326/* return the size of friendnumber's user status 323/* return the size of friendnumber's user status
327 guaranteed to be at most MAX_USERSTATUS_LENGTH */ 324 guaranteed to be at most MAX_STATUSMESSAGE_LENGTH */
328int m_get_userstatus_size(int friendnumber) 325int m_get_statusmessage_size(int friendnumber)
329{ 326{
330 if (friendnumber >= numfriends || friendnumber < 0) 327 if (friendnumber >= numfriends || friendnumber < 0)
331 return -1; 328 return -1;
332 return friendlist[friendnumber].userstatus_length; 329 return friendlist[friendnumber].statusmessage_length;
333} 330}
334 331
335/* copy the user status of friendnumber into buf, truncating if needed to maxlen 332/* copy the user status of friendnumber into buf, truncating if needed to maxlen
336 bytes, use m_get_userstatus_size to find out how much you need to allocate */ 333 bytes, use m_get_statusmessage_size to find out how much you need to allocate */
337int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen) 334int m_copy_statusmessage(int friendnumber, uint8_t * buf, uint32_t maxlen)
338{ 335{
339 if (friendnumber >= numfriends || friendnumber < 0) 336 if (friendnumber >= numfriends || friendnumber < 0)
340 return -1; 337 return -1;
341 memset(buf, 0, maxlen); 338 memset(buf, 0, maxlen);
342 memcpy(buf, friendlist[friendnumber].userstatus, MIN(maxlen, MAX_USERSTATUS_LENGTH) - 1); 339 memcpy(buf, friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
343 return 0; 340 return 0;
344} 341}
345 342
346int m_copy_self_userstatus(uint8_t * buf, uint32_t maxlen) 343int m_copy_self_statusmessage(uint8_t * buf, uint32_t maxlen)
347{ 344{
348 memset(buf, 0, maxlen); 345 memset(buf, 0, maxlen);
349 memcpy(buf, self_userstatus, MIN(maxlen, MAX_USERSTATUS_LENGTH) - 1); 346 memcpy(buf, self_statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
350 return 0; 347 return 0;
351} 348}
352 349
353USERSTATUS_KIND m_get_userstatus_kind(int friendnumber) { 350USERSTATUS m_get_userstatus(int friendnumber)
351{
354 if (friendnumber >= numfriends || friendnumber < 0) 352 if (friendnumber >= numfriends || friendnumber < 0)
355 return USERSTATUS_KIND_INVALID; 353 return USERSTATUS_INVALID;
356 USERSTATUS_KIND uk = friendlist[friendnumber].userstatus_kind; 354 USERSTATUS status = friendlist[friendnumber].userstatus;
357 if (uk >= USERSTATUS_KIND_INVALID) { 355 if (status >= USERSTATUS_INVALID) {
358 uk = USERSTATUS_KIND_ONLINE; 356 status = USERSTATUS_NONE;
359 } 357 }
360 return uk; 358 return status;
361} 359}
362 360
363USERSTATUS_KIND m_get_self_userstatus_kind(void) { 361USERSTATUS m_get_self_userstatus(void)
364 return self_userstatus_kind; 362{
363 return self_userstatus;
365} 364}
366 365
367static int send_userstatus(int friendnumber, uint8_t * status, uint16_t length) 366static int send_statusmessage(int friendnumber, uint8_t * status, uint16_t length)
368{ 367{
369 uint8_t *thepacket = malloc(length + 2); 368 uint8_t *thepacket = malloc(length + 1);
370 memcpy(thepacket + 2, status, length); 369 memcpy(thepacket + 1, status, length);
370 thepacket[0] = PACKET_ID_STATUSMESSAGE;
371 int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 1);
372 free(thepacket);
373 return written;
374}
375
376static int send_userstatus(int friendnumber, USERSTATUS status)
377{
378 uint8_t *thepacket = malloc(1 + 1);
379 memcpy(thepacket + 1, &status, 1);
371 thepacket[0] = PACKET_ID_USERSTATUS; 380 thepacket[0] = PACKET_ID_USERSTATUS;
372 thepacket[1] = self_userstatus_kind; 381 int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, 1 + 1);
373 int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 2);
374 free(thepacket); 382 free(thepacket);
375 return written; 383 return written;
376} 384}
377 385
378static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t length) 386static int set_friend_statusmessage(int friendnumber, uint8_t * status, uint16_t length)
379{ 387{
380 if (friendnumber >= numfriends || friendnumber < 0) 388 if (friendnumber >= numfriends || friendnumber < 0)
381 return -1; 389 return -1;
382 uint8_t *newstatus = calloc(length, 1); 390 uint8_t *newstatus = calloc(length, 1);
383 memcpy(newstatus, status, length); 391 memcpy(newstatus, status, length);
384 free(friendlist[friendnumber].userstatus); 392 free(friendlist[friendnumber].statusmessage);
385 friendlist[friendnumber].userstatus = newstatus; 393 friendlist[friendnumber].statusmessage = newstatus;
386 friendlist[friendnumber].userstatus_length = length; 394 friendlist[friendnumber].statusmessage_length = length;
387 return 0; 395 return 0;
388} 396}
389 397
390static void set_friend_userstatus_kind(int friendnumber, USERSTATUS_KIND k) 398static void set_friend_userstatus(int friendnumber, USERSTATUS status)
391{ 399{
392 friendlist[friendnumber].userstatus_kind = k; 400 friendlist[friendnumber].userstatus = status;
393} 401}
394 402
395/* Sets whether we send read receipts for friendnumber. */ 403/* Sets whether we send read receipts for friendnumber. */
@@ -428,12 +436,20 @@ void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t))
428 friend_namechange_isset = 1; 436 friend_namechange_isset = 1;
429} 437}
430 438
431static void (*friend_statuschange)(int, USERSTATUS_KIND, uint8_t *, uint16_t); 439static void (*friend_statusmessagechange)(int, uint8_t *, uint16_t);
432static uint8_t friend_statuschange_isset = 0; 440static uint8_t friend_statusmessagechange_isset = 0;
433void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uint16_t)) 441void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t))
434{ 442{
435 friend_statuschange = function; 443 friend_statusmessagechange = function;
436 friend_statuschange_isset = 1; 444 friend_statusmessagechange_isset = 1;
445}
446
447static void (*friend_userstatuschange)(int, USERSTATUS);
448static uint8_t friend_userstatuschange_isset = 0;
449void m_callback_userstatus(void (*function)(int, USERSTATUS))
450{
451 friend_userstatuschange = function;
452 friend_userstatuschange_isset = 1;
437} 453}
438 454
439static void (*read_receipt)(int, uint32_t); 455static void (*read_receipt)(int, uint32_t);
@@ -449,7 +465,7 @@ void m_callback_read_receipt(void (*function)(int, uint32_t))
449int initMessenger(void) 465int initMessenger(void)
450{ 466{
451 new_keys(); 467 new_keys();
452 m_set_userstatus(USERSTATUS_KIND_ONLINE, (uint8_t*)"Online", sizeof("Online")); 468 m_set_statusmessage((uint8_t*)"Online", sizeof("Online"));
453 initNetCrypto(); 469 initNetCrypto();
454 IP ip; 470 IP ip;
455 ip.i = 0; 471 ip.i = 0;
@@ -504,8 +520,12 @@ static void doFriends(void)
504 if (m_sendname(i, self_name, self_name_length)) 520 if (m_sendname(i, self_name, self_name_length))
505 friendlist[i].name_sent = 1; 521 friendlist[i].name_sent = 1;
506 } 522 }
523 if (friendlist[i].statusmessage_sent == 0) {
524 if (send_statusmessage(i, self_statusmessage, self_statusmessage_len))
525 friendlist[i].statusmessage_sent = 1;
526 }
507 if (friendlist[i].userstatus_sent == 0) { 527 if (friendlist[i].userstatus_sent == 0) {
508 if (send_userstatus(i, self_userstatus, self_userstatus_len)) 528 if (send_userstatus(i, self_userstatus))
509 friendlist[i].userstatus_sent = 1; 529 friendlist[i].userstatus_sent = 1;
510 } 530 }
511 len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); 531 len = read_cryptpacket(friendlist[i].crypt_connection_id, temp);
@@ -520,18 +540,24 @@ static void doFriends(void)
520 friendlist[i].name[len - 2] = 0; /* make sure the NULL terminator is present. */ 540 friendlist[i].name[len - 2] = 0; /* make sure the NULL terminator is present. */
521 break; 541 break;
522 } 542 }
543 case PACKET_ID_STATUSMESSAGE: {
544 if (len < 2)
545 break;
546 uint8_t *status = calloc(MIN(len - 1, MAX_STATUSMESSAGE_LENGTH), 1);
547 memcpy(status, temp + 1, MIN(len - 1, MAX_STATUSMESSAGE_LENGTH));
548 if (friend_statusmessagechange_isset)
549 friend_statusmessagechange(i, status, MIN(len - 1, MAX_STATUSMESSAGE_LENGTH));
550 set_friend_statusmessage(i, status, MIN(len - 1, MAX_STATUSMESSAGE_LENGTH));
551 free(status);
552 break;
553 }
523 case PACKET_ID_USERSTATUS: { 554 case PACKET_ID_USERSTATUS: {
524 if (len > 2) { 555 if (len != 2)
525 uint8_t *status = calloc(MIN(len - 2, MAX_USERSTATUS_LENGTH), 1); 556 break;
526 memcpy(status, temp + 2, MIN(len - 2, MAX_USERSTATUS_LENGTH)); 557 USERSTATUS status = temp[1];
527 if (friend_statuschange_isset) 558 if (friend_userstatuschange_isset)
528 friend_statuschange(i, temp[1], status, MIN(len - 2, MAX_USERSTATUS_LENGTH)); 559 friend_userstatuschange(i, status);
529 set_friend_userstatus(i, status, MIN(len - 2, MAX_USERSTATUS_LENGTH)); 560 set_friend_userstatus(i, status);
530 free(status);
531 } else if (friend_statuschange_isset) {
532 friend_statuschange(i, temp[1], friendlist[i].userstatus, friendlist[i].userstatus_length);
533 }
534 set_friend_userstatus_kind(i, temp[1]);
535 break; 561 break;
536 } 562 }
537 case PACKET_ID_MESSAGE: { 563 case PACKET_ID_MESSAGE: {
@@ -694,7 +720,7 @@ int Messenger_load(uint8_t * data, uint32_t length)
694 if(temp[i].status != 0) { 720 if(temp[i].status != 0) {
695 int fnum = m_addfriend_norequest(temp[i].client_id); 721 int fnum = m_addfriend_norequest(temp[i].client_id);
696 setfriendname(fnum, temp[i].name); 722 setfriendname(fnum, temp[i].name);
697 /* set_friend_userstatus(fnum, temp[i].userstatus, temp[i].userstatus_length); */ 723 /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */
698 } 724 }
699 } 725 }
700 free(temp); 726 free(temp);