summaryrefslogtreecommitdiff
path: root/toxav/msi.c
diff options
context:
space:
mode:
authormannol <eniz_vukovic@hotmail.com>2014-04-27 19:21:26 +0200
committermannol <eniz_vukovic@hotmail.com>2014-04-27 19:21:26 +0200
commit42b25a4d3e2fe66f03cbd8c866d8af7bd4f6e5a7 (patch)
tree161a21847a79f7fe052a9e9ad1b9b802d04defc6 /toxav/msi.c
parent736f5f80347a39f6b82cda8a4ddc1f7d88fcc2f5 (diff)
Yeah many calls
Diffstat (limited to 'toxav/msi.c')
-rwxr-xr-xtoxav/msi.c708
1 files changed, 466 insertions, 242 deletions
diff --git a/toxav/msi.c b/toxav/msi.c
index 26e301d3..ae6fcf84 100755
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -26,7 +26,9 @@
26#include "config.h" 26#include "config.h"
27#endif /* HAVE_CONFIG_H */ 27#endif /* HAVE_CONFIG_H */
28 28
29#define _BSD_SOURCE 29#include "../toxcore/logger.h"
30
31/*#define _BSD_SOURCE*/
30 32
31#include "msi.h" 33#include "msi.h"
32#include "event.h" 34#include "event.h"
@@ -120,10 +122,13 @@ static struct _Callbacks {
120 void* data; 122 void* data;
121} callbacks[11] = {0}; 123} callbacks[11] = {0};
122 124
123inline__ void invoke_callback(MSICallbackID id) 125inline__ void invoke_callback(uint32_t call_index, MSICallbackID id)
124{ 126{
125 /*if ( callbacks[id].function ) event.rise ( callbacks[id].function, callbacks[id].data );*/ 127 /*if ( callbacks[id].function ) event.rise ( callbacks[id].function, callbacks[id].data );*/
126 if ( callbacks[id].function ) callbacks[id].function ( callbacks[id].data ); 128 if ( callbacks[id].function ) {
129 LOGGER_DEBUG("Invoking callback function: %d", id);
130 callbacks[id].function ( call_index, callbacks[id].data );
131 }
127} 132}
128 133
129/*static MSICallback callbacks[10] = {0};*/ 134/*static MSICallback callbacks[10] = {0};*/
@@ -230,7 +235,9 @@ static inline__ const uint8_t *stringify_response ( MSIResponse response )
230 */ 235 */
231int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length ) 236int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length )
232{ 237{
233 assert ( msg ); 238 if ( msg == NULL ) {
239 LOGGER_ERROR("Could not parse message: no storage!");
240 }
234 241
235 if ( data[length - 1] ) /* End byte must have value 0 */ 242 if ( data[length - 1] ) /* End byte must have value 0 */
236 return -1; 243 return -1;
@@ -271,7 +278,7 @@ int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length )
271 if ON_HEADER ( _it, msg->version, VERSION_FIELD, 7 ) 278 if ON_HEADER ( _it, msg->version, VERSION_FIELD, 7 )
272 else if ON_HEADER ( _it, msg->request, REQUEST_FIELD, 7 ) 279 else if ON_HEADER ( _it, msg->request, REQUEST_FIELD, 7 )
273 else if ON_HEADER ( _it, msg->callid, CALLID_FIELD, 7 ) 280 else if ON_HEADER ( _it, msg->callid, CALLID_FIELD, 7 )
274 } 281 }
275 break; 282 break;
276 283
277 case 8: { /* Response header */ 284 case 8: { /* Response header */
@@ -290,9 +297,13 @@ int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length )
290 break; 297 break;
291 298
292 default: 299 default:
300 LOGGER_ERROR("Unkown field value");
293 return -1; 301 return -1;
294 } 302 }
295 } else return -1; 303 } else {
304 LOGGER_ERROR("Invalid field byte or field size too large");
305 return -1;
306 }
296 307
297 /* If it's anything else return failure as the message is invalid */ 308 /* If it's anything else return failure as the message is invalid */
298 309
@@ -304,8 +315,9 @@ int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length )
304 315
305#define ALLOCATE_HEADER( var, mheader_value, t_size) \ 316#define ALLOCATE_HEADER( var, mheader_value, t_size) \
306var.header_value = calloc(sizeof *mheader_value, t_size); \ 317var.header_value = calloc(sizeof *mheader_value, t_size); \
307memcpy(var.header_value, mheader_value, t_size); \ 318if (var.header_value == NULL) { LOGGER_WARNING("Header allocation failed!"); } \
308var.size = t_size; 319else { memcpy(var.header_value, mheader_value, t_size); \
320var.size = t_size; }
309 321
310 322
311/** 323/**
@@ -316,7 +328,9 @@ var.size = t_size;
316 */ 328 */
317void free_message ( MSIMessage *msg ) 329void free_message ( MSIMessage *msg )
318{ 330{
319 assert ( msg ); 331 if ( msg == NULL ) {
332 LOGGER_ERROR("Tried to free empty message");
333 }
320 334
321 free ( msg->calltype.header_value ); 335 free ( msg->calltype.header_value );
322 free ( msg->request.header_value ); 336 free ( msg->request.header_value );
@@ -343,7 +357,11 @@ void free_message ( MSIMessage *msg )
343MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id ) 357MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id )
344{ 358{
345 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 ); 359 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 );
346 assert ( _retu ); 360
361 if ( _retu == NULL ) {
362 LOGGER_WARNING("Allocation failed!");
363 return NULL;
364 }
347 365
348 if ( type == TYPE_REQUEST ) { 366 if ( type == TYPE_REQUEST ) {
349 ALLOCATE_HEADER ( _retu->request, type_id, strlen ( (const char *)type_id ) ) 367 ALLOCATE_HEADER ( _retu->request, type_id, strlen ( (const char *)type_id ) )
@@ -371,10 +389,17 @@ MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id )
371 */ 389 */
372MSIMessage *parse_message ( const uint8_t *data, uint16_t length ) 390MSIMessage *parse_message ( const uint8_t *data, uint16_t length )
373{ 391{
374 assert ( data ); 392 if ( data == NULL ) {
393 LOGGER_WARNING("Tried to parse empty message!");
394 return NULL;
395 }
375 396
376 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 ); 397 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 );
377 assert ( _retu ); 398
399 if ( _retu == NULL ) {
400 LOGGER_WARNING("Allocation failed!");
401 return NULL;
402 }
378 403
379 memset ( _retu, 0, sizeof ( MSIMessage ) ); 404 memset ( _retu, 0, sizeof ( MSIMessage ) );
380 405
@@ -397,6 +422,42 @@ MSIMessage *parse_message ( const uint8_t *data, uint16_t length )
397 422
398 423
399/** 424/**
425 * @brief Makes clear message presentation
426 *
427 * @param msg Message
428 * @param dest Dest string
429 * @return int
430 */
431int stringify_message(MSIMessage* msg, char* dest)
432{
433 #define HDR_TO_STR(__dest, __hdr) if (__hdr.header_value) {\
434 char nltstr[MSI_MAXMSG_SIZE]; memset(nltstr, '\0', MSI_MAXMSG_SIZE); int i = 0; \
435 for ( ; i < __hdr.size; i ++) nltstr[i] = (char)__hdr.header_value[i]; \
436 }
437
438 if ( !msg || !dest )
439 return -1;
440
441 HDR_TO_STR(dest, msg->version);
442 HDR_TO_STR(dest, msg->request);
443 HDR_TO_STR(dest, msg->response);
444 HDR_TO_STR(dest, msg->reason);
445 HDR_TO_STR(dest, msg->callid);
446 HDR_TO_STR(dest, msg->calltype);
447 HDR_TO_STR(dest, msg->cryptokey);
448 HDR_TO_STR(dest, msg->nonce);
449
450// if (msg->version.header_value) {
451// U8_TO_NLTCHAR(msg->version.header_value, msg->version.size, nltstr, MSI_MAXMSG_SIZE);
452// sprintf(dest, "Version: %s\n", nltstr);
453// }
454
455 return 0;
456}
457
458
459
460/**
400 * @brief Speaks for it self. 461 * @brief Speaks for it self.
401 * 462 *
402 * @param dest Container. 463 * @param dest Container.
@@ -413,10 +474,20 @@ uint8_t *append_header_to_string (
413 uint16_t value_len, 474 uint16_t value_len,
414 uint16_t *length ) 475 uint16_t *length )
415{ 476{
416 assert ( dest ); 477 if ( dest == NULL ) {
417 assert ( header_value ); 478 LOGGER_ERROR("No destination space!");
418 assert ( header_field ); 479 assert(dest);
419 480 }
481 if (header_value == NULL) {
482 LOGGER_ERROR("Empty header value");
483 return NULL;
484 }
485 if ( header_field == NULL ) {
486 LOGGER_ERROR("Empty header field");
487 return NULL;
488 }
489
490
420 const uint8_t *_hvit = header_value; 491 const uint8_t *_hvit = header_value;
421 uint16_t _total = 6 + value_len; /* 6 is known plus header value len + field len*/ 492 uint16_t _total = 6 + value_len; /* 6 is known plus header value len + field len*/
422 493
@@ -477,10 +548,16 @@ if ( header.header_value ) { var = append_header_to_string(var, (const uint8_t*)
477 * @param dest Destination. 548 * @param dest Destination.
478 * @return uint16_t It's final size. 549 * @return uint16_t It's final size.
479 */ 550 */
480uint16_t message_to_string ( MSIMessage *msg, uint8_t *dest ) 551uint16_t message_to_send ( MSIMessage *msg, uint8_t *dest )
481{ 552{
482 assert ( msg ); 553 if (msg == NULL) {
483 assert ( dest ); 554 LOGGER_ERROR("Empty message!");
555 return 0;
556 }
557 if (dest == NULL ) {
558 LOGGER_ERROR("Empty destination!");
559 return 0;
560 }
484 561
485 uint8_t *_iterated = dest; 562 uint8_t *_iterated = dest;
486 uint16_t _size = 0; 563 uint16_t _size = 0;
@@ -525,7 +602,10 @@ GENERIC_SETTER_DEFINITION ( nonce )
525 */ 602 */
526void t_randomstr ( uint8_t *str, size_t size ) 603void t_randomstr ( uint8_t *str, size_t size )
527{ 604{
528 assert ( str ); 605 if (str == NULL) {
606 LOGGER_DEBUG("Empty destination!");
607 return;
608 }
529 609
530 static const uint8_t _bytes[] = 610 static const uint8_t _bytes[] =
531 "0123456789" 611 "0123456789"
@@ -607,14 +687,32 @@ static inline__ const uint8_t *stringify_error_code ( MSICallError error_code )
607 * @retval -1 Error occured. 687 * @retval -1 Error occured.
608 * @retval 0 Success. 688 * @retval 0 Success.
609 */ 689 */
610int send_message ( MSISession *session, MSIMessage *msg, uint32_t to ) 690int send_message ( MSISession *session, MSICall* call, MSIMessage *msg, uint32_t to )
611{ 691{
612 msi_msg_set_callid ( msg, session->call->id, CALL_ID_LEN ); 692 msi_msg_set_callid ( msg, call->id, CALL_ID_LEN );
613 693
614 uint8_t _msg_string_final [MSI_MAXMSG_SIZE]; 694 uint8_t _msg_string_final [MSI_MAXMSG_SIZE];
615 uint16_t _length = message_to_string ( msg, _msg_string_final ); 695 uint16_t _length = message_to_send ( msg, _msg_string_final );
616 696
617 return m_msi_packet(session->messenger_handle, to, _msg_string_final, _length) ? 0 : -1; 697 if (!_length) {
698 LOGGER_WARNING("Parsing message failed; nothing sent!");
699 return -1;
700 }
701
702 /*
703 LOGGER_SCOPE(
704 char cast[MSI_MAXMSG_SIZE];
705 stringify_message(msg, cast);
706 LOGGER_DEBUG("[Call: %s] [to: %u] Sending message: len: %d\n%s", call->id, to, _length, cast);
707 );*/
708
709
710 if ( m_msi_packet(session->messenger_handle, to, _msg_string_final, _length) ) {
711 LOGGER_DEBUG("Sent message");
712 return 0;
713 }
714
715 return -1;
618} 716}
619 717
620 718
@@ -646,7 +744,7 @@ int call_id_bigger( const uint8_t* first, const uint8_t* second)
646 * @param peer_id The peer. 744 * @param peer_id The peer.
647 * @return void 745 * @return void
648 */ 746 */
649void flush_peer_type ( MSISession *session, MSIMessage *msg, int peer_id ) 747void flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id )
650{ 748{
651 if ( msg->calltype.header_value ) { 749 if ( msg->calltype.header_value ) {
652 uint8_t hdrval [MSI_MAXMSG_SIZE]; /* Make sure no overflow */ 750 uint8_t hdrval [MSI_MAXMSG_SIZE]; /* Make sure no overflow */
@@ -655,10 +753,10 @@ void flush_peer_type ( MSISession *session, MSIMessage *msg, int peer_id )
655 hdrval[msg->calltype.size] = '\0'; 753 hdrval[msg->calltype.size] = '\0';
656 754
657 if ( strcmp ( ( const char * ) hdrval, CT_AUDIO_HEADER_VALUE ) == 0 ) { 755 if ( strcmp ( ( const char * ) hdrval, CT_AUDIO_HEADER_VALUE ) == 0 ) {
658 session->call->type_peer[peer_id] = type_audio; 756 call->type_peer[peer_id] = type_audio;
659 757
660 } else if ( strcmp ( ( const char * ) hdrval, CT_VIDEO_HEADER_VALUE ) == 0 ) { 758 } else if ( strcmp ( ( const char * ) hdrval, CT_VIDEO_HEADER_VALUE ) == 0 ) {
661 session->call->type_peer[peer_id] = type_video; 759 call->type_peer[peer_id] = type_video;
662 } else {} /* Error */ 760 } else {} /* Error */
663 } else {} /* Error */ 761 } else {} /* Error */
664} 762}
@@ -669,13 +767,17 @@ void handle_remote_connection_change(Messenger *messenger, int friend_num, uint8
669 767
670 switch ( status ) { 768 switch ( status ) {
671 case 0: { /* Went offline */ 769 case 0: { /* Went offline */
672 if ( session->call ) { 770 uint32_t j =0;
771 for ( ; j < session->max_calls; j ++ ) {
772
773 if ( !session->calls[j] ) continue;
774
673 int i = 0; 775 int i = 0;
674 776 for ( ; i < session->calls[j]->peer_count; i ++ )
675 for ( ; i < session->call->peer_count; i ++ ) 777 if ( session->calls[j]->peers[i] == friend_num ) {
676 if ( session->call->peers[i] == friend_num ) { 778 invoke_callback(j, MSI_OnPeerTimeout);
677 invoke_callback(MSI_OnPeerTimeout); 779 LOGGER_DEBUG("Remote: %d timed out!", friend_num);
678 return; 780 return; /* TODO: On group calls change behaviour */
679 } 781 }
680 } 782 }
681 } 783 }
@@ -686,6 +788,18 @@ void handle_remote_connection_change(Messenger *messenger, int friend_num, uint8
686 } 788 }
687} 789}
688 790
791MSICall* find_call ( MSISession* session, uint8_t* call_id )
792{
793 if ( call_id == NULL ) return NULL;
794
795 uint32_t i = 0;
796 for (; i < session->max_calls; i ++ )
797 if ( session->calls[i] && memcmp(session->calls[i]->id, call_id, CALL_ID_LEN) == 0 )
798 return session->calls[i];
799
800 return NULL;
801}
802
689/** 803/**
690 * @brief Sends error response to peer. 804 * @brief Sends error response to peer.
691 * 805 *
@@ -695,20 +809,22 @@ void handle_remote_connection_change(Messenger *messenger, int friend_num, uint8
695 * @return int 809 * @return int
696 * @retval 0 It's always success. 810 * @retval 0 It's always success.
697 */ 811 */
698int handle_error ( MSISession *session, MSICallError errid, uint32_t to ) 812int handle_error ( MSISession *session, MSICall* call, MSICallError errid, uint32_t to )
699{ 813{
814 LOGGER_DEBUG("Sending error: %d on call: %s", errid, call->id);
815
700 MSIMessage *_msg_error = msi_new_message ( TYPE_RESPONSE, stringify_response ( error ) ); 816 MSIMessage *_msg_error = msi_new_message ( TYPE_RESPONSE, stringify_response ( error ) );
701 817
702 const uint8_t *_error_code_str = stringify_error_code ( errid ); 818 const uint8_t *_error_code_str = stringify_error_code ( errid );
703 819
704 msi_msg_set_reason ( _msg_error, _error_code_str, strlen ( ( const char * ) _error_code_str ) ); 820 msi_msg_set_reason ( _msg_error, _error_code_str, strlen ( ( const char * ) _error_code_str ) );
705 send_message ( session, _msg_error, to ); 821 send_message ( session, call, _msg_error, to );
706 free_message ( _msg_error ); 822 free_message ( _msg_error );
707 823
708 session->last_error_id = errid; 824 session->last_error_id = errid;
709 session->last_error_str = stringify_error ( errid ); 825 session->last_error_str = stringify_error ( errid );
710 826
711 invoke_callback(MSI_OnError); 827 invoke_callback(call->call_idx, MSI_OnError);
712 828
713 return 0; 829 return 0;
714} 830}
@@ -723,16 +839,16 @@ int handle_error ( MSISession *session, MSICallError errid, uint32_t to )
723 * @retval -1 No error. 839 * @retval -1 No error.
724 * @retval 0 Error occured and response sent. 840 * @retval 0 Error occured and response sent.
725 */ 841 */
726int has_call_error ( MSISession *session, MSIMessage *msg ) 842int has_call_error ( MSISession *session, MSICall* call, MSIMessage *msg )
727{ 843{
728 if ( !msg->callid.header_value ) { 844 if ( !msg->callid.header_value ) {
729 return handle_error ( session, error_no_callid, msg->friend_id ); 845 return handle_error ( session, call, error_no_callid, msg->friend_id );
730 846
731 } else if ( !session->call ) { 847 } else if ( !call ) {
732 return handle_error ( session, error_no_call, msg->friend_id ); 848 return handle_error ( session, call, error_no_call, msg->friend_id );
733 849
734 } else if ( memcmp ( session->call->id, msg->callid.header_value, CALL_ID_LEN ) != 0 ) { 850 } else if ( memcmp ( call->id, msg->callid.header_value, CALL_ID_LEN ) != 0 ) {
735 return handle_error ( session, error_id_mismatch, msg->friend_id ); 851 return handle_error ( session, call, error_id_mismatch, msg->friend_id );
736 852
737 } 853 }
738 854
@@ -741,7 +857,7 @@ int has_call_error ( MSISession *session, MSIMessage *msg )
741 857
742 858
743/** 859/**
744 * @brief Function called at request timeout. 860 * @brief Function called at request timeout. If not called in thread it might cause trouble
745 * 861 *
746 * @param arg Control session 862 * @param arg Control session
747 * @return void* 863 * @return void*
@@ -752,16 +868,18 @@ void *handle_timeout ( void *arg )
752 * timers on these cancels and terminate call on 868 * timers on these cancels and terminate call on
753 * their timeout 869 * their timeout
754 */ 870 */
755 MSISession *_session = arg; 871 MSICall *_call = arg;
756 872
757 invoke_callback(MSI_OnRequestTimeout); 873 LOGGER_DEBUG("[Call: %s] Request timed out!", _call->id);
874
875 invoke_callback(_call->call_idx, MSI_OnRequestTimeout);
758 876
759 if ( _session && _session->call ) { 877 if ( _call && _call->session ) {
760 878
761 /* TODO: Cancel all? */ 879 /* TODO: Cancel all? */
762 /* uint16_t _it = 0; 880 /* uint16_t _it = 0;
763 for ( ; _it < _session->call->peer_count; _it++ ) */ 881 for ( ; _it < _session->call->peer_count; _it++ ) */
764 msi_cancel ( _session, _session->call->peers [0], "Request timedout" ); 882 msi_cancel ( _call->session, _call->call_idx, _call->peers [0], "Request timed out" );
765 } 883 }
766 884
767 pthread_exit(NULL); 885 pthread_exit(NULL);
@@ -798,14 +916,41 @@ void add_peer( MSICall *call, int peer_id )
798 */ 916 */
799MSICall *init_call ( MSISession *session, int peers, int ringing_timeout ) 917MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
800{ 918{
801 assert ( session ); 919
802 assert ( peers ); 920 if (peers == 0) {
921 LOGGER_ERROR("No peers!");
922 return NULL;
923 }
924
925 uint32_t _call_idx = 0;
926 for (; _call_idx < session->max_calls; _call_idx ++) {
927 if ( !session->calls[_call_idx] ) {
928 session->calls[_call_idx] = calloc ( sizeof ( MSICall ), 1 );
929 break;
930 }
931 }
932
933 if ( _call_idx == session->max_calls ) {
934 LOGGER_WARNING("Reached maximum amount of calls!");
935 }
936
803 937
804 MSICall *_call = calloc ( sizeof ( MSICall ), 1 ); 938 MSICall *_call = session->calls[_call_idx];
939 _call->call_idx = _call_idx;
940
941 if ( _call == NULL ) {
942 LOGGER_WARNING("Allocation failed!");
943 return NULL;
944 }
945
805 _call->type_peer = calloc ( sizeof ( MSICallType ), peers ); 946 _call->type_peer = calloc ( sizeof ( MSICallType ), peers );
806 947
807 assert ( _call ); 948 if ( _call->type_peer == NULL ) {
808 assert ( _call->type_peer ); 949 LOGGER_WARNING("Allocation failed!");
950 return NULL;
951 }
952
953 _call->session = session;
809 954
810 /*_call->_participant_count = _peers;*/ 955 /*_call->_participant_count = _peers;*/
811 956
@@ -821,6 +966,7 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
821 966
822 pthread_mutex_init ( &_call->mutex, NULL ); 967 pthread_mutex_init ( &_call->mutex, NULL );
823 968
969 LOGGER_DEBUG("Started new call with index: %u", _call_idx);
824 return _call; 970 return _call;
825} 971}
826 972
@@ -833,51 +979,48 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
833 * @retval -1 Error occured. 979 * @retval -1 Error occured.
834 * @retval 0 Success. 980 * @retval 0 Success.
835 */ 981 */
836int terminate_call ( MSISession *session ) 982int terminate_call ( MSISession *session, MSICall *call )
837{ 983{
838 assert ( session ); 984 if ( !call ) {
839 985 LOGGER_WARNING("Tried to terminate non-existing call!");
840 if ( !session->call )
841 return -1; 986 return -1;
842 987 }
843 988
844 /* Check event loop and cancel timed events if there are any 989 /* Check event loop and cancel timed events if there are any
845 * NOTE: This has to be done before possibly 990 * NOTE: This has to be done before possibly
846 * locking the mutex the second time 991 * locking the mutex the second time
847 */ 992 */
848 event.timer_release ( session->call->request_timer_id ); 993 event.timer_release ( call->request_timer_id );
849 event.timer_release ( session->call->ringing_timer_id ); 994 event.timer_release ( call->ringing_timer_id );
850 995
851 /* Get a handle */ 996 /* Get a handle */
852 pthread_mutex_lock ( &session->call->mutex ); 997 pthread_mutex_lock ( &call->mutex );
853 998
854 MSICall *_call = session->call; 999 session->calls[call->call_idx]= NULL;
855 session->call = NULL;
856 1000
857 free ( _call->type_peer ); 1001 free ( call->type_peer );
858 free ( _call->key_local ); 1002 free ( call->key_local );
859 free ( _call->key_peer ); 1003 free ( call->key_peer );
860 free ( _call->peers); 1004 free ( call->peers);
861 1005
862 /* Release handle */ 1006 /* Release handle */
863 pthread_mutex_unlock ( &_call->mutex ); 1007 pthread_mutex_unlock ( &call->mutex );
864 1008
865 pthread_mutex_destroy ( &_call->mutex ); 1009 pthread_mutex_destroy ( &call->mutex );
866 1010
867 free ( _call ); 1011 free ( call );
868 1012
869 return 0; 1013 return 0;
870} 1014}
871 1015
872 1016
873/********** Request handlers **********/ 1017/********** Request handlers **********/
874int handle_recv_invite ( MSISession *session, MSIMessage *msg ) 1018int handle_recv_invite ( MSISession *session, MSICall* call, MSIMessage *msg )
875{ 1019{
876 assert ( session ); 1020 LOGGER_DEBUG("Handling 'invite' on call: %s", call? (char*)call->id : "making new");
877
878 1021
879 if ( session->call ) { 1022 if ( call ) {
880 if ( session->call->peers[0] == msg->friend_id ) { 1023 if ( call->peers[0] == msg->friend_id ) {
881 /* The glare case. A calls B when at the same time 1024 /* The glare case. A calls B when at the same time
882 * B calls A. Who has advantage is set bey calculating 1025 * B calls A. Who has advantage is set bey calculating
883 * 'bigger' Call id and then that call id is being used in 1026 * 'bigger' Call id and then that call id is being used in
@@ -885,8 +1028,8 @@ int handle_recv_invite ( MSISession *session, MSIMessage *msg )
885 * as in he will wait the reponse from the other. 1028 * as in he will wait the reponse from the other.
886 */ 1029 */
887 1030
888 if ( call_id_bigger (session->call->id, msg->callid.header_value) == 1 ) { /* Peer has advantage */ 1031 if ( call_id_bigger (call->id, msg->callid.header_value) == 1 ) { /* Peer has advantage */
889 terminate_call(session); 1032 terminate_call(session, call);
890 } 1033 }
891 else { 1034 else {
892 return 0; /* Wait for ringing from peer */ 1035 return 0; /* Wait for ringing from peer */
@@ -894,202 +1037,213 @@ int handle_recv_invite ( MSISession *session, MSIMessage *msg )
894 1037
895 } 1038 }
896 else { 1039 else {
897 handle_error ( session, error_busy, msg->friend_id ); 1040 handle_error ( session, call, error_busy, msg->friend_id ); /* TODO: Ugh*/
898 return 0; 1041 return 0;
899 } 1042 }
900 } 1043 }
901 1044
902 if ( !msg->callid.header_value ) { 1045 if ( !msg->callid.header_value ) {
903 handle_error ( session, error_no_callid, msg->friend_id ); 1046 handle_error ( session, call, error_no_callid, msg->friend_id );
904 return 0; 1047 return 0;
905 } 1048 }
906 1049
907 session->call = init_call ( session, 1, 0 ); 1050 MSICall* new_call = init_call ( session, 1, 0 );
908 memcpy ( session->call->id, msg->callid.header_value, CALL_ID_LEN ); 1051
909 session->call->state = call_starting; 1052 if ( !new_call ) {
1053 handle_error ( session, call, error_busy, msg->friend_id );
1054 return 0;
1055 }
1056
1057 memcpy ( new_call->id, msg->callid.header_value, CALL_ID_LEN );
1058 new_call->state = call_starting;
910 1059
911 add_peer( session->call, msg->friend_id); 1060 add_peer( new_call, msg->friend_id);
912 1061
913 flush_peer_type ( session, msg, 0 ); 1062 flush_peer_type ( new_call, msg, 0 );
914 1063
915 MSIMessage *_msg_ringing = msi_new_message ( TYPE_RESPONSE, stringify_response ( ringing ) ); 1064 MSIMessage *_msg_ringing = msi_new_message ( TYPE_RESPONSE, stringify_response ( ringing ) );
916 send_message ( session, _msg_ringing, msg->friend_id ); 1065 send_message ( session, new_call, _msg_ringing, msg->friend_id );
917 free_message ( _msg_ringing ); 1066 free_message ( _msg_ringing );
918 1067
919 invoke_callback(MSI_OnInvite); 1068 invoke_callback(new_call->call_idx, MSI_OnInvite);
920 1069
921 return 1; 1070 return 1;
922} 1071}
923int handle_recv_start ( MSISession *session, MSIMessage *msg ) 1072int handle_recv_start ( MSISession *session, MSICall* call, MSIMessage *msg )
924{ 1073{
925 assert ( session ); 1074 LOGGER_DEBUG("Handling 'start' on call: %s", call->id );
926 1075
927 if ( has_call_error ( session, msg ) == 0 ) 1076 if ( has_call_error ( session, call, msg ) == 0 )
928 return 0; 1077 return -1;
929 1078
930 if ( !msg->cryptokey.header_value ) 1079 if ( !msg->cryptokey.header_value )
931 return handle_error ( session, error_no_crypto_key, msg->friend_id ); 1080 return handle_error ( session, call, error_no_crypto_key, msg->friend_id );
932 1081
933 session->call->state = call_active; 1082 call->state = call_active;
934 1083
935 session->call->key_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES ); 1084 call->key_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES );
936 memcpy ( session->call->key_peer, msg->cryptokey.header_value, crypto_secretbox_KEYBYTES ); 1085 memcpy ( call->key_peer, msg->cryptokey.header_value, crypto_secretbox_KEYBYTES );
937 1086
938 session->call->nonce_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_NONCEBYTES ); 1087 call->nonce_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_NONCEBYTES );
939 memcpy ( session->call->nonce_peer, msg->nonce.header_value, crypto_secretbox_NONCEBYTES ); 1088 memcpy ( call->nonce_peer, msg->nonce.header_value, crypto_secretbox_NONCEBYTES );
940 1089
941 flush_peer_type ( session, msg, 0 ); 1090 flush_peer_type ( call, msg, 0 );
942 1091
943 invoke_callback(MSI_OnStart); 1092 invoke_callback(call->call_idx, MSI_OnStart);
944 1093
945 return 1; 1094 return 1;
946} 1095}
947int handle_recv_reject ( MSISession *session, MSIMessage *msg ) 1096int handle_recv_reject ( MSISession *session, MSICall* call, MSIMessage *msg )
948{ 1097{
949 assert ( session ); 1098 LOGGER_DEBUG("Handling 'reject' on call: %s", call->id );
950 1099
951 if ( has_call_error ( session, msg ) == 0 ) 1100 if ( has_call_error ( session, call, msg ) == 0 )
952 return 0; 1101 return 0;
953 1102
954 1103
955 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) ); 1104 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) );
956 send_message ( session, _msg_ending, msg->friend_id ); 1105 send_message ( session, call, _msg_ending, msg->friend_id );
957 free_message ( _msg_ending ); 1106 free_message ( _msg_ending );
958 1107
959 1108
960 invoke_callback(MSI_OnReject); 1109 invoke_callback(call->call_idx, MSI_OnReject);
961 /* 1110 /*
962 event.timer_release ( session->call->request_timer_id ); 1111 event.timer_release ( session->call->request_timer_id );
963 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout ); 1112 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
964 */ 1113 */
965 1114
966 terminate_call(session); 1115 terminate_call(session, call);
967 1116
968 return 1; 1117 return 1;
969} 1118}
970int handle_recv_cancel ( MSISession *session, MSIMessage *msg ) 1119int handle_recv_cancel ( MSISession *session, MSICall* call, MSIMessage *msg )
971{ 1120{
972 assert ( session ); 1121 LOGGER_DEBUG("Handling 'cancel' on call: %s", call->id );
973 1122
974 if ( has_call_error ( session, msg ) == 0 ) 1123 if ( has_call_error ( session, call, msg ) == 0 )
975 return 0; 1124 return 0;
976 1125
977 /* Act as end message */ 1126 /* Act as end message */
978 1127
979 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) ); 1128 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) );
980 send_message ( session, _msg_ending, msg->friend_id ); 1129 send_message ( session, call, _msg_ending, msg->friend_id );
981 free_message ( _msg_ending ); 1130 free_message ( _msg_ending );
982 1131
983 invoke_callback(MSI_OnCancel); 1132 invoke_callback(call->call_idx, MSI_OnCancel);
984 1133
985 terminate_call ( session ); 1134 terminate_call ( session, call );
986 1135
987 return 1; 1136 return 1;
988} 1137}
989int handle_recv_end ( MSISession *session, MSIMessage *msg ) 1138int handle_recv_end ( MSISession *session, MSICall* call, MSIMessage *msg )
990{ 1139{
991 assert ( session ); 1140 LOGGER_DEBUG("Handling 'end' on call: %s", call->id );
992 1141
993 if ( has_call_error ( session, msg ) == 0 ) 1142 if ( has_call_error ( session, call, msg ) == 0 )
994 return 0; 1143 return 0;
995 1144
996 1145
997 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) ); 1146 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) );
998 send_message ( session, _msg_ending, msg->friend_id ); 1147 send_message ( session, call, _msg_ending, msg->friend_id );
999 free_message ( _msg_ending ); 1148 free_message ( _msg_ending );
1000 1149
1001 invoke_callback(MSI_OnEnd); 1150 invoke_callback(call->call_idx, MSI_OnEnd);
1002 1151
1003 terminate_call ( session ); 1152 terminate_call ( session, call );
1004 return 1; 1153 return 1;
1005} 1154}
1006 1155
1007/********** Response handlers **********/ 1156/********** Response handlers **********/
1008int handle_recv_ringing ( MSISession *session, MSIMessage *msg ) 1157int handle_recv_ringing ( MSISession *session, MSICall* call, MSIMessage *msg )
1009{ 1158{
1010 assert ( session ); 1159 LOGGER_DEBUG("Handling 'ringing' on call: %s", call->id );
1011 1160
1012 if ( has_call_error ( session, msg ) == 0 ) 1161 if ( has_call_error ( session, call, msg ) == 0 )
1013 return 0; 1162 return 0;
1014 1163
1015 session->call->ringing_timer_id = event.timer_alloc ( handle_timeout, session, session->call->ringing_tout_ms ); 1164 call->ringing_timer_id = event.timer_alloc ( handle_timeout, call, call->ringing_tout_ms );
1016 1165
1017 invoke_callback(MSI_OnRinging); 1166 invoke_callback(call->call_idx, MSI_OnRinging);
1018 1167
1019 return 1; 1168 return 1;
1020} 1169}
1021int handle_recv_starting ( MSISession *session, MSIMessage *msg ) 1170int handle_recv_starting ( MSISession *session, MSICall* call, MSIMessage *msg )
1022{ 1171{
1023 assert ( session ); 1172 LOGGER_DEBUG("Handling 'starting' on call: %s", call->id );
1024 1173
1025 if ( has_call_error ( session, msg ) == 0 ) 1174 if ( has_call_error ( session, call, msg ) == 0 )
1026 return 0; 1175 return 0;
1027 1176
1028 if ( !msg->cryptokey.header_value ) { 1177 if ( !msg->cryptokey.header_value ) {
1029 return handle_error ( session, error_no_crypto_key, msg->friend_id ); 1178 return handle_error ( session, call, error_no_crypto_key, msg->friend_id );
1030 } 1179 }
1031 1180
1032 /* Generate local key/nonce to send */ 1181 /* Generate local key/nonce to send */
1033 session->call->key_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES ); 1182 call->key_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES );
1034 new_symmetric_key ( session->call->key_local ); 1183 new_symmetric_key ( call->key_local );
1035 1184
1036 session->call->nonce_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_NONCEBYTES ); 1185 call->nonce_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_NONCEBYTES );
1037 new_nonce ( session->call->nonce_local ); 1186 new_nonce ( call->nonce_local );
1038 1187
1039 /* Save peer key/nonce */ 1188 /* Save peer key/nonce */
1040 session->call->key_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES ); 1189 call->key_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES );
1041 memcpy ( session->call->key_peer, msg->cryptokey.header_value, crypto_secretbox_KEYBYTES ); 1190 memcpy ( call->key_peer, msg->cryptokey.header_value, crypto_secretbox_KEYBYTES );
1042 1191
1043 session->call->nonce_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_NONCEBYTES ); 1192 call->nonce_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_NONCEBYTES );
1044 memcpy ( session->call->nonce_peer, msg->nonce.header_value, crypto_secretbox_NONCEBYTES ); 1193 memcpy ( call->nonce_peer, msg->nonce.header_value, crypto_secretbox_NONCEBYTES );
1045 1194
1046 session->call->state = call_active; 1195 call->state = call_active;
1047 1196
1048 MSIMessage *_msg_start = msi_new_message ( TYPE_REQUEST, stringify_request ( start ) ); 1197 MSIMessage *_msg_start = msi_new_message ( TYPE_REQUEST, stringify_request ( start ) );
1049 msi_msg_set_cryptokey ( _msg_start, session->call->key_local, crypto_secretbox_KEYBYTES ); 1198 msi_msg_set_cryptokey ( _msg_start, call->key_local, crypto_secretbox_KEYBYTES );
1050 msi_msg_set_nonce ( _msg_start, session->call->nonce_local, crypto_secretbox_NONCEBYTES ); 1199 msi_msg_set_nonce ( _msg_start, call->nonce_local, crypto_secretbox_NONCEBYTES );
1051 send_message ( session, _msg_start, msg->friend_id ); 1200 send_message ( session, call, _msg_start, msg->friend_id );
1052 free_message ( _msg_start ); 1201 free_message ( _msg_start );
1053 1202
1054 flush_peer_type ( session, msg, 0 ); 1203 flush_peer_type ( call, msg, 0 );
1055 1204
1056 invoke_callback(MSI_OnStarting); 1205 invoke_callback(call->call_idx, MSI_OnStarting);
1057 1206
1058 event.timer_release ( session->call->ringing_timer_id ); 1207 event.timer_release ( call->ringing_timer_id );
1059 1208
1060 return 1; 1209 return 1;
1061} 1210}
1062int handle_recv_ending ( MSISession *session, MSIMessage *msg ) 1211int handle_recv_ending ( MSISession *session, MSICall* call, MSIMessage *msg )
1063{ 1212{
1064 assert ( session ); 1213 LOGGER_DEBUG("Handling 'ending' on call: %s", call->id );
1065 1214
1066 if ( has_call_error ( session, msg ) == 0 ) 1215 if ( has_call_error ( session, call, msg ) == 0 )
1067 return 0; 1216 return 0;
1068 1217
1069 /* Stop timer */ 1218 /* Stop timer */
1070 event.timer_release ( session->call->request_timer_id ); 1219 event.timer_release ( call->request_timer_id );
1071 1220
1072 invoke_callback(MSI_OnEnding); 1221 invoke_callback(call->call_idx, MSI_OnEnding);
1073 1222
1074 /* Terminate call */ 1223 /* Terminate call */
1075 terminate_call ( session ); 1224 terminate_call ( session, call );
1076 1225
1077 return 1; 1226 return 1;
1078} 1227}
1079int handle_recv_error ( MSISession *session, MSIMessage *msg ) 1228int handle_recv_error ( MSISession *session, MSICall* call, MSIMessage *msg )
1080{ 1229{
1081 assert ( session ); 1230 if ( !call ) {
1082 assert ( session->call ); 1231 LOGGER_WARNING("Handling 'error' on non-existing call!");
1232 return -1;
1233 }
1234
1235 LOGGER_DEBUG("Handling 'error' on call: %s", call->id );
1083 1236
1084 /* Handle error accordingly */ 1237 /* Handle error accordingly */
1085 if ( msg->reason.header_value ) { 1238 if ( msg->reason.header_value ) {
1086 session->last_error_id = atoi ( ( const char * ) msg->reason.header_value ); 1239 session->last_error_id = atoi ( ( const char * ) msg->reason.header_value );
1087 session->last_error_str = stringify_error ( session->last_error_id ); 1240 session->last_error_str = stringify_error ( session->last_error_id );
1241 LOGGER_DEBUG("Error reason: %s", session->last_error_str);
1088 } 1242 }
1089 1243
1090 invoke_callback(MSI_OnEnding); 1244 invoke_callback(call->call_idx, MSI_OnEnding);
1091 1245
1092 terminate_call ( session ); 1246 terminate_call ( session, call );
1093 return 1; 1247 return 1;
1094} 1248}
1095 1249
@@ -1128,26 +1282,40 @@ int handle_recv_error ( MSISession *session, MSIMessage *msg )
1128 */ 1282 */
1129void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16_t length, void *object ) 1283void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16_t length, void *object )
1130{ 1284{
1285 LOGGER_DEBUG("Got msi message");
1131 /* Unused */ 1286 /* Unused */
1132 (void)messenger; 1287 (void)messenger;
1133 1288
1134 MSISession *_session = object; 1289 MSISession *_session = object;
1135 MSIMessage *_msg; 1290 MSIMessage *_msg;
1136 1291
1137 if ( !length ) return; 1292 if ( !length ) {
1293 LOGGER_WARNING("Lenght param negative");
1294 return;
1295 }
1138 1296
1139 _msg = parse_message ( data, length ); 1297 _msg = parse_message ( data, length );
1140 1298
1141 if ( !_msg ) return; 1299 if ( !_msg ) {
1300 LOGGER_WARNING("Error parsing message");
1301 return;
1302 } else {
1303 LOGGER_DEBUG("Successfully parsed message");
1304 }
1142 1305
1143 _msg->friend_id = source; 1306 _msg->friend_id = source;
1144 1307
1145 1308 /* Find what call */
1309 MSICall* _call = _msg->callid.header_value ? find_call(_session, _msg->callid.header_value ) : NULL;
1310
1146 /* Now handle message */ 1311 /* Now handle message */
1147 1312
1148 if ( _msg->request.header_value ) { /* Handle request */ 1313 if ( _msg->request.header_value ) { /* Handle request */
1149 1314
1150 if ( _msg->response.size > 32 ) goto free_end; 1315 if ( _msg->response.size > 32 ) {
1316 LOGGER_WARNING("Header size too big");
1317 goto free_end;
1318 }
1151 1319
1152 uint8_t _request_value[32]; 1320 uint8_t _request_value[32];
1153 1321
@@ -1155,26 +1323,30 @@ void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16
1155 _request_value[_msg->request.size] = '\0'; 1323 _request_value[_msg->request.size] = '\0';
1156 1324
1157 if ( same ( _request_value, stringify_request ( invite ) ) ) { 1325 if ( same ( _request_value, stringify_request ( invite ) ) ) {
1158 handle_recv_invite ( _session, _msg ); 1326 handle_recv_invite ( _session, _call, _msg );
1159 1327
1160 } else if ( same ( _request_value, stringify_request ( start ) ) ) { 1328 } else if ( same ( _request_value, stringify_request ( start ) ) ) {
1161 handle_recv_start ( _session, _msg ); 1329 handle_recv_start ( _session, _call, _msg );
1162 1330
1163 } else if ( same ( _request_value, stringify_request ( cancel ) ) ) { 1331 } else if ( same ( _request_value, stringify_request ( cancel ) ) ) {
1164 handle_recv_cancel ( _session, _msg ); 1332 handle_recv_cancel ( _session, _call, _msg );
1165 1333
1166 } else if ( same ( _request_value, stringify_request ( reject ) ) ) { 1334 } else if ( same ( _request_value, stringify_request ( reject ) ) ) {
1167 handle_recv_reject ( _session, _msg ); 1335 handle_recv_reject ( _session, _call, _msg );
1168 1336
1169 } else if ( same ( _request_value, stringify_request ( end ) ) ) { 1337 } else if ( same ( _request_value, stringify_request ( end ) ) ) {
1170 handle_recv_end ( _session, _msg ); 1338 handle_recv_end ( _session, _call, _msg );
1339 } else {
1340 LOGGER_WARNING("Uknown request");
1341 goto free_end;
1171 } 1342 }
1172 1343
1173 else goto free_end;
1174
1175 } else if ( _msg->response.header_value ) { /* Handle response */ 1344 } else if ( _msg->response.header_value ) { /* Handle response */
1176 1345
1177 if ( _msg->response.size > 32 ) goto free_end; 1346 if ( _msg->response.size > 32 ) {
1347 LOGGER_WARNING("Header size too big");
1348 goto free_end;
1349 }
1178 1350
1179 uint8_t _response_value[32]; 1351 uint8_t _response_value[32];
1180 1352
@@ -1182,23 +1354,28 @@ void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16
1182 _response_value[_msg->response.size] = '\0'; 1354 _response_value[_msg->response.size] = '\0';
1183 1355
1184 if ( same ( _response_value, stringify_response ( ringing ) ) ) { 1356 if ( same ( _response_value, stringify_response ( ringing ) ) ) {
1185 handle_recv_ringing ( _session, _msg ); 1357 handle_recv_ringing ( _session, _call, _msg );
1186 1358
1187 } else if ( same ( _response_value, stringify_response ( starting ) ) ) { 1359 } else if ( same ( _response_value, stringify_response ( starting ) ) ) {
1188 handle_recv_starting ( _session, _msg ); 1360 handle_recv_starting ( _session, _call, _msg );
1189 1361
1190 } else if ( same ( _response_value, stringify_response ( ending ) ) ) { 1362 } else if ( same ( _response_value, stringify_response ( ending ) ) ) {
1191 handle_recv_ending ( _session, _msg ); 1363 handle_recv_ending ( _session, _call, _msg );
1192 1364
1193 } else if ( same ( _response_value, stringify_response ( error ) ) ) { 1365 } else if ( same ( _response_value, stringify_response ( error ) ) ) {
1194 handle_recv_error ( _session, _msg ); 1366 handle_recv_error ( _session, _call, _msg );
1195 1367
1196 } else goto free_end; 1368 } else {
1369 LOGGER_WARNING("Uknown response");
1370 goto free_end;
1371 }
1197 1372
1198 /* Got response so cancel timer */ 1373 /* Got response so cancel timer */
1199 if ( _session->call ) 1374 if ( _call )
1200 event.timer_release ( _session->call->request_timer_id ); 1375 event.timer_release ( _call->request_timer_id );
1201 1376
1377 } else {
1378 LOGGER_WARNING("Invalid message: no resp nor requ headers");
1202 } 1379 }
1203 1380
1204 free_end:free_message ( _msg ); 1381 free_end:free_message ( _msg );
@@ -1248,21 +1425,31 @@ void msi_register_callback ( MSICallback callback, MSICallbackID id, void* userd
1248 * @brief Start the control session. 1425 * @brief Start the control session.
1249 * 1426 *
1250 * @param messenger Tox* object. 1427 * @param messenger Tox* object.
1251 * @param user_agent User agent, i.e. 'Venom'; 'QT-gui' 1428 * @param max_calls Amount of calls possible
1252 * @return MSISession* The created session. 1429 * @return MSISession* The created session.
1253 * @retval NULL Error occured. 1430 * @retval NULL Error occured.
1254 */ 1431 */
1255MSISession *msi_init_session ( Messenger* messenger ) 1432MSISession *msi_init_session ( Messenger* messenger, uint32_t max_calls )
1256{ 1433{
1257 assert ( messenger ); 1434 if (messenger == NULL) {
1435 LOGGER_ERROR("Could not init session on empty messenger!");
1436 return NULL;
1437 }
1258 1438
1439 if ( !max_calls) return NULL;
1440
1259 MSISession *_retu = calloc ( sizeof ( MSISession ), 1 ); 1441 MSISession *_retu = calloc ( sizeof ( MSISession ), 1 );
1260 assert ( _retu ); 1442
1443 if (_retu == NULL) {
1444 LOGGER_ERROR("Allocation failed!");
1445 return NULL;
1446 }
1261 1447
1262 _retu->messenger_handle = messenger; 1448 _retu->messenger_handle = messenger;
1263 _retu->agent_handler = NULL; 1449 _retu->agent_handler = NULL;
1264 1450
1265 _retu->call = NULL; 1451 _retu->calls = calloc( sizeof (MSICall*), max_calls );
1452 _retu->max_calls = max_calls;
1266 1453
1267 _retu->frequ = 10000; /* default value? */ 1454 _retu->frequ = 10000; /* default value? */
1268 _retu->call_timeout = 30000; /* default value? */ 1455 _retu->call_timeout = 30000; /* default value? */
@@ -1272,7 +1459,8 @@ MSISession *msi_init_session ( Messenger* messenger )
1272 1459
1273 /* This is called when remote terminates session */ 1460 /* This is called when remote terminates session */
1274 m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, _retu); 1461 m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, _retu);
1275 1462
1463 LOGGER_DEBUG("New msi session: %p max calls: %u", _retu, max_calls);
1276 return _retu; 1464 return _retu;
1277} 1465}
1278 1466
@@ -1285,16 +1473,20 @@ MSISession *msi_init_session ( Messenger* messenger )
1285 */ 1473 */
1286int msi_terminate_session ( MSISession *session ) 1474int msi_terminate_session ( MSISession *session )
1287{ 1475{
1288 assert ( session ); 1476 if (session == NULL) {
1477 LOGGER_ERROR("Tried to terminate non-existing session");
1478 return -1;
1479 }
1289 1480
1290 int _status = 0; 1481 int _status = 0;
1291 1482
1292 /* If have call, cancel it */ 1483 /* If have calls, cancel them */
1293 if ( session->call ) { 1484 uint32_t idx = 0;
1485 for (; idx < session->max_calls; idx ++) if ( session->calls[idx] ) {
1294 /* Cancel all? */ 1486 /* Cancel all? */
1295 uint16_t _it = 0; 1487 uint16_t _it = 0;
1296 for ( ; _it < session->call->peer_count; _it++ ) 1488 for ( ; _it < session->calls[idx]->peer_count; _it++ )
1297 msi_cancel ( session, session->call->peers [_it], "MSI session terminated!" ); 1489 msi_cancel ( session, idx, session->calls[idx]->peers [_it], "MSI session terminated!" );
1298 } 1490 }
1299 1491
1300 m_callback_msi_packet((struct Messenger *) session->messenger_handle, NULL, NULL); 1492 m_callback_msi_packet((struct Messenger *) session->messenger_handle, NULL, NULL);
@@ -1313,35 +1505,39 @@ int msi_terminate_session ( MSISession *session )
1313 * @param friend_id The friend. 1505 * @param friend_id The friend.
1314 * @return int 1506 * @return int
1315 */ 1507 */
1316int msi_invite ( MSISession *session, MSICallType call_type, uint32_t rngsec, uint32_t friend_id ) 1508int msi_invite ( MSISession* session, uint32_t* call_index, MSICallType call_type, uint32_t rngsec, uint32_t friend_id )
1317{ 1509{
1318 assert ( session ); 1510 LOGGER_DEBUG("Inviting friend: %u", friend_id);
1319 1511
1320 MSIMessage *_msg_invite = msi_new_message ( TYPE_REQUEST, stringify_request ( invite ) ); 1512 MSIMessage *_msg_invite = msi_new_message ( TYPE_REQUEST, stringify_request ( invite ) );
1513
1514 MSICall* _call = init_call ( session, 1, rngsec ); /* Just one for now */
1515 if ( !_call ) return -1; /* Cannot handle more calls */
1516
1517 *call_index = _call->call_idx;
1518
1519 t_randomstr ( _call->id, CALL_ID_LEN );
1321 1520
1322 session->call = init_call ( session, 1, rngsec ); /* Just one for now */ 1521 add_peer(_call, friend_id );
1323 t_randomstr ( session->call->id, CALL_ID_LEN );
1324
1325 add_peer(session->call, friend_id );
1326 1522
1327 session->call->type_local = call_type; 1523 _call->type_local = call_type;
1524
1328 /* Do whatever with message */ 1525 /* Do whatever with message */
1329
1330 if ( call_type == type_audio ) { 1526 if ( call_type == type_audio ) {
1331 msi_msg_set_calltype 1527 msi_msg_set_calltype ( _msg_invite, ( const uint8_t * ) CT_AUDIO_HEADER_VALUE, strlen ( CT_AUDIO_HEADER_VALUE ) );
1332 ( _msg_invite, ( const uint8_t * ) CT_AUDIO_HEADER_VALUE, strlen ( CT_AUDIO_HEADER_VALUE ) );
1333 } else { 1528 } else {
1334 msi_msg_set_calltype 1529 msi_msg_set_calltype ( _msg_invite, ( const uint8_t * ) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) );
1335 ( _msg_invite, ( const uint8_t * ) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) );
1336 } 1530 }
1337 1531
1338 send_message ( session, _msg_invite, friend_id ); 1532 send_message ( session, _call, _msg_invite, friend_id );
1339 free_message ( _msg_invite ); 1533 free_message ( _msg_invite );
1340 1534
1341 session->call->state = call_inviting; 1535 _call->state = call_inviting;
1342
1343 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
1344 1536
1537 _call->request_timer_id = event.timer_alloc ( handle_timeout, _call, m_deftout );
1538
1539 LOGGER_DEBUG("Invite sent");
1540
1345 return 0; 1541 return 0;
1346} 1542}
1347 1543
@@ -1350,29 +1546,37 @@ int msi_invite ( MSISession *session, MSICallType call_type, uint32_t rngsec, ui
1350 * @brief Hangup active call. 1546 * @brief Hangup active call.
1351 * 1547 *
1352 * @param session Control session. 1548 * @param session Control session.
1549 * @param call_id To which call is this action handled.
1353 * @return int 1550 * @return int
1354 * @retval -1 Error occured. 1551 * @retval -1 Error occured.
1355 * @retval 0 Success. 1552 * @retval 0 Success.
1356 */ 1553 */
1357int msi_hangup ( MSISession *session ) 1554int msi_hangup ( MSISession* session, uint32_t call_index )
1358{ 1555{
1359 assert ( session ); 1556 LOGGER_DEBUG("Hanging up call: %u", call_index);
1360 1557
1361 if ( !session->call || session->call->state != call_active ) 1558 if ( call_index >= session->max_calls || !session->calls[call_index] ) {
1559 LOGGER_ERROR("Invalid call index!");
1560 return -1;
1561 }
1562
1563 if ( !session->calls[call_index] || session->calls[call_index]->state != call_active ) {
1564 LOGGER_ERROR("No call with such index or call is not active!");
1362 return -1; 1565 return -1;
1566 }
1363 1567
1364 MSIMessage *_msg_end = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) ); 1568 MSIMessage *_msg_end = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) );
1365 1569
1366 /* hangup for each peer */ 1570 /* hangup for each peer */
1367 int _it = 0; 1571 int _it = 0;
1368 1572
1369 for ( ; _it < session->call->peer_count; _it ++ ) 1573 for ( ; _it < session->calls[call_index]->peer_count; _it ++ )
1370 send_message ( session, _msg_end, session->call->peers[_it] ); 1574 send_message ( session, session->calls[call_index], _msg_end, session->calls[call_index]->peers[_it] );
1371 1575
1372 1576
1373 free_message ( _msg_end ); 1577 free_message ( _msg_end );
1374 1578
1375 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout ); 1579 session->calls[call_index]->request_timer_id = event.timer_alloc ( handle_timeout, session->calls[call_index], m_deftout );
1376 1580
1377 return 0; 1581 return 0;
1378} 1582}
@@ -1382,15 +1586,22 @@ int msi_hangup ( MSISession *session )
1382 * @brief Answer active call request. 1586 * @brief Answer active call request.
1383 * 1587 *
1384 * @param session Control session. 1588 * @param session Control session.
1589 * @param call_id To which call is this action handled.
1385 * @param call_type Answer with Audio or Video(both). 1590 * @param call_type Answer with Audio or Video(both).
1386 * @return int 1591 * @return int
1387 */ 1592 */
1388int msi_answer ( MSISession *session, MSICallType call_type ) 1593int msi_answer ( MSISession* session, uint32_t call_index, MSICallType call_type )
1389{ 1594{
1390 assert ( session ); 1595 LOGGER_DEBUG("Answering call: %u", call_index);
1391 1596
1597 if ( call_index >= session->max_calls || !session->calls[call_index] ){
1598 LOGGER_ERROR("Invalid call index!");
1599 return -1;
1600 }
1601
1392 MSIMessage *_msg_starting = msi_new_message ( TYPE_RESPONSE, stringify_response ( starting ) ); 1602 MSIMessage *_msg_starting = msi_new_message ( TYPE_RESPONSE, stringify_response ( starting ) );
1393 session->call->type_local = call_type; 1603
1604 session->calls[call_index]->type_local = call_type;
1394 1605
1395 if ( call_type == type_audio ) { 1606 if ( call_type == type_audio ) {
1396 msi_msg_set_calltype 1607 msi_msg_set_calltype
@@ -1402,19 +1613,19 @@ int msi_answer ( MSISession *session, MSICallType call_type )
1402 1613
1403 /* Now set the local encryption key and pass it with STARTING message */ 1614 /* Now set the local encryption key and pass it with STARTING message */
1404 1615
1405 session->call->key_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES ); 1616 session->calls[call_index]->key_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES );
1406 new_symmetric_key ( session->call->key_local ); 1617 new_symmetric_key ( session->calls[call_index]->key_local );
1407 1618
1408 session->call->nonce_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_NONCEBYTES ); 1619 session->calls[call_index]->nonce_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_NONCEBYTES );
1409 new_nonce ( session->call->nonce_local ); 1620 new_nonce ( session->calls[call_index]->nonce_local );
1410 1621
1411 msi_msg_set_cryptokey ( _msg_starting, session->call->key_local, crypto_secretbox_KEYBYTES ); 1622 msi_msg_set_cryptokey ( _msg_starting, session->calls[call_index]->key_local, crypto_secretbox_KEYBYTES );
1412 msi_msg_set_nonce ( _msg_starting, session->call->nonce_local, crypto_secretbox_NONCEBYTES ); 1623 msi_msg_set_nonce ( _msg_starting, session->calls[call_index]->nonce_local, crypto_secretbox_NONCEBYTES );
1413 1624
1414 send_message ( session, _msg_starting, session->call->peers[session->call->peer_count - 1] ); 1625 send_message ( session, session->calls[call_index], _msg_starting, session->calls[call_index]->peers[session->calls[call_index]->peer_count - 1] );
1415 free_message ( _msg_starting ); 1626 free_message ( _msg_starting );
1416 1627
1417 session->call->state = call_active; 1628 session->calls[call_index]->state = call_active;
1418 1629
1419 return 0; 1630 return 0;
1420} 1631}
@@ -1424,21 +1635,27 @@ int msi_answer ( MSISession *session, MSICallType call_type )
1424 * @brief Cancel request. 1635 * @brief Cancel request.
1425 * 1636 *
1426 * @param session Control session. 1637 * @param session Control session.
1638 * @param call_id To which call is this action handled.
1427 * @param reason Set optional reason header. Pass NULL if none. 1639 * @param reason Set optional reason header. Pass NULL if none.
1428 * @return int 1640 * @return int
1429 */ 1641 */
1430int msi_cancel ( MSISession *session, uint32_t peer, const char *reason ) 1642int msi_cancel ( MSISession *session, uint32_t call_index, uint32_t peer, const char *reason )
1431{ 1643{
1432 assert ( session ); 1644 LOGGER_DEBUG("Canceling call: %u; reason:", call_index, reason? reason : "Unknown");
1433 1645
1646 if ( call_index >= session->max_calls || !session->calls[call_index] ){
1647 LOGGER_ERROR("Invalid call index!");
1648 return -1;
1649 }
1650
1434 MSIMessage *_msg_cancel = msi_new_message ( TYPE_REQUEST, stringify_request ( cancel ) ); 1651 MSIMessage *_msg_cancel = msi_new_message ( TYPE_REQUEST, stringify_request ( cancel ) );
1435 1652
1436 if ( reason ) msi_msg_set_reason(_msg_cancel, (const uint8_t*)reason, strlen(reason)); 1653 if ( reason ) msi_msg_set_reason(_msg_cancel, (const uint8_t*)reason, strlen(reason));
1437 1654
1438 send_message ( session, _msg_cancel, peer ); 1655 send_message ( session, session->calls[call_index], _msg_cancel, peer );
1439 free_message ( _msg_cancel ); 1656 free_message ( _msg_cancel );
1440 1657
1441 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout ); 1658 session->calls[call_index]->request_timer_id = event.timer_alloc ( handle_timeout, session->calls[call_index], m_deftout );
1442 1659
1443 return 0; 1660 return 0;
1444} 1661}
@@ -1448,20 +1665,26 @@ int msi_cancel ( MSISession *session, uint32_t peer, const char *reason )
1448 * @brief Reject request. 1665 * @brief Reject request.
1449 * 1666 *
1450 * @param session Control session. 1667 * @param session Control session.
1668 * @param call_id To which call is this action handled.
1451 * @return int 1669 * @return int
1452 */ 1670 */
1453int msi_reject ( MSISession *session, const uint8_t *reason ) 1671int msi_reject ( MSISession *session, uint32_t call_index, const uint8_t *reason )
1454{ 1672{
1455 assert ( session ); 1673 LOGGER_DEBUG("Rejecting call: %u; reason:", call_index, reason? (char*)reason : "Unknown");
1456 1674
1675 if ( call_index >= session->max_calls || !session->calls[call_index] ){
1676 LOGGER_ERROR("Invalid call index!");
1677 return -1;
1678 }
1679
1457 MSIMessage *_msg_reject = msi_new_message ( TYPE_REQUEST, stringify_request ( reject ) ); 1680 MSIMessage *_msg_reject = msi_new_message ( TYPE_REQUEST, stringify_request ( reject ) );
1458 1681
1459 if ( reason ) msi_msg_set_reason(_msg_reject, reason, strlen((const char *)reason) + 1); 1682 if ( reason ) msi_msg_set_reason(_msg_reject, reason, strlen((const char *)reason) + 1);
1460 1683
1461 send_message ( session, _msg_reject, session->call->peers[session->call->peer_count - 1] ); 1684 send_message ( session, session->calls[call_index], _msg_reject, session->calls[call_index]->peers[session->calls[call_index]->peer_count - 1] );
1462 free_message ( _msg_reject ); 1685 free_message ( _msg_reject );
1463 1686
1464 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout ); 1687 session->calls[call_index]->request_timer_id = event.timer_alloc ( handle_timeout, session->calls[call_index], m_deftout );
1465 1688
1466 return 0; 1689 return 0;
1467} 1690}
@@ -1471,18 +1694,19 @@ int msi_reject ( MSISession *session, const uint8_t *reason )
1471 * @brief Terminate the current call. 1694 * @brief Terminate the current call.
1472 * 1695 *
1473 * @param session Control session. 1696 * @param session Control session.
1697 * @param call_id To which call is this action handled.
1474 * @return int 1698 * @return int
1475 */ 1699 */
1476int msi_stopcall ( MSISession *session ) 1700int msi_stopcall ( MSISession *session, uint32_t call_index )
1477{ 1701{
1478 assert ( session ); 1702 LOGGER_DEBUG("Stopping call index: %u", call_index);
1479 1703
1480 if ( !session->call ) 1704 if ( call_index >= session->max_calls || !session->calls[call_index] )
1481 return -1; 1705 return -1;
1482 1706
1483 /* just terminate it */ 1707 /* just terminate it */
1484 1708
1485 terminate_call ( session ); 1709 terminate_call ( session, session->calls[call_index] );
1486 1710
1487 return 0; 1711 return 0;
1488} \ No newline at end of file 1712} \ No newline at end of file