diff options
Diffstat (limited to 'core/Messenger.c')
-rw-r--r-- | core/Messenger.c | 172 |
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]; | |||
46 | static uint8_t self_name[MAX_NAME_LENGTH]; | 47 | static uint8_t self_name[MAX_NAME_LENGTH]; |
47 | static uint16_t self_name_length; | 48 | static uint16_t self_name_length; |
48 | 49 | ||
49 | static uint8_t *self_userstatus; | 50 | static uint8_t *self_statusmessage; |
50 | static uint16_t self_userstatus_len; | 51 | static uint16_t self_statusmessage_len; |
51 | static USERSTATUS_KIND self_userstatus_kind; | 52 | static 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 | ||
293 | int m_set_userstatus(USERSTATUS_KIND kind, uint8_t *status, uint16_t length) | 295 | int 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 | ||
312 | int m_set_userstatus_kind(USERSTATUS_KIND kind) { | 311 | int 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 */ |
328 | int m_get_userstatus_size(int friendnumber) | 325 | int 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 */ |
337 | int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen) | 334 | int 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 | ||
346 | int m_copy_self_userstatus(uint8_t * buf, uint32_t maxlen) | 343 | int 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 | ||
353 | USERSTATUS_KIND m_get_userstatus_kind(int friendnumber) { | 350 | USERSTATUS 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 | ||
363 | USERSTATUS_KIND m_get_self_userstatus_kind(void) { | 361 | USERSTATUS m_get_self_userstatus(void) |
364 | return self_userstatus_kind; | 362 | { |
363 | return self_userstatus; | ||
365 | } | 364 | } |
366 | 365 | ||
367 | static int send_userstatus(int friendnumber, uint8_t * status, uint16_t length) | 366 | static 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 | |||
376 | static 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 | ||
378 | static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t length) | 386 | static 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 | ||
390 | static void set_friend_userstatus_kind(int friendnumber, USERSTATUS_KIND k) | 398 | static 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 | ||
431 | static void (*friend_statuschange)(int, USERSTATUS_KIND, uint8_t *, uint16_t); | 439 | static void (*friend_statusmessagechange)(int, uint8_t *, uint16_t); |
432 | static uint8_t friend_statuschange_isset = 0; | 440 | static uint8_t friend_statusmessagechange_isset = 0; |
433 | void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uint16_t)) | 441 | void 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 | |||
447 | static void (*friend_userstatuschange)(int, USERSTATUS); | ||
448 | static uint8_t friend_userstatuschange_isset = 0; | ||
449 | void m_callback_userstatus(void (*function)(int, USERSTATUS)) | ||
450 | { | ||
451 | friend_userstatuschange = function; | ||
452 | friend_userstatuschange_isset = 1; | ||
437 | } | 453 | } |
438 | 454 | ||
439 | static void (*read_receipt)(int, uint32_t); | 455 | static void (*read_receipt)(int, uint32_t); |
@@ -449,7 +465,7 @@ void m_callback_read_receipt(void (*function)(int, uint32_t)) | |||
449 | int initMessenger(void) | 465 | int 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); |