diff options
author | mannol <eniz_vukovic@hotmail.com> | 2014-04-27 19:21:26 +0200 |
---|---|---|
committer | mannol <eniz_vukovic@hotmail.com> | 2014-04-27 19:21:26 +0200 |
commit | 42b25a4d3e2fe66f03cbd8c866d8af7bd4f6e5a7 (patch) | |
tree | 161a21847a79f7fe052a9e9ad1b9b802d04defc6 /toxav/msi.c | |
parent | 736f5f80347a39f6b82cda8a4ddc1f7d88fcc2f5 (diff) |
Yeah many calls
Diffstat (limited to 'toxav/msi.c')
-rwxr-xr-x | toxav/msi.c | 708 |
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 | ||
123 | inline__ void invoke_callback(MSICallbackID id) | 125 | inline__ 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 | */ |
231 | int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length ) | 236 | int 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) \ |
306 | var.header_value = calloc(sizeof *mheader_value, t_size); \ | 317 | var.header_value = calloc(sizeof *mheader_value, t_size); \ |
307 | memcpy(var.header_value, mheader_value, t_size); \ | 318 | if (var.header_value == NULL) { LOGGER_WARNING("Header allocation failed!"); } \ |
308 | var.size = t_size; | 319 | else { memcpy(var.header_value, mheader_value, t_size); \ |
320 | var.size = t_size; } | ||
309 | 321 | ||
310 | 322 | ||
311 | /** | 323 | /** |
@@ -316,7 +328,9 @@ var.size = t_size; | |||
316 | */ | 328 | */ |
317 | void free_message ( MSIMessage *msg ) | 329 | void 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 ) | |||
343 | MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id ) | 357 | MSIMessage *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 | */ |
372 | MSIMessage *parse_message ( const uint8_t *data, uint16_t length ) | 390 | MSIMessage *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 | */ | ||
431 | int 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 | */ |
480 | uint16_t message_to_string ( MSIMessage *msg, uint8_t *dest ) | 551 | uint16_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 | */ |
526 | void t_randomstr ( uint8_t *str, size_t size ) | 603 | void 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 | */ |
610 | int send_message ( MSISession *session, MSIMessage *msg, uint32_t to ) | 690 | int 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 | */ |
649 | void flush_peer_type ( MSISession *session, MSIMessage *msg, int peer_id ) | 747 | void 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 | ||
791 | MSICall* 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 | */ |
698 | int handle_error ( MSISession *session, MSICallError errid, uint32_t to ) | 812 | int 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 | */ |
726 | int has_call_error ( MSISession *session, MSIMessage *msg ) | 842 | int 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 | */ |
799 | MSICall *init_call ( MSISession *session, int peers, int ringing_timeout ) | 917 | MSICall *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 | */ |
836 | int terminate_call ( MSISession *session ) | 982 | int 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 **********/ |
874 | int handle_recv_invite ( MSISession *session, MSIMessage *msg ) | 1018 | int 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 | } |
923 | int handle_recv_start ( MSISession *session, MSIMessage *msg ) | 1072 | int 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 | } |
947 | int handle_recv_reject ( MSISession *session, MSIMessage *msg ) | 1096 | int 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 | } |
970 | int handle_recv_cancel ( MSISession *session, MSIMessage *msg ) | 1119 | int 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 | } |
989 | int handle_recv_end ( MSISession *session, MSIMessage *msg ) | 1138 | int 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 **********/ |
1008 | int handle_recv_ringing ( MSISession *session, MSIMessage *msg ) | 1157 | int 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 | } |
1021 | int handle_recv_starting ( MSISession *session, MSIMessage *msg ) | 1170 | int 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 | } |
1062 | int handle_recv_ending ( MSISession *session, MSIMessage *msg ) | 1211 | int 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 | } |
1079 | int handle_recv_error ( MSISession *session, MSIMessage *msg ) | 1228 | int 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 | */ |
1129 | void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16_t length, void *object ) | 1283 | void 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 | */ |
1255 | MSISession *msi_init_session ( Messenger* messenger ) | 1432 | MSISession *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 | */ |
1286 | int msi_terminate_session ( MSISession *session ) | 1474 | int 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 | */ |
1316 | int msi_invite ( MSISession *session, MSICallType call_type, uint32_t rngsec, uint32_t friend_id ) | 1508 | int 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 | */ |
1357 | int msi_hangup ( MSISession *session ) | 1554 | int 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 | */ |
1388 | int msi_answer ( MSISession *session, MSICallType call_type ) | 1593 | int 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 | */ |
1430 | int msi_cancel ( MSISession *session, uint32_t peer, const char *reason ) | 1642 | int 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 | */ |
1453 | int msi_reject ( MSISession *session, const uint8_t *reason ) | 1671 | int 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 | */ |
1476 | int msi_stopcall ( MSISession *session ) | 1700 | int 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 |