summaryrefslogtreecommitdiff
path: root/core/Messenger.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-07-18 12:44:14 -0700
committerirungentoo <irungentoo@gmail.com>2013-07-18 12:44:14 -0700
commit8a71941423bf9a5e8ceb44a6e4c46688ab15bf8a (patch)
tree37b86e3d919f4436eaa42d70ad7a40068b6f285e /core/Messenger.c
parent7611ca810f9af9f0f534a85869cd36e35137ec6f (diff)
parenteb262207434443f7a5e4485c6c87c9999bffcd53 (diff)
Merge pull request #47 from stal888/master
Add custom user statuses to core, updated nTox to support nicknames and user statuses.
Diffstat (limited to 'core/Messenger.c')
-rw-r--r--core/Messenger.c149
1 files changed, 129 insertions, 20 deletions
diff --git a/core/Messenger.c b/core/Messenger.c
index 85b2ac5a..8e22f448 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -1,7 +1,7 @@
1/* Messenger.c 1/* Messenger.c
2* 2*
3* An implementation of a simple text chat only messenger on the tox network core. 3* An implementation of a simple text chat only messenger on the tox network core.
4* 4*
5 5
6 Copyright (C) 2013 Tox project All Rights Reserved. 6 Copyright (C) 2013 Tox project All Rights Reserved.
7 7
@@ -23,8 +23,7 @@
23*/ 23*/
24 24
25#include "Messenger.h" 25#include "Messenger.h"
26 26#define MIN(a,b) (((a)<(b))?(a):(b))
27#define MAX_NAME_LENGTH 128
28 27
29typedef struct 28typedef struct
30{ 29{
@@ -35,6 +34,9 @@ typedef struct
35 uint8_t info[MAX_DATA_SIZE]; //the data that is sent during the friend requests we do 34 uint8_t info[MAX_DATA_SIZE]; //the data that is sent during the friend requests we do
36 uint8_t name[MAX_NAME_LENGTH]; 35 uint8_t name[MAX_NAME_LENGTH];
37 uint8_t name_sent;//0 if we didn't send our name to this friend 1 if we have. 36 uint8_t name_sent;//0 if we didn't send our name to this friend 1 if we have.
37 uint8_t *userstatus;
38 uint16_t userstatus_length;
39 uint8_t userstatus_sent;
38 uint16_t info_size; //length of the info 40 uint16_t info_size; //length of the info
39}Friend; 41}Friend;
40 42
@@ -43,6 +45,8 @@ typedef struct
43uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 45uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
44 46
45static uint8_t self_name[MAX_NAME_LENGTH]; 47static uint8_t self_name[MAX_NAME_LENGTH];
48static uint8_t *self_userstatus;
49static uint16_t self_userstatus_len;
46 50
47#define MAX_NUM_FRIENDS 256 51#define MAX_NUM_FRIENDS 256
48 52
@@ -102,7 +106,7 @@ int getclient_id(int friend_id, uint8_t * client_id)
102//return -1 if failure. 106//return -1 if failure.
103int m_addfriend(uint8_t * client_id, uint8_t * data, uint16_t length) 107int m_addfriend(uint8_t * client_id, uint8_t * data, uint16_t length)
104{ 108{
105 if(length == 0 || length >= 109 if(length == 0 || length >=
106 (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES)) 110 (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES))
107 { 111 {
108 return -1; 112 return -1;
@@ -125,7 +129,8 @@ int m_addfriend(uint8_t * client_id, uint8_t * data, uint16_t length)
125 friendlist[i].crypt_connection_id = -1; 129 friendlist[i].crypt_connection_id = -1;
126 friendlist[i].friend_request_id = -1; 130 friendlist[i].friend_request_id = -1;
127 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); 131 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
128 132 friendlist[i].userstatus = calloc(1, 1);
133 friendlist[i].userstatus_length = 1;
129 memcpy(friendlist[i].info, data, length); 134 memcpy(friendlist[i].info, data, length);
130 friendlist[i].info_size = length; 135 friendlist[i].info_size = length;
131 136
@@ -152,6 +157,8 @@ int m_addfriend_norequest(uint8_t * client_id)
152 friendlist[i].crypt_connection_id = -1; 157 friendlist[i].crypt_connection_id = -1;
153 friendlist[i].friend_request_id = -1; 158 friendlist[i].friend_request_id = -1;
154 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); 159 memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
160 friendlist[i].userstatus = calloc(1, 1);
161 friendlist[i].userstatus_length = 1;
155 numfriends++; 162 numfriends++;
156 return i; 163 return i;
157 } 164 }
@@ -171,6 +178,7 @@ int m_delfriend(int friendnumber)
171 178
172 DHT_delfriend(friendlist[friendnumber].client_id); 179 DHT_delfriend(friendlist[friendnumber].client_id);
173 crypto_kill(friendlist[friendnumber].crypt_connection_id); 180 crypto_kill(friendlist[friendnumber].crypt_connection_id);
181 free(friendlist[friendnumber].userstatus);
174 memset(&friendlist[friendnumber], 0, sizeof(Friend)); 182 memset(&friendlist[friendnumber], 0, sizeof(Friend));
175 uint32_t i; 183 uint32_t i;
176 for(i = numfriends; i != 0; i--) 184 for(i = numfriends; i != 0; i--)
@@ -212,7 +220,7 @@ int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length)
212 if(length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4) 220 if(length >= MAX_DATA_SIZE || friendlist[friendnumber].status != 4)
213 //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.
214 { 222 {
215 return 0; 223 return 0;
216 } 224 }
217 uint8_t temp[MAX_DATA_SIZE]; 225 uint8_t temp[MAX_DATA_SIZE];
218 temp[0] = 64; 226 temp[0] = 64;
@@ -278,6 +286,74 @@ int getname(int friendnumber, uint8_t * name)
278 return 0; 286 return 0;
279} 287}
280 288
289int m_set_userstatus(uint8_t *status, uint16_t length)
290{
291 if(length > MAX_USERSTATUS_LENGTH)
292 {
293 return -1;
294 }
295 uint8_t *newstatus = calloc(length, 1);
296 memcpy(newstatus, status, length);
297 free(self_userstatus);
298 self_userstatus = newstatus;
299 self_userstatus_len = length;
300
301 uint32_t i;
302 for(i = 0; i < numfriends; i++)
303 {
304 friendlist[i].userstatus_sent = 0;
305 }
306 return 0;
307}
308
309// return the size of friendnumber's user status
310// guaranteed to be at most MAX_USERSTATUS_LENGTH
311int m_get_userstatus_size(int friendnumber)
312{
313 if(friendnumber >= numfriends || friendnumber < 0)
314 {
315 return -1;
316 }
317 return friendlist[friendnumber].userstatus_length;
318}
319
320// copy the user status of friendnumber into buf, truncating if needed to maxlen
321// bytes, use m_get_userstatus_size to find out how much you need to allocate
322int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen)
323{
324 if(friendnumber >= numfriends || friendnumber < 0)
325 {
326 return -1;
327 }
328 memset(buf, 0, maxlen);
329 memcpy(buf, friendlist[friendnumber].userstatus, MIN(maxlen, MAX_USERSTATUS_LENGTH) - 1);
330 return 0;
331}
332
333static int send_userstatus(int friendnumber, uint8_t * status, uint16_t length)
334{
335 uint8_t *thepacket = malloc(length + 1);
336 memcpy(thepacket + 1, status, length);
337 thepacket[0] = 70;
338 int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 1);
339 free(thepacket);
340 return written;
341}
342
343static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t length)
344{
345 if(friendnumber >= numfriends || friendnumber < 0)
346 {
347 return -1;
348 }
349 uint8_t *newstatus = calloc(length, 1);
350 memcpy(newstatus, status, length);
351 free(friendlist[friendnumber].userstatus);
352 friendlist[friendnumber].userstatus = newstatus;
353 friendlist[friendnumber].userstatus_length = length;
354 return 0;
355}
356
281static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); 357static void (*friend_request)(uint8_t *, uint8_t *, uint16_t);
282 358
283//set the function that will be executed when a friend request is received. 359//set the function that will be executed when a friend request is received.
@@ -296,11 +372,24 @@ void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t))
296} 372}
297 373
298 374
375static void (*friend_namechange)(int, uint8_t *, uint16_t);
376void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t))
377{
378 friend_namechange = function;
379}
380
381static void (*friend_statuschange)(int, uint8_t *, uint16_t);
382void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t))
383{
384 friend_statuschange = function;
385}
386
299#define PORT 33445 387#define PORT 33445
300//run this at startup 388//run this at startup
301void initMessenger() 389void initMessenger()
302{ 390{
303 new_keys(); 391 new_keys();
392 m_set_userstatus((uint8_t*)"Online", sizeof("Online"));
304 initNetCrypto(); 393 initNetCrypto();
305 IP ip; 394 IP ip;
306 ip.i = 0; 395 ip.i = 0;
@@ -321,7 +410,7 @@ static void doFriends()
321 //printf("\n%u %u %u\n", friendip.ip.i, request, friendlist[i].friend_request_id); 410 //printf("\n%u %u %u\n", friendip.ip.i, request, friendlist[i].friend_request_id);
322 if(friendip.ip.i > 1 && request == -1) 411 if(friendip.ip.i > 1 && request == -1)
323 { 412 {
324 friendlist[i].friend_request_id = send_friendrequest(friendlist[i].client_id, 413 friendlist[i].friend_request_id = send_friendrequest(friendlist[i].client_id,
325 friendip, friendlist[i].info, friendlist[i].info_size); 414 friendip, friendlist[i].info, friendlist[i].info_size);
326 friendlist[i].status = 2; 415 friendlist[i].status = 2;
327 } 416 }
@@ -356,19 +445,37 @@ static void doFriends()
356 friendlist[i].name_sent = 1; 445 friendlist[i].name_sent = 1;
357 } 446 }
358 } 447 }
448 if(friendlist[i].userstatus_sent == 0)
449 {
450 if(send_userstatus(i, self_userstatus, self_userstatus_len))
451 {
452 friendlist[i].userstatus_sent = 1;
453 }
454 }
359 len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); 455 len = read_cryptpacket(friendlist[i].crypt_connection_id, temp);
360 if(len > 0) 456 if(len > 0)
361 { 457 {
362 if(temp[0] == 48 && len == MAX_NAME_LENGTH + 1)//Username 458 switch(temp[0]) {
363 { 459 case 48: {
364 memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH); 460 if (len != MAX_NAME_LENGTH + 1) break;
365 friendlist[i].name[MAX_NAME_LENGTH - 1] = 0;//make sure the NULL terminator is present. 461 friend_namechange(i, temp + 1, MAX_NAME_LENGTH); // todo: use the actual length
366 } 462 memcpy(friendlist[i].name, temp + 1, MAX_NAME_LENGTH);
367 else 463 friendlist[i].name[MAX_NAME_LENGTH - 1] = 0;//make sure the NULL terminator is present.
368 if(temp[0] == 64)//Chat message 464 break;
369 { 465 }
370 (*friend_message)(i, temp + 1, len - 1); 466 case 64: {
371 } 467 (*friend_message)(i, temp + 1, len - 1);
468 break;
469 }
470 case 70: {
471 uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1);
472 memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH));
473 friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
474 set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
475 free(status);
476 break;
477 }
478 }
372 } 479 }
373 else 480 else
374 { 481 {
@@ -410,7 +517,7 @@ static void doInbound()
410 if(friend_id != -1) 517 if(friend_id != -1)
411 { 518 {
412 crypto_kill(friendlist[friend_id].crypt_connection_id); 519 crypto_kill(friendlist[friend_id].crypt_connection_id);
413 friendlist[friend_id].crypt_connection_id = 520 friendlist[friend_id].crypt_connection_id =
414 accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); 521 accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key);
415 522
416 friendlist[friend_id].status = 3; 523 friendlist[friend_id].status = 3;
@@ -520,7 +627,9 @@ int Messenger_load(uint8_t * data, uint32_t length)
520 uint32_t i; 627 uint32_t i;
521 for(i = 0; i < num; i++) 628 for(i = 0; i < num; i++)
522 { 629 {
523 setfriendname(m_addfriend_norequest(temp[i].client_id), temp[i].name); 630 int fnum = m_addfriend_norequest(temp[i].client_id);
631 setfriendname(fnum, temp[i].name);
632 set_friend_userstatus(fnum, temp[i].userstatus, temp[i].userstatus_length);
524 } 633 }
525 free(temp); 634 free(temp);
526 return 0; 635 return 0;