From 65d320e31daa4709bb48b7f2a52c269dde0927e9 Mon Sep 17 00:00:00 2001 From: mannol Date: Sat, 25 Jan 2014 01:32:33 +0100 Subject: Done with encryption and core adaptations. --- toxmsi/Makefile.inc | 69 ---- toxmsi/phone.c | 668 -------------------------------------- toxmsi/phone.h | 62 ---- toxmsi/toxmedia.c | 825 ----------------------------------------------- toxmsi/toxmedia.h | 168 ---------- toxmsi/toxmsi.c | 835 ------------------------------------------------ toxmsi/toxmsi.h | 145 --------- toxmsi/toxmsi_event.c | 214 ------------- toxmsi/toxmsi_event.h | 46 --- toxmsi/toxmsi_header.c | 181 ----------- toxmsi/toxmsi_header.h | 99 ------ toxmsi/toxmsi_message.c | 267 ---------------- toxmsi/toxmsi_message.h | 120 ------- 13 files changed, 3699 deletions(-) delete mode 100644 toxmsi/Makefile.inc delete mode 100644 toxmsi/phone.c delete mode 100644 toxmsi/phone.h delete mode 100644 toxmsi/toxmedia.c delete mode 100644 toxmsi/toxmedia.h delete mode 100644 toxmsi/toxmsi.c delete mode 100644 toxmsi/toxmsi.h delete mode 100644 toxmsi/toxmsi_event.c delete mode 100644 toxmsi/toxmsi_event.h delete mode 100644 toxmsi/toxmsi_header.c delete mode 100644 toxmsi/toxmsi_header.h delete mode 100644 toxmsi/toxmsi_message.c delete mode 100644 toxmsi/toxmsi_message.h (limited to 'toxmsi') diff --git a/toxmsi/Makefile.inc b/toxmsi/Makefile.inc deleted file mode 100644 index 7d620e70..00000000 --- a/toxmsi/Makefile.inc +++ /dev/null @@ -1,69 +0,0 @@ -if BUILD_AV - -lib_LTLIBRARIES += libtoxmsi.la - -libtoxmsi_la_include_HEADERS = \ - ../toxmsi/toxmsi.h \ - ../toxmsi/toxmedia.h - -libtoxmsi_la_includedir = $(includedir)/tox - - -libtoxmsi_la_SOURCES = ../toxmsi/toxmsi.h \ - ../toxmsi/toxmsi.c \ - ../toxmsi/toxmsi_message.h \ - ../toxmsi/toxmsi_message.c \ - ../toxmsi/toxmsi_header.h \ - ../toxmsi/toxmsi_header.c \ - ../toxmsi/toxmsi_event.h \ - ../toxmsi/toxmsi_event.c \ - ../toxrtp/tests/test_helper.h \ - ../toxrtp/tests/test_helper.c - -libtoxmsi_la_CFLAGS = -I../toxcore \ - -I../toxmsi \ - -I../toxrtp \ - $(NACL_CFLAGS) \ - $(PTHREAD_CFLAGS) - -libtoxmsi_la_LDFLAGS = $(TOXMSI_LT_LDFLAGS) \ - $(EXTRA_LT_LDFLAGS) \ - $(NACL_LDFLAGS) \ - $(PTHREAD_LIBS) - -libtoxmsi_la_LIBS = $(NACL_LIBS) - -noinst_PROGRAMS += phone - -phone_SOURCES = ../toxmsi/phone.c \ - ../toxmsi/toxmedia.c - -phone_CFLAGS = -I../toxcore \ - -I../toxrtp \ - $(AVFORMAT_CFLAGS) \ - $(AVCODEC_CFLAGS) \ - $(AVUTIL_CFLAGS) \ - $(AVDEVICE_CFLAGS) \ - $(SWSCALE_CFLAGS) \ - $(SDL_CFLAGS) \ - $(OPENAL_CFLAGS) \ - $(NACL_CFLAGS) \ - $(OPUS_CFLAGS) \ - $(PTHREAD_CFLAGS) - - -phone_LDADD = $(PTHREAD_LIBS) \ - libtoxrtp.la \ - libtoxmsi.la \ - $(NACL_LDFLAGS) \ - $(AVFORMAT_LIBS) \ - $(AVCODEC_LIBS) \ - $(AVUTIL_LIBS) \ - $(AVDEVICE_LIBS) \ - $(SWSCALE_LIBS) \ - $(SDL_LIBS) \ - $(OPENAL_LIBS) \ - $(NACL_LIBS) \ - $(OPUS_LIBS) - -endif diff --git a/toxmsi/phone.c b/toxmsi/phone.c deleted file mode 100644 index 432be94c..00000000 --- a/toxmsi/phone.c +++ /dev/null @@ -1,668 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#define _BSD_SOURCE -#define _GNU_SOURCE - -#define _CT_PHONE - -#ifdef _CT_PHONE -#include "phone.h" -#include -#include -#include -#include -#include -/* #include Can this be removed? */ -#include -#include "toxmedia.h" - - - -void INFO (const char *_format, ...) -{ - printf("\r[!] "); - va_list _arg; - va_start (_arg, _format); - vfprintf (stdout, _format, _arg); - va_end (_arg); - printf("\n\r >> "); - fflush(stdout); -} - -int rtp_handlepacket ( void *_object, tox_IP_Port ip_port, uint8_t *data, uint32_t length ) -{ - phone_t *_phone = _object; - rtp_msg_t *_msg; - uint8_t _payload_id; - - if ( _phone->_msi->_call && _phone->_msi->_call->_state == call_active ) { - - _msg = rtp_msg_parse ( NULL, data + 1, length - 1 ); /* ignore marker byte */ - - if ( !_msg ) - return 0; - - _payload_id = rtp_header_get_setting_payload_type(_msg->_header); - - if ( _payload_id == _PAYLOAD_OPUS && _phone->_rtp_audio ) - rtp_store_msg(_phone->_rtp_audio, _msg); - else if ( _payload_id == _PAYLOAD_VP8 && _phone->_rtp_video ) - rtp_store_msg(_phone->_rtp_video, _msg); - else rtp_free_msg( NULL, _msg); - } - - return SUCCESS; -} -int msi_handlepacket ( void *_object, tox_IP_Port ip_port, uint8_t *data, uint32_t length ) -{ - msi_session_t *_session = _object; - msi_msg_t *_msg; - - _msg = msi_parse_msg ( data + 1 ); /* ignore marker byte */ - - if ( _msg ) { - /* my current solution for "hole punching" */ - _session->_friend_id = ip_port; - } else { - return FAILURE; - } - - /* place message in a session */ - msi_store_msg(_session, _msg); - - return SUCCESS; -} - -void *phone_receivepacket ( void *_phone_p ) -{ - phone_t *_phone = _phone_p; - - - networking_registerhandler(_phone->_networking, MSI_PACKET, msi_handlepacket, _phone->_msi); - networking_registerhandler(_phone->_networking, RTP_PACKET, rtp_handlepacket, _phone); - - /* Now start main networking loop */ - while ( _phone->_networking ) { /* so not thread safe */ - networking_poll(_phone->_networking); - usleep(10000); - } - - pthread_exit ( NULL ); -} - -/* Media transport callback */ -typedef struct hmtc_args_s { - rtp_session_t **_rtp_audio; - rtp_session_t **_rtp_video; - call_type *_local_type_call; - call_state *_this_call; - void *_core_handler; -} hmtc_args_t; - -void *phone_handle_media_transport_poll ( void *_hmtc_args_p ) -{ - rtp_msg_t *_audio_msg, * _video_msg; - - hmtc_args_t *_hmtc_args = _hmtc_args_p; - - rtp_session_t *_rtp_audio = *_hmtc_args->_rtp_audio; - rtp_session_t *_rtp_video = *_hmtc_args->_rtp_video; - - call_type *_type = _hmtc_args->_local_type_call; - void *_core_handler = _hmtc_args->_core_handler; - - - call_state *_this_call = _hmtc_args->_this_call; - - while ( *_this_call == call_active ) { - - // THREADLOCK() - - _audio_msg = rtp_recv_msg ( _rtp_audio ); - _video_msg = rtp_recv_msg ( _rtp_video ); - - if ( _audio_msg ) { - /* Do whatever with msg */ - puts("audio"); - /* Do whatever with msg - puts(_audio_msg->_data);*/ - rtp_free_msg ( _rtp_audio, _audio_msg ); - } - - if ( _video_msg ) { - /* Do whatever with msg */ - puts("video"); - /* Do whatever with msg - puts(_video_msg->_data); */ - rtp_free_msg ( _rtp_video, _video_msg ); - _video_msg = NULL; - } - - /* -------------------- */ - - _audio_msg = rtp_msg_new ( _rtp_audio, (const uint8_t *)"audio\0", 6 ) ; - rtp_send_msg ( _rtp_audio, _audio_msg, _core_handler ); - _audio_msg = NULL; - - if ( *_type == type_video ) { /* if local call send video */ - _video_msg = rtp_msg_new ( _rtp_video, (const uint8_t *)"video\0", 6 ) ; - rtp_send_msg ( _rtp_video, _video_msg, _core_handler ); - _video_msg = NULL; - } - - //THREADUNLOCK() - - usleep ( 10000 ); - /* -------------------- */ - } - - //THREADLOCK() - - if ( _audio_msg ) { - rtp_free_msg(_rtp_audio, _audio_msg); - } - - if ( _video_msg ) { - rtp_free_msg(_rtp_video, _video_msg); - } - - rtp_release_session_recv(_rtp_video); - rtp_release_session_recv(_rtp_audio); - - rtp_terminate_session(_rtp_audio); - rtp_terminate_session(_rtp_video); - - *_hmtc_args->_rtp_audio = NULL; - *_hmtc_args->_rtp_video = NULL; - - free(_hmtc_args_p); - - //THREADUNLOCK() - - INFO("Media thread finished!"); - - pthread_exit ( NULL ); -} - -pthread_t phone_startmedia_loop ( phone_t *_phone ) -{ - if ( !_phone ) { - return 0; - } - - int _status; - - uint8_t _prefix = RTP_PACKET; - - pthread_t _rtp_tid; - int _rtp_thread_running = 1; - - _phone->_rtp_audio = rtp_init_session ( -1, 1 ); - rtp_set_prefix ( _phone->_rtp_audio, &_prefix, 1 ); - rtp_add_receiver ( _phone->_rtp_audio, &_phone->_msi->_friend_id ); - rtp_set_payload_type(_phone->_rtp_audio, _PAYLOAD_OPUS); - - _phone->_rtp_video = rtp_init_session ( -1, 1 ); - rtp_set_prefix ( _phone->_rtp_video, &_prefix, 1 ); - rtp_add_receiver ( _phone->_rtp_video, &_phone->_msi->_friend_id ); - rtp_set_payload_type(_phone->_rtp_video, _PAYLOAD_VP8); - - - - hmtc_args_t *rtp_targs = calloc(sizeof(hmtc_args_t), 1); - - - rtp_targs->_rtp_audio = &_phone->_rtp_audio; - rtp_targs->_rtp_video = &_phone->_rtp_video; - rtp_targs->_local_type_call = &_phone->_msi->_call->_type_local; - rtp_targs->_this_call = &_phone->_msi->_call->_state; - rtp_targs->_core_handler = _phone->_networking; - - codec_state *cs; - cs = _phone->cs; - //_status = pthread_create ( &_rtp_tid, NULL, phone_handle_media_transport_poll, rtp_targs ); - cs->_rtp_audio = _phone->_rtp_audio; - cs->_rtp_video = _phone->_rtp_video; - cs->_networking = _phone->_networking; - cs->socket = _phone->_tox_sock; - cs->quit = 0; - - printf("support: %d %d\n", cs->support_send_audio, cs->support_send_video); - - if (cs->support_send_audio && cs->support_send_video) /* quick fix */ - pthread_create(&_phone->cs->encode_audio_thread, NULL, encode_audio_thread, _phone->cs); - - if (cs->support_receive_audio) - pthread_create(&_phone->cs->decode_audio_thread, NULL, decode_audio_thread, _phone->cs); - - if (cs->support_send_video) - pthread_create(&_phone->cs->encode_video_thread, NULL, encode_video_thread, _phone->cs); - - if (cs->support_receive_video) - pthread_create(&_phone->cs->decode_video_thread, NULL, decode_video_thread, _phone->cs); - -// - return 1; - - - - -} - - -/* Some example callbacks */ - -MCBTYPE callback_recv_invite ( MCBARGS ) -{ - const char *_call_type; - - msi_session_t *_msi = _arg; - - /* Get the last one */ - call_type _type = _msi->_call->_type_peer[_msi->_call->_participants - 1]; - - switch ( _type ) { - case type_audio: - _call_type = "audio"; - break; - - case type_video: - _call_type = "video"; - break; - } - - INFO( "Incoming %s call!", _call_type ); - -} -MCBTYPE callback_recv_trying ( MCBARGS ) -{ - INFO ( "Trying..."); -} -MCBTYPE callback_recv_ringing ( MCBARGS ) -{ - INFO ( "Ringing!" ); -} -MCBTYPE callback_recv_starting ( MCBARGS ) -{ - msi_session_t *_session = _arg; - - if ( !phone_startmedia_loop(_session->_agent_handler) ) { - INFO("Starting call failed!"); - } else { - INFO ("Call started! ( press h to hangup )"); - } -} -MCBTYPE callback_recv_ending ( MCBARGS ) -{ - msi_session_t *_session = _arg; - phone_t *_phone = _session->_agent_handler; - _phone->cs->quit = 1; - - if (_phone->cs->encode_video_thread) - pthread_join(_phone->cs->encode_video_thread, NULL); - - if (_phone->cs->encode_audio_thread) - pthread_join(_phone->cs->encode_audio_thread, NULL); - - if (_phone->cs->decode_audio_thread) - pthread_join(_phone->cs->decode_audio_thread, NULL); - - if (_phone->cs->decode_video_thread) - pthread_join(_phone->cs->decode_video_thread, NULL); - - SDL_Quit(); - printf("all A/V threads successfully shut down\n"); - - INFO ( "Call ended!" ); -} - -MCBTYPE callback_recv_error ( MCBARGS ) -{ - msi_session_t *_session = _arg; - - INFO( "Error: %s", _session->_last_error_str ); -} - -MCBTYPE callback_call_started ( MCBARGS ) -{ - msi_session_t *_session = _arg; - - if ( !phone_startmedia_loop(_session->_agent_handler) ) { - INFO("Starting call failed!"); - } else { - INFO ("Call started! ( press h to hangup )"); - } - -} -MCBTYPE callback_call_canceled ( MCBARGS ) -{ - INFO ( "Call canceled!" ); -} -MCBTYPE callback_call_rejected ( MCBARGS ) -{ - INFO ( "Call rejected!\n" ); -} -MCBTYPE callback_call_ended ( MCBARGS ) -{ - - msi_session_t *_session = _arg; - phone_t *_phone = _session->_agent_handler; - _phone->cs->quit = 1; - - if (_phone->cs->encode_video_thread) - pthread_join(_phone->cs->encode_video_thread, NULL); - - if (_phone->cs->encode_audio_thread) - pthread_join(_phone->cs->encode_audio_thread, NULL); - - if (_phone->cs->decode_audio_thread) - pthread_join(_phone->cs->decode_audio_thread, NULL); - - if (_phone->cs->decode_video_thread) - pthread_join(_phone->cs->decode_video_thread, NULL); - - SDL_Quit(); - printf("all A/V threads successfully shut down\n"); - - INFO ( "Call ended!" ); -} - -MCBTYPE callback_requ_timeout ( MCBARGS ) -{ - INFO( "No answer! " ); -} - - -phone_t *initPhone(uint16_t _listen_port, uint16_t _send_port) -{ - phone_t *_retu = calloc(sizeof(phone_t), 1); - _retu->cs = av_calloc(sizeof(codec_state), 1); - - /* Initialize our mutex */ - pthread_mutex_init ( &_mutex, NULL ); - - IP_Port _local; - ip_init(&_local.ip, 0); - _local.ip.ip4.uint32 = htonl ( INADDR_ANY ); - - /* Bind local receive port to any address */ - _retu->_networking = new_networking ( _local.ip, _listen_port ); - - if ( !_retu->_networking ) { - fprintf ( stderr, "new_networking() failed!\n" ); - return NULL; - } - - _retu->_send_port = _send_port; - _retu->_recv_port = _listen_port; - - _retu->_tox_sock = _retu->_networking->sock; - - _retu->_rtp_audio = NULL; - _retu->_rtp_video = NULL; - - - /* Initialize msi */ - _retu->_msi = msi_init_session ( _retu->_networking, (const uint8_t *)_USERAGENT ); - - if ( !_retu->_msi ) { - fprintf ( stderr, "msi_init_session() failed\n" ); - return NULL; - } - - /* Initiate codecs */ - init_encoder(_retu->cs); - init_decoder(_retu->cs); - - _retu->_msi->_agent_handler = _retu; - /* Initiate callbacks */ - msi_register_callback_send ( sendpacket ); /* Using core's send */ - - msi_register_callback_call_started ( callback_call_started ); - msi_register_callback_call_canceled ( callback_call_canceled ); - msi_register_callback_call_rejected ( callback_call_rejected ); - msi_register_callback_call_ended ( callback_call_ended ); - - msi_register_callback_recv_invite ( callback_recv_invite ); - msi_register_callback_recv_ringing ( callback_recv_ringing ); - msi_register_callback_recv_starting ( callback_recv_starting ); - msi_register_callback_recv_ending ( callback_recv_ending ); - msi_register_callback_recv_error(callback_recv_error); - - msi_register_callback_requ_timeout ( callback_requ_timeout ); - /* ------------------ */ - - /* Now start msi main loop. It's a must! - * Define a frequency in ms; 10 ms is just fine - */ - msi_start_main_loop ( _retu->_msi, 10 ); - - return _retu; -} - -pthread_t phone_startmain_loop(phone_t *_phone) -{ - int _status; - /* Start receive thread */ - pthread_t _recv_thread, _phone_loop_thread; - _status = pthread_create ( &_recv_thread, NULL, phone_receivepacket, _phone ); - - if ( _status < 0 ) { - printf ( "Error while starting handle call: %d, %s\n", errno, strerror ( errno ) ); - return 0; - } - - _status = pthread_detach ( _recv_thread ); - - if ( _status < 0 ) { - printf ( "Error while starting handle call: %d, %s\n", errno, strerror ( errno ) ); - return 0; - } - - _status = pthread_create ( &_phone_loop_thread, NULL, phone_poll, _phone ); - - if ( _status < 0 ) { - printf ( "Error while starting main phone loop: %d, %s\n", errno, strerror ( errno ) ); - return 0; - } - - _status = pthread_join ( _phone_loop_thread, NULL ); - - if ( _status < 0 ) { - printf ( "Error while starting main phone loop: %d, %s\n", errno, strerror ( errno ) ); - return 0; - } - - return _phone_loop_thread; -} - -void *phone_poll ( void *_p_phone ) -{ - phone_t *_phone = _p_phone; - - int _status = SUCCESS; - - char _line[100]; - size_t _len; - - - char _dest[17]; /* For parsing destination ip */ - memset(_dest, '\0', 17); - - INFO("Welcome to tox_phone version: " _USERAGENT "\n" - "Usage: \n" - "c [a/v] (type) [0.0.0.0] (dest ip) (calls dest ip)\n" - "h (if call is active hang up)\n" - "a [a/v] (answer incoming call: a - audio / v - audio + video (audio is default))\n" - "r (reject incoming call)\n" - "q (quit)\n" - "================================================================================" - ); - - while ( 1 ) { - fgets(_line, sizeof(_line), stdin); - int i; - - for (i = 0; i < 100; i++) { - if (_line[i] == '\n') { - _line[i] = '\0'; - } - } - - _len = strlen(_line); - - if ( !_len ) { - printf(" >> "); - fflush(stdout); - continue; - } - - if ( _len > 1 && _line[1] != ' ' && _line[1] != '\n' ) { - INFO("Invalid input!"); - continue; - } - - switch (_line[0]) { - - case 'c': { - if ( _phone->_msi->_call ) { - INFO("Already in a call"); - break; - } - - call_type _ctype; - - if ( _len < 11 ) { - INFO("Invalid input; usage: c a/v 0.0.0.0"); - break; - } else if ( _line[2] == 'a' || _line[2] != 'v' ) { /* default and audio */ - _ctype = type_audio; - } else { /* video */ - _ctype = type_video; - } - - strcpy(_dest, _line + 4 ); - _status = t_setipport(_dest, _phone->_send_port, &(_phone->_msi->_friend_id)); - - if ( _status < 0 ) { - INFO("Could not resolve address!"); - } else { - /* Set timeout */ - msi_invite ( _phone->_msi, _ctype, 30 * 1000 ); - INFO("Calling!"); - } - - t_memset((uint8_t *)_dest, '\0', 17); - - } - break; - - case 'h': { - if ( !_phone->_msi->_call ) { - break; - } - - msi_hangup(_phone->_msi); - - INFO("Hung up..."); - - } - break; - - case 'a': { - if ( _phone->_msi->_call && _phone->_msi->_call->_state != call_starting ) { - break; - } - - if ( _len > 1 && _line[2] == 'v' ) - msi_answer(_phone->_msi, type_video); - else - msi_answer(_phone->_msi, type_audio); - - } - break; - - case 'r': { - if ( _phone->_msi->_call && _phone->_msi->_call->_state != call_starting ) { - break; - } - - msi_reject(_phone->_msi); - - INFO("Call Rejected..."); - - } - break; - - case 'q': { - INFO("Quitting!"); - pthread_exit(NULL); - } - - default: { - INFO("Invalid command!"); - } - break; - - } - - usleep(1000); - } - - pthread_exit(NULL); -} - -int quitPhone(phone_t *_phone) -{ - if ( _phone->_msi->_call ) { - msi_hangup(_phone->_msi); /* Hangup the phone first */ - } - - msi_terminate_session(_phone->_msi); - pthread_mutex_destroy ( &_mutex ); - - printf("\r[i] Quit!\n"); - return SUCCESS; -} - -/* ---------------------- */ - -int print_help ( const char *_name ) -{ - printf ( "Usage: %s -m (mode) -r/s ( for setting the ports on test version )\n", _name ); - return FAILURE; -} - -int main ( int argc, char *argv [] ) -{ - arg_t *_args = parse_args ( argc, argv ); - - const char *_mode = find_arg_duble ( _args, "-m" ); - uint16_t _listen_port; - uint16_t _send_port; - - if ( !_mode ) - return print_help ( argv[0] ); - - if ( _mode[0] == 'r' ) { - _send_port = 31000; - _listen_port = 31001; - } else if ( _mode[0] == 's' ) { - _send_port = 31001; - _listen_port = 31000; - } else return print_help ( argv[0] ); - - phone_t *_phone = initPhone(_listen_port, _send_port); - - if ( _phone ) { - phone_startmain_loop(_phone); - - quitPhone(_phone); - } - - return SUCCESS; -} - -#endif /* _CT_PHONE */ diff --git a/toxmsi/phone.h b/toxmsi/phone.h deleted file mode 100644 index f96aac73..00000000 --- a/toxmsi/phone.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef _PHONE_H_ -#define _PHONE_H_ - -#include "toxmsi.h" -#include "../toxrtp/toxrtp.h" -#include "toxmsi_message.h" -#include "../toxrtp/toxrtp_message.h" -#include "../toxrtp/tests/test_helper.h" -#include -#include -#include "toxmedia.h" - -/* Define client version */ -#define _USERAGENT "tox_phone-v.0.2.1" - -static pthread_mutex_t _mutex; - -#define THREADLOCK() \ -pthread_mutex_lock ( &_mutex ); - -#define THREADUNLOCK() \ -pthread_mutex_unlock ( &_mutex ); - -typedef struct phone_s { - msi_session_t* _msi; - - rtp_session_t* _rtp_audio; - rtp_session_t* _rtp_video; - - uint32_t _frame_rate; - - uint16_t _send_port, _recv_port; - - int _tox_sock; - - pthread_t _medialoop_id; - codec_state *cs; - - Networking_Core* _networking; -} phone_t; - -phone_t* initPhone(uint16_t _listen_port, uint16_t _send_port); -int quitPhone(phone_t* _phone); - -/* My recv functions */ -int rtp_handlepacket ( void* _object, tox_IP_Port ip_port, uint8_t* data, uint32_t length ); -int msi_handlepacket ( void* _object, tox_IP_Port ip_port, uint8_t* data, uint32_t length ); - -/* This is basically representation of networking_poll of toxcore */ -void* phone_receivepacket ( void* _phone ); - -/* Phones main loop */ -void* phone_poll ( void* _phone ); - -pthread_t phone_startmain_loop(phone_t* _phone); -pthread_t phone_startmedia_loop ( phone_t* _phone ); - -/* Thread handlers */ -void* phone_handle_receive_callback ( void* _p ); -void* phone_handle_media_transport_poll ( void* _hmtc_args_p ); - -#endif /* _PHONE_H_ */ diff --git a/toxmsi/toxmedia.c b/toxmsi/toxmedia.c deleted file mode 100644 index 4c9f5261..00000000 --- a/toxmsi/toxmedia.c +++ /dev/null @@ -1,825 +0,0 @@ -/* AV_codec.c -// * - * Audio and video codec intitialisation, encoding/decoding and playback - * - * Copyright (C) 2013 Tox project All Rights Reserved. - * - * This file is part of Tox. - * - * Tox is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tox. If not, see . - * - */ - -/*----------------------------------------------------------------------------------*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "toxmsi.h" -#include "toxmsi_message.h" -#include "../toxrtp/toxrtp_message.h" -#include "../toxrtp/tests/test_helper.h" -#include "phone.h" -#include "toxmedia.h" - -SDL_Surface *screen; - -int display_received_frame(codec_state *cs, AVFrame *r_video_frame) -{ - AVPicture pict; - SDL_LockYUVOverlay(cs->video_picture.bmp); - - pict.data[0] = cs->video_picture.bmp->pixels[0]; - pict.data[1] = cs->video_picture.bmp->pixels[2]; - pict.data[2] = cs->video_picture.bmp->pixels[1]; - pict.linesize[0] = cs->video_picture.bmp->pitches[0]; - pict.linesize[1] = cs->video_picture.bmp->pitches[2]; - pict.linesize[2] = cs->video_picture.bmp->pitches[1]; - - /* Convert the image into YUV format that SDL uses */ - sws_scale(cs->sws_SDL_r_ctx, (uint8_t const * const *)r_video_frame->data, r_video_frame->linesize, 0, - cs->video_decoder_ctx->height, pict.data, pict.linesize ); - - SDL_UnlockYUVOverlay(cs->video_picture.bmp); - SDL_Rect rect; - rect.x = 0; - rect.y = 0; - rect.w = cs->video_decoder_ctx->width; - rect.h = cs->video_decoder_ctx->height; - SDL_DisplayYUVOverlay(cs->video_picture.bmp, &rect); - return 1; -} - -struct jitter_buffer { - rtp_msg_t **queue; - uint16_t capacity; - uint16_t size; - uint16_t front; - uint16_t rear; - uint8_t queue_ready; - uint16_t current_id; - uint32_t current_ts; - uint8_t id_set; -}; - -struct jitter_buffer *create_queue(int capacity) -{ - struct jitter_buffer *q; - q = (struct jitter_buffer *)calloc(sizeof(struct jitter_buffer),1); - q->queue = (rtp_msg_t **)calloc((sizeof(rtp_msg_t) * capacity),1); - int i = 0; - - for (i = 0; i < capacity; ++i) { - q->queue[i] = NULL; - } - - q->size = 0; - q->capacity = capacity; - q->front = 0; - q->rear = -1; - q->queue_ready = 0; - q->current_id = 0; - q->current_ts = 0; - q->id_set = 0; - return q; -} - -/* returns 1 if 'a' has a higher sequence number than 'b' */ -uint8_t sequence_number_older(uint16_t sn_a, uint16_t sn_b, uint32_t ts_a, uint32_t ts_b) -{ - /* should be stable enough */ - return (sn_a > sn_b || ts_a > ts_b); -} - -/* success is 0 when there is nothing to dequeue, 1 when there's a good packet, 2 when there's a lost packet */ -rtp_msg_t *dequeue(struct jitter_buffer *q, int *success) -{ - if (q->size == 0 || q->queue_ready == 0) { - q->queue_ready = 0; - *success = 0; - return NULL; - } - - int front = q->front; - - if (q->id_set == 0) { - q->current_id = q->queue[front]->_header->_sequence_number; - q->current_ts = q->queue[front]->_header->_timestamp; - q->id_set = 1; - } else { - int next_id = q->queue[front]->_header->_sequence_number; - int next_ts = q->queue[front]->_header->_timestamp; - - /* if this packet is indeed the expected packet */ - if (next_id == (q->current_id + 1) % _MAX_SEQU_NUM) { - q->current_id = next_id; - q->current_ts = next_ts; - } else { - if (sequence_number_older(next_id, q->current_id, next_ts, q->current_ts)) { - printf("nextid: %d current: %d\n", next_id, q->current_id); - q->current_id = (q->current_id + 1) % _MAX_SEQU_NUM; - *success = 2; /* tell the decoder the packet is lost */ - return NULL; - } else { - /* packet too old */ - printf("packet too old\n"); - *success = 0; - return NULL; - } - } - } - - q->size--; - q->front++; - - if (q->front == q->capacity) - q->front = 0; - - *success = 1; - q->current_id = q->queue[front]->_header->_sequence_number; - q->current_ts = q->queue[front]->_header->_timestamp; - return q->queue[front]; -} - -int empty_queue(struct jitter_buffer *q) -{ - while (q->size > 0) { - q->size--; - /* FIXME: */ - /* rtp_free_msg(cs->_rtp_video, q->queue[q->front]); */ - q->front++; - - if (q->front == q->capacity) - q->front = 0; - } - - q->id_set = 0; - q->queue_ready = 0; - return 0; -} - -int queue(struct jitter_buffer *q, rtp_msg_t *pk) -{ - if (q->size == q->capacity) { - printf("buffer full, emptying buffer...\n"); - empty_queue(q); - return 0; - } - - if (q->size > 8) - q->queue_ready = 1; - - ++q->size; - ++q->rear; - - if (q->rear == q->capacity) - q->rear = 0; - - q->queue[q->rear] = pk; - - int a; - int b; - int j; - a = q->rear; - - for (j = 0; j < q->size - 1; ++j) { - b = a - 1; - - if (b < 0) - b += q->capacity; - - if (sequence_number_older(q->queue[b]->_header->_sequence_number, q->queue[a]->_header->_sequence_number, - q->queue[b]->_header->_timestamp, q->queue[a]->_header->_timestamp)) { - rtp_msg_t *temp; - temp = q->queue[a]; - q->queue[a] = q->queue[b]; - q->queue[b] = temp; - printf("had to swap\n"); - } else { - break; - } - - a -= 1; - - if (a < 0) - a += q->capacity; - } - - if (pk) - return 1; - - return 0; -} - -int init_receive_audio(codec_state *cs) -{ - int err = OPUS_OK; - cs->audio_decoder = opus_decoder_create(48000, 1, &err); - opus_decoder_init(cs->audio_decoder, 48000, 1); - printf("init audio decoder successful\n"); - return 1; -} - -int init_receive_video(codec_state *cs) -{ - cs->video_decoder = avcodec_find_decoder(VIDEO_CODEC); - - if (!cs->video_decoder) { - printf("init video_decoder failed\n"); - return 0; - } - - cs->video_decoder_ctx = avcodec_alloc_context3(cs->video_decoder); - - if (!cs->video_decoder_ctx) { - printf("init video_decoder_ctx failed\n"); - return 0; - } - - if (avcodec_open2(cs->video_decoder_ctx, cs->video_decoder, NULL) < 0) { - printf("opening video decoder failed\n"); - return 0; - } - - printf("init video decoder successful\n"); - return 1; -} - -int init_send_video(codec_state *cs) -{ - cs->video_input_format = av_find_input_format(VIDEO_DRIVER); - - if (avformat_open_input(&cs->video_format_ctx, DEFAULT_WEBCAM, cs->video_input_format, NULL) != 0) { - printf("opening video_input_format failed\n"); - return 0; - } - - avformat_find_stream_info(cs->video_format_ctx, NULL); - av_dump_format(cs->video_format_ctx, 0, DEFAULT_WEBCAM, 0); - - int i; - - for (i = 0; i < cs->video_format_ctx->nb_streams; ++i) { - if (cs->video_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - cs->video_stream = i; - break; - } - } - - cs->webcam_decoder_ctx = cs->video_format_ctx->streams[cs->video_stream]->codec; - cs->webcam_decoder = avcodec_find_decoder(cs->webcam_decoder_ctx->codec_id); - - if (cs->webcam_decoder == NULL) { - printf("Unsupported codec\n"); - return 0; - } - - if (cs->webcam_decoder_ctx == NULL) { - printf("init webcam_decoder_ctx failed\n"); - return 0; - } - - if (avcodec_open2(cs->webcam_decoder_ctx, cs->webcam_decoder, NULL) < 0) { - printf("opening webcam decoder failed\n"); - return 0; - } - - cs->video_encoder = avcodec_find_encoder(VIDEO_CODEC); - - if (!cs->video_encoder) { - printf("init video_encoder failed\n"); - return 0; - } - - cs->video_encoder_ctx = avcodec_alloc_context3(cs->video_encoder); - - if (!cs->video_encoder_ctx) { - printf("init video_encoder_ctx failed\n"); - return 0; - } - - cs->video_encoder_ctx->bit_rate = VIDEO_BITRATE; - cs->video_encoder_ctx->rc_min_rate = cs->video_encoder_ctx->rc_max_rate = cs->video_encoder_ctx->bit_rate; - av_opt_set_double(cs->video_encoder_ctx->priv_data, "max-intra-rate", 90, 0); - av_opt_set(cs->video_encoder_ctx->priv_data, "quality", "realtime", 0); - - cs->video_encoder_ctx->thread_count = 4; - cs->video_encoder_ctx->rc_buffer_aggressivity = 0.95; - cs->video_encoder_ctx->rc_buffer_size = VIDEO_BITRATE * 6; - cs->video_encoder_ctx->profile = 3; - cs->video_encoder_ctx->qmax = 54; - cs->video_encoder_ctx->qmin = 4; - AVRational myrational = {1, 25}; - cs->video_encoder_ctx->time_base = myrational; - cs->video_encoder_ctx->gop_size = 99999; - cs->video_encoder_ctx->pix_fmt = PIX_FMT_YUV420P; - cs->video_encoder_ctx->width = cs->webcam_decoder_ctx->width; - cs->video_encoder_ctx->height = cs->webcam_decoder_ctx->height; - - if (avcodec_open2(cs->video_encoder_ctx, cs->video_encoder, NULL) < 0) { - printf("opening video encoder failed\n"); - return 0; - } - - printf("init video encoder successful\n"); - return 1; -} - -int init_send_audio(codec_state *cs) -{ - cs->support_send_audio = 0; - - const ALchar *pDeviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); - int i = 0; - const ALchar *device_names[20]; - - if (pDeviceList) { - printf("\nAvailable Capture Devices are:\n"); - - while (*pDeviceList) { - device_names[i] = pDeviceList; - printf("%d) %s\n", i, device_names[i]); - pDeviceList += strlen(pDeviceList) + 1; - ++i; - } - } - - printf("enter capture device number: \n"); - char dev[2]; - fgets(dev, sizeof(dev), stdin); - cs->audio_capture_device = alcCaptureOpenDevice(device_names[dev[0] - 48], AUDIO_SAMPLE_RATE, AL_FORMAT_MONO16, - AUDIO_FRAME_SIZE * 4); - - if (alcGetError(cs->audio_capture_device) != AL_NO_ERROR) { - printf("could not start capture device! %d\n", alcGetError(cs->audio_capture_device)); - return 0; - } - - int err = OPUS_OK; - cs->audio_bitrate = AUDIO_BITRATE; - cs->audio_encoder = opus_encoder_create(AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, &err); - err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate)); - err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10)); - err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); - - opus_encoder_init(cs->audio_encoder, AUDIO_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP); - - int nfo; - err = opus_encoder_ctl(cs->audio_encoder, OPUS_GET_LOOKAHEAD(&nfo)); - /* printf("Encoder lookahead delay : %d\n", nfo); */ - printf("init audio encoder successful\n"); - - return 1; -} - -int init_encoder(codec_state *cs) -{ - avdevice_register_all(); - avcodec_register_all(); - avdevice_register_all(); - av_register_all(); - - pthread_mutex_init(&cs->rtp_msg_mutex_lock, NULL); - pthread_mutex_init(&cs->avcodec_mutex_lock, NULL); - - cs->support_send_video = init_send_video(cs); - cs->support_send_audio = init_send_audio(cs); - - cs->send_audio = 1; - cs->send_video = 1; - - return 1; -} - -int init_decoder(codec_state *cs) -{ - avdevice_register_all(); - avcodec_register_all(); - avdevice_register_all(); - av_register_all(); - - cs->receive_video = 0; - cs->receive_audio = 0; - - cs->support_receive_video = init_receive_video(cs); - cs->support_receive_audio = init_receive_audio(cs); - - cs->receive_audio = 1; - cs->receive_video = 1; - - return 1; -} - -int video_encoder_refresh(codec_state *cs, int bps) -{ - if (cs->video_encoder_ctx) - avcodec_close(cs->video_encoder_ctx); - - cs->video_encoder = avcodec_find_encoder(VIDEO_CODEC); - - if (!cs->video_encoder) { - printf("init video_encoder failed\n"); - return -1; - } - - cs->video_encoder_ctx = avcodec_alloc_context3(cs->video_encoder); - - if (!cs->video_encoder_ctx) { - printf("init video_encoder_ctx failed\n"); - return -1; - } - - cs->video_encoder_ctx->bit_rate = bps; - cs->video_encoder_ctx->rc_min_rate = cs->video_encoder_ctx->rc_max_rate = cs->video_encoder_ctx->bit_rate; - av_opt_set_double(cs->video_encoder_ctx->priv_data, "max-intra-rate", 90, 0); - av_opt_set(cs->video_encoder_ctx->priv_data, "quality", "realtime", 0); - - cs->video_encoder_ctx->thread_count = 4; - cs->video_encoder_ctx->rc_buffer_aggressivity = 0.95; - cs->video_encoder_ctx->rc_buffer_size = bps * 6; - cs->video_encoder_ctx->profile = 0; - cs->video_encoder_ctx->qmax = 54; - cs->video_encoder_ctx->qmin = 4; - AVRational myrational = {1, 25}; - cs->video_encoder_ctx->time_base = myrational; - cs->video_encoder_ctx->gop_size = 99999; - cs->video_encoder_ctx->pix_fmt = PIX_FMT_YUV420P; - cs->video_encoder_ctx->width = cs->webcam_decoder_ctx->width; - cs->video_encoder_ctx->height = cs->webcam_decoder_ctx->height; - - if (avcodec_open2(cs->video_encoder_ctx, cs->video_encoder, NULL) < 0) { - printf("opening video encoder failed\n"); - return -1; - } - return 0; -} - -void *encode_video_thread(void *arg) -{ - codec_state *cs = (codec_state *)arg; - AVPacket pkt1, *packet = &pkt1; - int p = 0; - int err; - int got_packet; - rtp_msg_t *s_video_msg; - int video_frame_finished; - AVFrame *s_video_frame; - AVFrame *webcam_frame; - s_video_frame = avcodec_alloc_frame(); - webcam_frame = avcodec_alloc_frame(); - AVPacket enc_video_packet; - - uint8_t *buffer; - int numBytes; - /* Determine required buffer size and allocate buffer */ - numBytes = avpicture_get_size(PIX_FMT_YUV420P, cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height); - buffer = (uint8_t *)av_calloc(numBytes * sizeof(uint8_t),1); - avpicture_fill((AVPicture *)s_video_frame, buffer, PIX_FMT_YUV420P, cs->webcam_decoder_ctx->width, - cs->webcam_decoder_ctx->height); - cs->sws_ctx = sws_getContext(cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height, - cs->webcam_decoder_ctx->pix_fmt, cs->webcam_decoder_ctx->width, cs->webcam_decoder_ctx->height, PIX_FMT_YUV420P, - SWS_BILINEAR, NULL, NULL, NULL); - - while (!cs->quit && cs->send_video) { - - if (av_read_frame(cs->video_format_ctx, packet) < 0) { - printf("error reading frame\n"); - - if (cs->video_format_ctx->pb->error != 0) - break; - - continue; - } - - if (packet->stream_index == cs->video_stream) { - if (avcodec_decode_video2(cs->webcam_decoder_ctx, webcam_frame, &video_frame_finished, packet) < 0) { - printf("couldn't decode\n"); - continue; - } - - av_free_packet(packet); - sws_scale(cs->sws_ctx, (uint8_t const * const *)webcam_frame->data, webcam_frame->linesize, 0, - cs->webcam_decoder_ctx->height, s_video_frame->data, s_video_frame->linesize); - /* create a new I-frame every 60 frames */ - ++p; - - if (p == 60) { - - s_video_frame->pict_type = AV_PICTURE_TYPE_BI ; - } else if (p == 61) { - s_video_frame->pict_type = AV_PICTURE_TYPE_I ; - p = 0; - } else { - s_video_frame->pict_type = AV_PICTURE_TYPE_P ; - } - - if (video_frame_finished) { - err = avcodec_encode_video2(cs->video_encoder_ctx, &enc_video_packet, s_video_frame, &got_packet); - - if (err < 0) { - printf("could not encode video frame\n"); - continue; - } - - if (!got_packet) { - continue; - } - - pthread_mutex_lock(&cs->rtp_msg_mutex_lock); - THREADLOCK() - - if (!enc_video_packet.data) fprintf(stderr, "video packet data is NULL\n"); - - s_video_msg = rtp_msg_new ( cs->_rtp_video, enc_video_packet.data, enc_video_packet.size ) ; - - if (!s_video_msg) { - printf("invalid message\n"); - } - - rtp_send_msg ( cs->_rtp_video, s_video_msg, cs->_networking ); - THREADUNLOCK() - pthread_mutex_unlock(&cs->rtp_msg_mutex_lock); - av_free_packet(&enc_video_packet); - } - } else { - av_free_packet(packet); - } - } - - /* clean up codecs */ - pthread_mutex_lock(&cs->avcodec_mutex_lock); - av_free(buffer); - av_free(webcam_frame); - av_free(s_video_frame); - sws_freeContext(cs->sws_ctx); - avcodec_close(cs->webcam_decoder_ctx); - avcodec_close(cs->video_encoder_ctx); - pthread_mutex_unlock(&cs->avcodec_mutex_lock); - pthread_exit ( NULL ); -} - -void *encode_audio_thread(void *arg) -{ - codec_state *cs = (codec_state *)arg; - rtp_msg_t *s_audio_msg; - unsigned char encoded_data[4096]; - int encoded_size = 0; - int16_t frame[4096]; - int frame_size = AUDIO_FRAME_SIZE; - ALint sample = 0; - alcCaptureStart(cs->audio_capture_device); - - while (!cs->quit && cs->send_audio) { - alcGetIntegerv(cs->audio_capture_device, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), &sample); - - if (sample >= frame_size) { - alcCaptureSamples(cs->audio_capture_device, frame, frame_size); - encoded_size = opus_encode(cs->audio_encoder, frame, frame_size, encoded_data, 480); - - if (encoded_size <= 0) { - printf("Could not encode audio packet\n"); - } else { - pthread_mutex_lock(&cs->rtp_msg_mutex_lock); - THREADLOCK() - rtp_set_payload_type(cs->_rtp_audio, 96); - s_audio_msg = rtp_msg_new (cs->_rtp_audio, encoded_data, encoded_size) ; - rtp_send_msg ( cs->_rtp_audio, s_audio_msg, cs->_networking ); - pthread_mutex_unlock(&cs->rtp_msg_mutex_lock); - THREADUNLOCK() - } - } else { - usleep(1000); - } - } - - /* clean up codecs */ - pthread_mutex_lock(&cs->avcodec_mutex_lock); - alcCaptureStop(cs->audio_capture_device); - alcCaptureCloseDevice(cs->audio_capture_device); - - pthread_mutex_unlock(&cs->avcodec_mutex_lock); - pthread_exit ( NULL ); -} - - -int video_decoder_refresh(codec_state *cs, int width, int height) -{ - printf("need to refresh\n"); - screen = SDL_SetVideoMode(width, height, 0, 0); - - if (cs->video_picture.bmp) - SDL_FreeYUVOverlay(cs->video_picture.bmp); - - cs->video_picture.bmp = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, screen); - cs->sws_SDL_r_ctx = sws_getContext(width, height, cs->video_decoder_ctx->pix_fmt, width, height, PIX_FMT_YUV420P, - SWS_BILINEAR, NULL, NULL, NULL); - return 1; -} - -void *decode_video_thread(void *arg) -{ - codec_state *cs = (codec_state *)arg; - cs->video_stream = 0; - rtp_msg_t *r_msg; - int dec_frame_finished; - AVFrame *r_video_frame; - r_video_frame = avcodec_alloc_frame(); - AVPacket dec_video_packet; - av_new_packet (&dec_video_packet, 65536); - int width = 0; - int height = 0; - - while (!cs->quit && cs->receive_video) { - r_msg = rtp_recv_msg ( cs->_rtp_video ); - - if (r_msg) { - memcpy(dec_video_packet.data, r_msg->_data, r_msg->_length); - dec_video_packet.size = r_msg->_length; - avcodec_decode_video2(cs->video_decoder_ctx, r_video_frame, &dec_frame_finished, &dec_video_packet); - - if (dec_frame_finished) { - if (cs->video_decoder_ctx->width != width || cs->video_decoder_ctx->height != height) { - width = cs->video_decoder_ctx->width; - height = cs->video_decoder_ctx->height; - printf("w: %d h%d \n", width, height); - video_decoder_refresh(cs, width, height); - } - - display_received_frame(cs, r_video_frame); - } else { - /* TODO: request the sender to create a new i-frame immediatly */ - printf("bad video packet\n"); - } - - rtp_free_msg(cs->_rtp_video, r_msg); - } - - usleep(1000); - } - - printf("vend\n"); - /* clean up codecs */ - pthread_mutex_lock(&cs->avcodec_mutex_lock); - av_free(r_video_frame); - avcodec_close(cs->video_decoder_ctx); - pthread_mutex_unlock(&cs->avcodec_mutex_lock); - pthread_exit ( NULL ); -} - -void *decode_audio_thread(void *arg) -{ - codec_state *cs = (codec_state *)arg; - rtp_msg_t *r_msg; - - int frame_size = AUDIO_FRAME_SIZE; - int data_size; - - ALCdevice *dev; - ALCcontext *ctx; - ALuint source, *buffers; - dev = alcOpenDevice(NULL); - ctx = alcCreateContext(dev, NULL); - alcMakeContextCurrent(ctx); - int openal_buffers = 5; - - buffers = calloc(sizeof(ALuint) * openal_buffers,1); - alGenBuffers(openal_buffers, buffers); - alGenSources((ALuint)1, &source); - alSourcei(source, AL_LOOPING, AL_FALSE); - - ALuint buffer; - ALint val; - - ALenum error; - uint16_t zeros[frame_size]; - int i; - - for (i = 0; i < frame_size; i++) { - zeros[i] = 0; - } - - for (i = 0; i < openal_buffers; ++i) { - alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, frame_size, 48000); - } - - alSourceQueueBuffers(source, openal_buffers, buffers); - alSourcePlay(source); - - if (alGetError() != AL_NO_ERROR) { - fprintf(stderr, "Error starting audio\n"); - cs->quit = 1; - } - - struct jitter_buffer *j_buf = NULL; - - j_buf = create_queue(20); - - int success = 0; - - int dec_frame_len; - - opus_int16 PCM[frame_size]; - - while (!cs->quit && cs->receive_audio) { - THREADLOCK() - r_msg = rtp_recv_msg ( cs->_rtp_audio ); - - if (r_msg) { - /* push the packet into the queue */ - queue(j_buf, r_msg); - } - - /* grab a packet from the queue */ - success = 0; - alGetSourcei(source, AL_BUFFERS_PROCESSED, &val); - - if (val > 0) - r_msg = dequeue(j_buf, &success); - - if (success > 0) { - /* good packet */ - if (success == 1) { - dec_frame_len = opus_decode(cs->audio_decoder, r_msg->_data, r_msg->_length, PCM, frame_size, 0); - rtp_free_msg(cs->_rtp_audio, r_msg); - } - - /* lost packet */ - if (success == 2) { - printf("lost packet\n"); - dec_frame_len = opus_decode(cs->audio_decoder, NULL, 0, PCM, frame_size, 1); - } - - if (dec_frame_len > 0) { - alGetSourcei(source, AL_BUFFERS_PROCESSED, &val); - - if (val <= 0) - continue; - - alSourceUnqueueBuffers(source, 1, &buffer); - data_size = av_samples_get_buffer_size(NULL, 1, dec_frame_len, AV_SAMPLE_FMT_S16, 1); - alBufferData(buffer, AL_FORMAT_MONO16, PCM, data_size, 48000); - int error = alGetError(); - - if (error != AL_NO_ERROR) { - fprintf(stderr, "Error setting buffer %d\n", error); - break; - } - - alSourceQueueBuffers(source, 1, &buffer); - - if (alGetError() != AL_NO_ERROR) { - fprintf(stderr, "error: could not buffer audio\n"); - break; - } - - alGetSourcei(source, AL_SOURCE_STATE, &val); - - if (val != AL_PLAYING) - alSourcePlay(source); - - - } - } - - THREADUNLOCK() - usleep(1000); - } - - /* clean up codecs */ - pthread_mutex_lock(&cs->avcodec_mutex_lock); - - /* clean up openal */ - alDeleteSources(1, &source); - alDeleteBuffers(openal_buffers, buffers); - alcMakeContextCurrent(NULL); - alcDestroyContext(ctx); - alcCloseDevice(dev); - pthread_mutex_unlock(&cs->avcodec_mutex_lock); - pthread_exit ( NULL ); -} diff --git a/toxmsi/toxmedia.h b/toxmsi/toxmedia.h deleted file mode 100644 index 8734b173..00000000 --- a/toxmsi/toxmedia.h +++ /dev/null @@ -1,168 +0,0 @@ -/* AV_codec.h - * - * Audio and video codec intitialisation, encoding/decoding and playback - * - * Copyright (C) 2013 Tox project All Rights Reserved. - * - * This file is part of Tox. - * - * Tox is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tox. If not, see . - * - */ - -/*----------------------------------------------------------------------------------*/ -#ifndef _AVCODEC_H_ -#define _AVCODEC_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "toxrtp.h" -#include "tox.h" - -#include -#include - -/* ffmpeg VP8 codec ID */ -#define VIDEO_CODEC AV_CODEC_ID_VP8 - -/* ffmpeg Opus codec ID */ -#define AUDIO_CODEC AV_CODEC_ID_OPUS - -/* default video bitrate in bytes/s */ -#define VIDEO_BITRATE 10*1000 - -/* default audio bitrate in bytes/s */ -#define AUDIO_BITRATE 64000 - -/* audio frame duration in miliseconds */ -#define AUDIO_FRAME_DURATION 20 - -/* audio sample rate recommended to be 48kHz for Opus */ -#define AUDIO_SAMPLE_RATE 48000 - -/* the amount of samples in one audio frame */ -#define AUDIO_FRAME_SIZE AUDIO_SAMPLE_RATE*AUDIO_FRAME_DURATION/1000 - -/* the quit event for SDL */ -#define FF_QUIT_EVENT (SDL_USEREVENT + 2) - -#ifdef __linux__ -#define VIDEO_DRIVER "video4linux2" -#define DEFAULT_WEBCAM "/dev/video0" -#endif - -#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) -#define VIDEO_DRIVER "vfwcap" -#define DEFAULT_WEBCAM "0" -#endif - -extern SDL_Surface *screen; - -typedef struct { - SDL_Overlay *bmp; - int width, height; -} VideoPicture; - - -typedef struct { - uint8_t send_audio; - uint8_t receive_audio; - uint8_t send_video; - uint8_t receive_video; - - uint8_t support_send_audio; - uint8_t support_send_video; - uint8_t support_receive_audio; - uint8_t support_receive_video; - - /* video encoding */ - AVInputFormat *video_input_format; - AVFormatContext *video_format_ctx; - uint8_t video_stream; - AVCodecContext *webcam_decoder_ctx; - AVCodec *webcam_decoder; - AVCodecContext *video_encoder_ctx; - AVCodec *video_encoder; - - /* video decoding */ - AVCodecContext *video_decoder_ctx; - AVCodec *video_decoder; - - /* audio encoding */ - ALCdevice *audio_capture_device; - OpusEncoder *audio_encoder; - int audio_bitrate; - - /* audio decoding */ - OpusDecoder *audio_decoder; - - uint8_t req_video_refresh; - - /* context for converting image format to something SDL can use*/ - struct SwsContext *sws_SDL_r_ctx; - - /* context for converting webcam image format to something the video encoder can use */ - struct SwsContext *sws_ctx; - - /* rendered video picture, ready for display */ - VideoPicture video_picture; - - rtp_session_t *_rtp_video; - rtp_session_t *_rtp_audio; - int socket; - Networking_Core *_networking; - - pthread_t encode_audio_thread; - pthread_t encode_video_thread; - - pthread_t decode_audio_thread; - pthread_t decode_video_thread; - - pthread_mutex_t rtp_msg_mutex_lock; - pthread_mutex_t avcodec_mutex_lock; - - uint8_t quit; - SDL_Event SDL_event; - - msi_session_t *_msi; - uint32_t _frame_rate; - uint16_t _send_port, _recv_port; - int _tox_sock; - //pthread_id _medialoop_id; - -} codec_state; - -int display_received_frame(codec_state *cs, AVFrame *r_video_frame); -int init_receive_audio(codec_state *cs); -int init_decoder(codec_state *cs); -int init_send_video(codec_state *cs); -int init_send_audio(codec_state *cs); -int init_encoder(codec_state *cs); -int video_encoder_refresh(codec_state *cs, int bps); -void *encode_video_thread(void *arg); -void *encode_audio_thread(void *arg); -int video_decoder_refresh(codec_state *cs, int width, int height); -int handle_rtp_video_packet(codec_state *cs, rtp_msg_t *r_msg); -void *decode_video_thread(void *arg); -void *decode_audio_thread(void *arg); - -#endif diff --git a/toxmsi/toxmsi.c b/toxmsi/toxmsi.c deleted file mode 100644 index 38af28fb..00000000 --- a/toxmsi/toxmsi.c +++ /dev/null @@ -1,835 +0,0 @@ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#define _BSD_SOURCE - -#include "toxmsi.h" -#include "toxmsi_event.h" -#include "toxmsi_message.h" -#include "../toxrtp/toxrtp_helper.h" -#include "../toxcore/network.h" - -#include -#include -#include - -#define same(x, y) strcmp((const char*) x, (const char*) y) == 0 - -typedef enum { - error_deadcall = 1, /* has call id but it's from old call */ - error_id_mismatch, /* non-existing call */ - - error_no_callid, /* not having call id */ - error_no_call, /* no call in session */ - - error_busy -} msi_error_t; /* Error codes */ - -static inline const uint8_t *stringify_error(msi_error_t _error_code) -{ - static const uint8_t* strings[] = - { - (uint8_t*)"", - (uint8_t*)"Using dead call", - (uint8_t*)"Call id not set to any call", - (uint8_t*)"Call id not available", - (uint8_t*)"No active call in session", - (uint8_t*)"Callee busy" - }; - - return strings[_error_code]; -} - -static inline const uint8_t *stringify_error_code(msi_error_t _error_code) -{ - static const uint8_t* strings[] = - { - (uint8_t*)"", - (uint8_t*)"1", - (uint8_t*)"2", - (uint8_t*)"3", - (uint8_t*)"4", - (uint8_t*)"5" - }; - - return strings[_error_code]; -} - -/* ******************* */ -/* --------- GLOBAL FUNCTIONS USED BY THIS FILE --------- */ - -/* CALLBACKS */ -/*int (*msi_send_message_callback) ( int, uint8_t*, uint32_t ) = NULL;*/ -int ( *msi_send_message_callback ) ( void* _core_handler, tox_IP_Port, uint8_t*, uint32_t ) = NULL; -int ( *msi_recv_message_callback ) ( tox_IP_Port*, uint8_t*, uint32_t* ) = NULL; - -MCBTYPE ( *msi_recv_invite_callback ) ( MCBARGS ) = NULL; -MCBTYPE ( *msi_start_call_callback ) ( MCBARGS ) = NULL; -MCBTYPE ( *msi_reject_call_callback ) ( MCBARGS ) = NULL; -MCBTYPE ( *msi_cancel_call_callback ) ( MCBARGS ) = NULL; -MCBTYPE ( *msi_end_call_callback ) ( MCBARGS ) = NULL; - -MCBTYPE ( *msi_ringing_callback ) ( MCBARGS ) = NULL; -MCBTYPE ( *msi_starting_callback ) ( MCBARGS ) = NULL; -MCBTYPE ( *msi_ending_callback ) ( MCBARGS ) = NULL; -MCBTYPE ( *msi_error_callback ) ( MCBARGS ) = NULL; - -MCBTYPE ( *msi_timeout_callback ) ( MCBARGS ) = NULL; -/* End of CALLBACKS */ - -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ - -/* REGISTER CALLBACKS */ -/*void msi_register_callback_send(int (*callback) ( int, uint8_t*, uint32_t ) )*/ -void msi_register_callback_send ( int ( *callback ) ( void* _core_handler, tox_IP_Port, uint8_t*, uint32_t ) ) -{ - msi_send_message_callback = callback; -} - -void msi_register_callback_recv ( int ( *callback ) ( tox_IP_Port*, uint8_t*, uint32_t* ) ) -{ - msi_recv_message_callback = callback; -} - -/* Function to be called when received invite. - * This callback is all about what you do with it. - * Everything else is done internally. - */ -void msi_register_callback_recv_invite ( MCALLBACK ) -{ - msi_recv_invite_callback = callback; -} - -/* Function to be called when the call is started - * This callback is all about what you do with it. - * Everything else is done internally. - */ -void msi_register_callback_call_started ( MCALLBACK ) -{ - msi_start_call_callback = callback; -} - -/* Function to be called when call is rejected - * This callback is all about what you do with it. - * Everything else is done internally. - */ -void msi_register_callback_call_rejected ( MCALLBACK ) -{ - msi_reject_call_callback = callback; -} - -/* Function to be called when call is canceled - * This callback is all about what you do with it. - * Everything else is done internally. - */ -void msi_register_callback_call_canceled ( MCALLBACK ) -{ - msi_cancel_call_callback = callback; -} - -void msi_register_callback_call_ended ( MCALLBACK ) -{ - msi_end_call_callback = callback; -} - - -/* Functions to be called when gotten x response */ - -void msi_register_callback_recv_ringing ( MCALLBACK ) -{ - msi_ringing_callback = callback; -} -void msi_register_callback_recv_starting ( MCALLBACK ) -{ - msi_starting_callback = callback; -} -void msi_register_callback_recv_ending ( MCALLBACK ) -{ - msi_ending_callback = callback; -} - -void msi_register_callback_recv_error ( MCALLBACK ) -{ - msi_error_callback = callback; -} - -/* Timeout */ -void msi_register_callback_requ_timeout ( MCALLBACK ) -{ - msi_timeout_callback = callback; -} -/* END REGISTERING */ - -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ - -/* Function for receiving and parsing a message that will be used internally */ - -msi_msg_t* receive_message ( msi_session_t* _session ) -{ - assert(_session); - - - msi_msg_t* _retu = _session->_oldest_msg; - - pthread_mutex_lock ( &_session->_mutex ); - - if ( _retu ) - _session->_oldest_msg = _retu->_next; - - if ( !_session->_oldest_msg ) - _session->_last_msg = NULL; - - pthread_mutex_unlock ( &_session->_mutex ); - - return _retu; -} - -void msi_store_msg ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - assert(_msg); - - pthread_mutex_lock ( &_session->_mutex ); - - if ( _session->_last_msg ) { - _session->_last_msg->_next = _msg; - _session->_last_msg = _msg; - } else { - _session->_last_msg = _session->_oldest_msg = _msg; - } - - pthread_mutex_unlock ( &_session->_mutex ); -} - -int msi_send_msg ( msi_session_t* _session, msi_msg_t* _msg ) -{ - int _status; - - if ( !_session->_call ) /* Which should never happen */ - return FAILURE; - - msi_msg_set_call_id ( _msg, _session->_call->_id ); - - uint8_t _msg_string_final [MSI_MAXMSG_SIZE]; - t_memset ( _msg_string_final, '\0', MSI_MAXMSG_SIZE ); - - _msg_string_final[0] = 69; - - uint8_t* _msg_string = msi_msg_to_string ( _msg ); - - size_t _lenght = t_memlen ( _msg_string ); - - memcpy ( _msg_string_final + 1, _msg_string, _lenght ); - - _lenght += 1; - - _status = ( *msi_send_message_callback ) ( _session->_core_handler, _session->_friend_id, _msg_string_final, _lenght ); - - free ( _msg_string ); - - return _status; -} - -/* Random stuff */ -void flush_peer_type ( msi_session_t* _session, msi_msg_t* _msg, int _peer_id ) -{ - if ( _msg->_call_type ) { - if ( strcmp ( ( const char* ) _msg->_call_type->_header_value, CT_AUDIO_HEADER_VALUE ) == 0 ) { - _session->_call->_type_peer[_peer_id] = type_audio; - - } else if ( strcmp ( ( const char* ) _msg->_call_type->_header_value, CT_VIDEO_HEADER_VALUE ) == 0 ) { - _session->_call->_type_peer[_peer_id] = type_video; - } else {} /* Error */ - } else {} /* Error */ -} - -int has_call_error ( msi_session_t* _session, msi_msg_t* _msg ) -{ - msi_msg_t* _msg_error = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _error ) ); - - if ( !_msg->_call_id ) { - msi_msg_set_reason(_msg_error, stringify_error_code(error_no_callid) ); - - } else if ( !_session->_call ) { - msi_msg_set_reason(_msg_error, stringify_error_code(error_no_call) ); - - } else if ( strcmp((const char*)_session->_call->_id, (const char*)_msg->_call_id->_header_value ) != 0 ) { - msi_msg_set_reason(_msg_error, stringify_error_code(error_id_mismatch) ); - } - - if ( _msg_error->_reason ) { - msi_send_msg ( _session, _msg_error ); - msi_free_msg ( _msg_error ); - return SUCCESS; - } - - msi_free_msg ( _msg_error ); - return FAILURE; -} - -/* --------- END OF GLOBAL FUNCTIONS USED BY THIS FILE --------- */ - -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ - -msi_session_t* msi_init_session ( void* _core_handler, const uint8_t* _user_agent ) -{ - assert(_core_handler); - assert(_user_agent); - - msi_session_t* _session = calloc ( sizeof ( msi_session_t ), 1 ); - assert(_session); - - _session->_oldest_msg = _session->_last_msg = NULL; - _session->_core_handler = _core_handler; - - _session->_user_agent = t_strallcpy ( _user_agent ); - _session->_agent_handler = NULL; - - _session->_key = 0; - _session->_call = NULL; - - _session->_frequ = 10000; /* default value? */ - _session->_call_timeout = 30000; /* default value? */ - - /* Use the same frequency */ - _session->_event_handler = init_event_poll ( _session->_frequ ); - - pthread_mutex_init ( &_session->_mutex, NULL ); - - return _session; -} - -int msi_terminate_session ( msi_session_t* _session ) -{ - assert(_session); - - int _status = 0; - - terminate_event_poll ( _session->_event_handler ); - free ( _session ); - /* TODO: terminate the rest of the session */ - - pthread_mutex_destroy ( &_session->_mutex ); - - return _status; -} - -msi_call_t* msi_init_call ( msi_session_t* _session, int _peers, uint32_t _timeoutms ) -{ - assert(_session); - assert(_peers); - - msi_call_t* _call = calloc ( sizeof ( msi_call_t ), 1 ); - _call->_type_peer = calloc ( sizeof ( call_type ), _peers ); - - assert(_call); - assert(_call->_type_peer); - - _call->_participants = _peers; - _call->_key = _session->_key; - _call->_timeoutst = _timeoutms; - _call->_outgoing_timer_id = 0; - - return _call; -} - -int msi_terminate_call ( msi_session_t* _session ) -{ - assert(_session); - - if ( _session->_call->_type_peer ) - free ( _session->_call->_type_peer ); - - cancel_timer_event(_session->_event_handler, _session->_call->_outgoing_timer_id); - - free ( _session->_call ); - - _session->_call = NULL; - - return SUCCESS; -} -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ - -/* STATE HANDLERS */ - -/* REQUESTS */ -int msi_handle_recv_invite ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - - if ( _session->_call ) { - msi_msg_t* _msg_error = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _error ) ); - msi_msg_set_reason(_msg_error, stringify_error_code(error_busy)); - msi_send_msg(_session, _msg_error); - msi_free_msg(_msg_error); - - return 0; - } - if ( !_msg->_call_id ) { - msi_msg_t* _msg_error = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _error ) ); - msi_msg_set_reason(_msg_error, stringify_error_code(error_no_callid)); - msi_send_msg(_session, _msg_error); - msi_free_msg(_msg_error); - return 0; - } - - _session->_call = msi_init_call ( _session, 1, _session->_call_timeout ); - t_memcpy(_session->_call->_id, _msg->_call_id->_header_value, _CALL_ID_LEN); - _session->_call->_state = call_starting; - - flush_peer_type ( _session, _msg, 0 ); - - msi_msg_t* _msg_ringing = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _ringing ) ); - msi_send_msg ( _session, _msg_ringing ); - msi_free_msg ( _msg_ringing ); - - throw_event ( _session->_event_handler, msi_recv_invite_callback, _session ); - return 1; -} -int msi_handle_recv_start ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - - if ( has_call_error(_session, _msg) == 0 ) - return 0; - - _session->_call->_state = call_active; - - flush_peer_type ( _session, _msg, 0 ); - - throw_event ( _session->_event_handler, msi_start_call_callback, _session ); - return 1; -} -int msi_handle_recv_reject ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - - if ( has_call_error(_session, _msg) == 0 ) - return 0; - - msi_msg_t* _msg_end = msi_msg_new ( TYPE_REQUEST, stringify_request ( _end ) ); - msi_send_msg ( _session, _msg_end ); - msi_free_msg ( _msg_end ); - - throw_event ( _session->_event_handler, msi_reject_call_callback, _session ); - - return 1; -} -int msi_handle_recv_cancel ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - - if ( has_call_error(_session, _msg) == 0 ) - return 0; - - msi_msg_t* _msg_ending = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _ending ) ); - msi_send_msg ( _session, _msg_ending ); - msi_free_msg ( _msg_ending ); - - msi_terminate_call ( _session ); - - throw_event ( _session->_event_handler, msi_cancel_call_callback, _session ); - - return 1; -} -int msi_handle_recv_end ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - - if ( has_call_error(_session, _msg) == 0 ) - return 0; - - msi_msg_t* _msg_ending = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _ending ) ); - msi_send_msg ( _session, _msg_ending ); - msi_free_msg ( _msg_ending ); - - msi_terminate_call ( _session ); - - throw_event ( _session->_event_handler, msi_end_call_callback, _session ); - - return 1; -} -/*--------*/ - -/* RESPONSES */ -int msi_handle_recv_ringing ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - - if ( has_call_error(_session, _msg) == 0 ) - return 0; - - throw_event ( _session->_event_handler, msi_ringing_callback, _session ); - - return 1; -} -int msi_handle_recv_starting ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - - if ( has_call_error(_session, _msg) == 0 ) - return 0; - - _session->_call->_state = call_active; - - msi_msg_t* _msg_start = msi_msg_new ( TYPE_REQUEST, stringify_request ( _start ) ); - msi_send_msg ( _session, _msg_start ); - msi_free_msg ( _msg_start ); - - flush_peer_type ( _session, _msg, 0 ); - - throw_event ( _session->_event_handler, msi_starting_callback, _session ); - cancel_timer_event(_session->_event_handler, _session->_call->_outgoing_timer_id); - _session->_call->_outgoing_timer_id = 0; - - return 1; -} -int msi_handle_recv_ending ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - - if ( has_call_error(_session, _msg) == 0 ) - return 0; - - msi_terminate_call ( _session ); - throw_event ( _session->_event_handler, msi_ending_callback, _session ); - - return 1; -} -int msi_handle_recv_error ( msi_session_t* _session, msi_msg_t* _msg ) -{ - assert(_session); - assert(_session->_call); - - /* Handle error accordingly */ - if ( _msg->_reason ) { - _session->_last_error_id = atoi((const char*)_msg->_reason->_header_value); - _session->_last_error_str = stringify_error(_session->_last_error_id); - } - - msi_terminate_call(_session); - - throw_event ( _session->_event_handler, msi_error_callback, _session ); - - return 1; -} -/* ------------------ */ - -MCBTYPE msi_handle_timeout (void* _arg) -{ - msi_session_t* _session = _arg; - msi_terminate_call(_session); - - (*msi_timeout_callback) (_arg); - (*msi_ending_callback) (_arg); - -} - -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ - -int msi_invite ( msi_session_t* _session, call_type _call_type, uint32_t _timeoutms ) -{ - assert(_session); - - if ( !msi_send_message_callback ) - return 0; - - msi_msg_t* _msg_invite = msi_msg_new ( TYPE_REQUEST, stringify_request ( _invite ) ); - - _session->_call = msi_init_call ( _session, 1, _timeoutms ); /* Just one for now */ - msi_genterate_call_id(_session->_call->_id, _CALL_ID_LEN); - _session->_call->_type_local = _call_type; - /* Do whatever with message */ - - if ( _call_type == type_audio ) { - msi_msg_set_call_type ( _msg_invite, ( const uint8_t* ) CT_AUDIO_HEADER_VALUE ); - } else { - msi_msg_set_call_type ( _msg_invite, ( const uint8_t* ) CT_VIDEO_HEADER_VALUE ); - } - - msi_send_msg ( _session, _msg_invite ); - msi_free_msg ( _msg_invite ); - - _session->_call->_state = call_inviting; - - _session->_call->_outgoing_timer_id = throw_timer_event(_session->_event_handler, msi_handle_timeout, _session, _timeoutms ); - - return 1; -} -int msi_hangup ( msi_session_t* _session ) -{ - assert(_session); - - if ( !_session->_call || ( !msi_send_message_callback && _session->_call->_state != call_active ) ) - return 0; - - msi_msg_t* _msg_ending = msi_msg_new ( TYPE_REQUEST, stringify_request ( _end ) ); - msi_send_msg ( _session, _msg_ending ); - msi_free_msg ( _msg_ending ); - - return 1; -} - - -int msi_answer ( msi_session_t* _session, call_type _call_type ) -{ - assert(_session); - - if ( !msi_send_message_callback || !_session->_call ) - return 0; - - msi_msg_t* _msg_starting = msi_msg_new ( TYPE_RESPONSE, stringify_response ( _starting ) ); - _session->_call->_type_local = _call_type; - - if ( _call_type == type_audio ) { - msi_msg_set_call_type ( _msg_starting, ( const uint8_t* ) CT_AUDIO_HEADER_VALUE ); - } else { - msi_msg_set_call_type ( _msg_starting, ( const uint8_t* ) CT_VIDEO_HEADER_VALUE ); - } - - msi_send_msg ( _session, _msg_starting ); - msi_free_msg ( _msg_starting ); - - _session->_call->_state = call_active; - return 1; -} -int msi_cancel ( msi_session_t* _session ) -{ - assert(_session); - - if ( !_session->_call || !msi_send_message_callback ) - return 0; - - msi_msg_t* _msg_cancel = msi_msg_new ( TYPE_REQUEST, stringify_request ( _cancel ) ); - msi_send_msg ( _session, _msg_cancel ); - msi_free_msg ( _msg_cancel ); - - - - return 1; -} -int msi_reject ( msi_session_t* _session ) -{ - assert(_session); - - if ( !_session->_call || !msi_send_message_callback ) - return 0; - - msi_msg_t* _msg_reject = msi_msg_new ( TYPE_REQUEST, stringify_request ( _reject ) ); - msi_send_msg ( _session, _msg_reject ); - msi_free_msg ( _msg_reject ); - - return 1; -} - -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ - -/* OUR MAIN POOL FUNCTION */ -/* - * Forks it self to other thread and then handles the session initiation. - * - * BASIC call flow: - * - * ALICE BOB - * | invite --> | - * | | - * | <-- ringing | - * | | - * | <-- starting | - * | | - * | start --> | - * | | - * | <-- MEDIA TRANS --> | - * | | - * | end --> | - * | | - * | <-- ending | - * - * Alice calls Bob by sending invite packet. - * Bob recvs the packet and sends an ringing packet; - * which notifies Alice that her invite is acknowledged. - * Ringing screen shown on both sides. - * Bob accepts the invite for a call by sending starting packet. - * Alice recvs the starting packet and sends the started packet to - * inform Bob that she recved the starting packet. - * Now the media transmission is established ( i.e. RTP transmission ). - * Alice hangs up and sends end packet. - * Bob recves the end packet and sends ending packet - * as the acknowledgement that the call is ending. - * - * - */ - - -/* - * Needs a bit more work on the protocol - */ -void* msi_poll_stack ( void* _session_p ) -{ - msi_session_t* _session = ( msi_session_t* ) _session_p; - msi_msg_t* _msg = NULL; - - uint32_t* _frequ = &_session->_frequ; - while ( _session ) { - - /* At this point it's already parsed */ - _msg = receive_message ( _session ); - - if ( _msg ) { - - if ( _msg->_request ) { /* Handle request */ - - const uint8_t* _request_value = _msg->_request->_header_value; - - if ( same ( _request_value, stringify_request ( _invite ) ) ) { - msi_handle_recv_invite ( _session, _msg ); - - } else if ( same ( _request_value, stringify_request ( _start ) ) ) { - msi_handle_recv_start ( _session, _msg ); - - } else if ( same ( _request_value, stringify_request ( _cancel ) ) ) { - msi_handle_recv_cancel ( _session, _msg ); - - } else if ( same ( _request_value, stringify_request ( _reject ) ) ) { - msi_handle_recv_reject ( _session, _msg ); - - } else if ( same ( _request_value, stringify_request ( _end ) ) ) { - msi_handle_recv_end ( _session, _msg ); - } - - } else if ( _msg->_response ) { /* Handle response */ - - const uint8_t* _response_value = _msg->_response->_header_value; - - if ( same ( _response_value, stringify_response ( _ringing ) ) ) { - msi_handle_recv_ringing ( _session, _msg ); - - } else if ( same ( _response_value, stringify_response ( _starting ) ) ) { - msi_handle_recv_starting ( _session, _msg ); - - } else if ( same ( _response_value, stringify_response ( _ending ) ) ) { - msi_handle_recv_ending ( _session, _msg ); - - } else if ( same ( _response_value, stringify_response ( _error ) ) ) { - msi_handle_recv_error ( _session, _msg ); - } - - } - - msi_free_msg ( _msg ); - - } - usleep ( *_frequ ); - } - - return NULL; -} - -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ -/*------------------------*/ - -/* Easy way to start the poll */ - -pthread_t msi_start_main_loop ( msi_session_t* _session, uint32_t _frequms ) -{ - assert(_session); - - int _status; - pthread_t _thread_id; - - - _session->_frequ = _frequms * 1000; - - _status = pthread_create ( &_thread_id, NULL, msi_poll_stack, _session ); - - if ( _status < 0 ) { - printf ( "Error while starting main loop: %d, %s\n", errno, strerror ( errno ) ); - return _status; - } - - _status = pthread_detach ( _thread_id ); - - if ( _status < 0 ) { - printf ( "Error while starting main loop: %d, %s\n", errno, strerror ( errno ) ); - } - - return _thread_id; -} diff --git a/toxmsi/toxmsi.h b/toxmsi/toxmsi.h deleted file mode 100644 index d8985c64..00000000 --- a/toxmsi/toxmsi.h +++ /dev/null @@ -1,145 +0,0 @@ -/* msi_initiation.h -* -* Has function for session initiation along with session description. -* It follows the Tox API ( http://wiki.tox.im/index.php/Messaging_Protocol ). !Red! -* -* -* Copyright (C) 2013 Tox project All Rights Reserved. -* -* This file is part of Tox. -* -* Tox is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Tox is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with Tox. If not, see . -* -*/ - - -#ifndef _MSI_IMPL_H_ -#define _MSI_IMPL_H_ - -#include -#include "tox.h" -#include - -#define MCBTYPE void -#define MCBARGS void* _arg -#define MCALLBACK MCBTYPE(*callback)(void* _arg) - -#define MSI_PACKET 69 - -#define CT_AUDIO_HEADER_VALUE "AUDIO" -#define CT_VIDEO_HEADER_VALUE "VIDEO" - -/* define size for call_id */ -#define _CALL_ID_LEN 12 - -typedef enum { - type_audio = 1, - type_video, -} call_type; - -typedef enum { - call_inviting, /* when sending call invite */ - call_starting, /* when getting call invite */ - call_active, - call_hold - -} call_state; - -typedef int crypto_key; - -typedef struct msi_call_s { /* Call info structure */ - call_state _state; - call_type _type_local; - call_type* _type_peer; /* Support for conference starts with this */ - uint8_t _id[_CALL_ID_LEN]; /* Random value identifying the call */ - crypto_key _key; /* What is the type again? */ - uint16_t _participants; /* Number of participants */ - uint32_t _timeoutst; /* Time of the timeout for some action to end; 0 if infinite */ - int _outgoing_timer_id; /* Timer id */ - -} msi_call_t; - -typedef struct msi_session_s { - pthread_mutex_t _mutex; - - crypto_key _key; /* The key */ - - /* Call information/handler. ( Maybe only information? ) */ - msi_call_t* _call; - - /* Storage for message receiving */ - struct msi_msg_s* _oldest_msg; - struct msi_msg_s* _last_msg; /* tail */ - - /*int _friend_id;*/ - tox_IP_Port _friend_id; - - int _last_error_id; /* Determine the last error */ - const uint8_t* _last_error_str; - - const uint8_t* _user_agent; - - void* _agent_handler; /* Pointer to an object that is handling msi */ - void* _core_handler; /* Pointer to networking core or to anything that - * should handle interaction with core/networking - */ - void* _event_handler; /* Pointer to an object which handles the events */ - - uint32_t _frequ; - uint32_t _call_timeout; /* Time of the timeout for some action to end; 0 if infinite */ -} msi_session_t; - - - -msi_session_t* msi_init_session ( void* _core_handler, const uint8_t* _user_agent ); -int msi_terminate_session ( msi_session_t* _session ); - -pthread_t msi_start_main_loop ( msi_session_t* _session, uint32_t _frequms ); - -/* Registering callbacks */ - -/*void msi_register_callback_send(int (*callback) ( int, uint8_t*, uint32_t ) );*/ -void msi_register_callback_send ( int ( *callback ) ( void* _core_handler, tox_IP_Port, uint8_t*, uint32_t ) ); - -/* Callbacks that handle the states */ -void msi_register_callback_call_started ( MCALLBACK ); -void msi_register_callback_call_canceled ( MCALLBACK ); -void msi_register_callback_call_rejected ( MCALLBACK ); -void msi_register_callback_call_ended ( MCALLBACK ); - -void msi_register_callback_recv_invite ( MCALLBACK ); -void msi_register_callback_recv_ringing ( MCALLBACK ); -void msi_register_callback_recv_starting ( MCALLBACK ); -void msi_register_callback_recv_ending ( MCALLBACK ); -void msi_register_callback_recv_error ( MCALLBACK ); - -void msi_register_callback_requ_timeout ( MCALLBACK ); -/* -------- */ - - -/* Function handling receiving from core */ -/*static int msi_handlepacket ( tox_IP_Port ip_port, uint8_t* _data, uint16_t _lenght ); */ - -/* functions describing the usage of msi */ -int msi_invite ( msi_session_t* _session, call_type _call_type, uint32_t _timeoutms ); -int msi_hangup ( msi_session_t* _session ); - -int msi_answer ( msi_session_t* _session, call_type _call_type ); -int msi_cancel ( msi_session_t* _session ); -int msi_reject ( msi_session_t* _session ); - -int msi_send_msg ( msi_session_t* _session, struct msi_msg_s* _msg ); -void msi_store_msg ( msi_session_t* _session, struct msi_msg_s* _msg ); - -#endif /* _MSI_IMPL_H_ */ diff --git a/toxmsi/toxmsi_event.c b/toxmsi/toxmsi_event.c deleted file mode 100644 index d8c0d269..00000000 --- a/toxmsi/toxmsi_event.c +++ /dev/null @@ -1,214 +0,0 @@ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include - -#include "toxmsi_event.h" - -#include "../toxrtp/toxrtp_helper.h" -#include -#include -#include - -static int _unique_id = 1; - -/* clear events */ -void clear_events (event_container_t** _event_container, size_t* _counter) -{ - assert( *_event_container ); - - free(*_event_container); - *_event_container = NULL; - - *_counter = 0; -} - -int pop_id ( event_container_t** _event_container, size_t* _counter, int _id ) -{ - if ( !*_event_container || !*_counter || !_id ) - return FAILURE; - - event_container_t* _it = *_event_container; - int i; - - for ( i = *_counter; i > 0 ; -- i ){ - if ( _it->_id == _id ) { /* Hit! */ - break; - } - ++_it; - } - - if ( i ) { - for ( ; i > 0; -- i ){ *_it = *(_it + 1); ++_it; } - -- (*_counter); - *_event_container = realloc(*_event_container, sizeof(event_container_t) * (*_counter)); /* resize */ - - if ( *_counter ) - assert(*_event_container); - - return SUCCESS; - - } else { - assert(i); - return FAILURE; - } -} - -/* main poll for event execution */ -void* event_poll( void* _event_handler_p ) -{ - event_handler_t* _event_handler = _event_handler_p; - uint32_t* _frequms = &_event_handler->_frequms; - - - while ( _event_handler->_running ) - { - - if ( _event_handler->_events_count ){ - pthread_mutex_lock(&_event_handler->_mutex); - - int i; - for ( i = 0; i < _event_handler->_events_count; i ++ ){ - _event_handler->_events[i]._event(_event_handler->_events[i]._event_args); - - } - clear_events(&_event_handler->_events, &_event_handler->_events_count); - - pthread_mutex_unlock(&_event_handler->_mutex); - } - - if ( _event_handler->_timed_events_count ){ - pthread_mutex_lock(&_event_handler->_mutex); - - uint32_t _time = t_time(); - - if ( _event_handler->_timed_events[0]._timeout < _time ) { - _event_handler->_timed_events[0]._event(_event_handler->_timed_events[0]._event_args); - - pop_id(&_event_handler->_timed_events, - &_event_handler->_timed_events_count, - _event_handler->_timed_events[0]._id); - } - pthread_mutex_unlock(&_event_handler->_mutex); - } - - - usleep(*_frequms); - } - - _event_handler->_running = -1; - pthread_exit(NULL); -} - -void push_event ( event_container_t** _container, size_t* _counter, event_t _func, event_arg_t _arg ) -{ - (*_counter)++; - (*_container) = realloc((*_container), sizeof(event_container_t) * (*_counter)); - assert((*_container) != NULL); - - (*_container[*_counter - 1])._event = _func; - (*_container[*_counter - 1])._event_args = _arg; - (*_container[*_counter - 1])._timeout = 0; - (*_container[*_counter - 1])._id = 0; -} - -void throw_event( void* _event_handler_p, event_t _func, event_arg_t _arg ) -{ - if ( !_func ) - return; - - event_handler_t* _event_handler = _event_handler_p; - - pthread_mutex_lock(&_event_handler->_mutex); - - push_event(&_event_handler->_events, &_event_handler->_events_count, _func, _arg); - - pthread_mutex_unlock(&_event_handler->_mutex); -} - -int throw_timer_event ( void* _event_handler_p, event_t _func, event_arg_t _arg, uint32_t _timeout) -{ - if ( !_func ) - return FAILURE; - - event_handler_t* _event_handler = _event_handler_p; - - pthread_mutex_lock(&_event_handler->_mutex); - - push_event(&_event_handler->_timed_events, &_event_handler->_timed_events_count, _func, _arg); - size_t _counter = _event_handler->_timed_events_count; - _event_handler->_timed_events[_counter - 1]._timeout = _timeout + t_time(); - _event_handler->_timed_events[_counter - 1]._id = _unique_id; ++_unique_id; - - - /* reorder */ - if ( _counter > 1 ) { - - int i = _counter - 1; - /* start from behind excluding last added member */ - event_container_t* _it = &_event_handler->_timed_events[i - 1]; - - event_container_t _last_added = _event_handler->_timed_events[i]; - - for ( ; i > 0; --i ) { - if ( _it->_timeout > _timeout ){ - *(_it + 1) = *_it; - *_it = _last_added; -- _it; - } - } - - } - - pthread_mutex_unlock(&_event_handler->_mutex); - - return _event_handler->_timed_events[_counter - 1]._id; -} -int cancel_timer_event ( void* _event_handler_p, int _id ) -{ - event_handler_t* _event_handler = _event_handler_p; - return pop_id(&_event_handler->_timed_events, &_event_handler->_timed_events_count, _id); -} - -event_handler_t* init_event_poll (uint32_t _frequms) -{ - event_handler_t* _retu = calloc(sizeof(event_handler_t), 1); - assert(_retu); - /* Initialize basic events */ - _retu->_events = NULL ; - - /* Initialize timed events */ - _retu->_timed_events = NULL; - - _retu->_frequms = _frequms; - _retu->_running = 1; - pthread_mutex_init(&_retu->_mutex, NULL); - - pthread_create(&_retu->_thread_id, NULL, event_poll, _retu); - int _rc = pthread_detach(_retu->_thread_id); - assert(_rc == 0); - - return _retu; -} - -int terminate_event_poll(event_handler_t* _handler) -{ - if ( !_handler ) - return FAILURE; - - _handler->_running = 0; - while (_handler->_running != -1); /* Wait for execution */ - - if (_handler->_events) - clear_events(&_handler->_events, &_handler->_events_count); - if (_handler->_events) - clear_events(&_handler->_timed_events, &_handler->_timed_events_count); - - pthread_mutex_destroy( &_handler->_mutex ); - - free(_handler); - - return SUCCESS; -} - diff --git a/toxmsi/toxmsi_event.h b/toxmsi/toxmsi_event.h deleted file mode 100644 index 032e4df5..00000000 --- a/toxmsi/toxmsi_event.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _MSI__EVENT_H_ -#define _MSI__EVENT_H_ - -#include -#include -#include - -typedef void* event_arg_t; - -typedef void ( *event_t ) ( event_arg_t ); -typedef void ( *timed_event_t ) ( event_arg_t ); - -typedef struct event_container_s { - event_t _event; - event_arg_t _event_args; - uint32_t _timeout; - long long _id; - -} event_container_t; - -typedef struct event_handler_s { - event_container_t* _events; - size_t _events_count; - - event_container_t* _timed_events; - size_t _timed_events_count; - - uint32_t _frequms; - int _running; - - pthread_mutex_t _mutex; - pthread_t _thread_id; - -} event_handler_t; - -event_handler_t* init_event_poll ( uint32_t _frequms ); -int terminate_event_poll ( event_handler_t* _event_handler ); - -void throw_event ( void* _event_handler_p, event_t _func, event_arg_t _arg ); - -/* Not yet ready for use */ -int throw_timer_event ( void* _event_handler_p, event_t _func, event_arg_t _arg, uint32_t _timeout); -int cancel_timer_event ( void* _event_handler_p, int _id ); - - -#endif /* _MSI__EVENT_H_ */ diff --git a/toxmsi/toxmsi_header.c b/toxmsi/toxmsi_header.c deleted file mode 100644 index 448ebc7f..00000000 --- a/toxmsi/toxmsi_header.c +++ /dev/null @@ -1,181 +0,0 @@ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "toxmsi_message.h" -#include -#include "../toxrtp/toxrtp_helper.h" -#include -#include "../toxcore/Lossless_UDP.h" - -#define ALLOC_ADD_DATA(_tempval, _hdrlist, _fielddef, _msgvar, _alloctype) \ -_tempval = msi_search_field(_hdrlist, (const uint8_t*)_fielddef); \ -if ( _tempval ){ \ - _msgvar = calloc(sizeof(_alloctype), 1); \ - assert(_msgvar); \ - _msgvar->_header_value = _tempval; \ -} - -uint8_t* msi_search_field ( msi_header_t* _list, const uint8_t* _field ) -{ - assert(_list); - assert(_field); - - msi_header_t* _iterator; - - for ( _iterator = _list; - _iterator && strcmp((const char*)_iterator->_header_field, (const char*)_field) != 0; - _iterator = _iterator->next ); - - if ( _iterator ){ - return t_strallcpy(_iterator->_header_value); - } else return NULL; -} - -int msi_parse_headers ( msi_msg_t* _msg ) -{ - assert(_msg); - - if ( !_msg->_headers ) - return FAILURE; - - msi_header_t* _list = _msg->_headers; - uint8_t* _field_current; - - ALLOC_ADD_DATA(_field_current, _list, _CALL_ID_FIELD, _msg->_call_id, msi_header_call_id_t) - ALLOC_ADD_DATA(_field_current, _list, _VERSION_FIELD, _msg->_version, msi_header_version_t) - ALLOC_ADD_DATA(_field_current, _list, _REQUEST_FIELD, _msg->_request, msi_header_request_t) - ALLOC_ADD_DATA(_field_current, _list, _RESPONSE_FIELD, _msg->_response, msi_header_response_t) - ALLOC_ADD_DATA(_field_current, _list, _FRIENDID_FIELD, _msg->_friend_id, msi_header_friendid_t) - ALLOC_ADD_DATA(_field_current, _list, _CALLTYPE_FIELD, _msg->_call_type, msi_header_call_type_t) - ALLOC_ADD_DATA(_field_current, _list, _USERAGENT_FIELD, _msg->_user_agent, msi_header_user_agent_t) - ALLOC_ADD_DATA(_field_current, _list, _INFO_FIELD, _msg->_info, msi_header_info_t) - ALLOC_ADD_DATA(_field_current, _list, _REASON_FIELD, _msg->_reason, msi_header_reason_t) - - /* Since we don't need the raw header anymore remove it */ - msi_header_t* _temp; - while ( _list ){ - _temp = _list->next; - free(_list->_header_field); - free(_list->_header_value); - free(_list); - _list = _temp; - } - - _msg->_headers = NULL; - - return SUCCESS; -} - -/* - * If you find better way of parsing values let me know - */ -msi_header_t* msi_add_new_header ( uint8_t* _value ) -{ - if ( !_value ) - return NULL; - - size_t _length = t_memlen(_value); - - if ( !_length ) { - return NULL; - } - - size_t _first_len = t_strfind(_value, (const uint8_t*)" "); - if ( !_first_len ){ - return NULL; - } - - size_t _second_len = (_length - _first_len); - if ( !_second_len ){ - return NULL; - } - - - uint8_t* _identifier = calloc(sizeof (uint8_t), (_first_len + 1) ); - uint8_t* _data = calloc(sizeof (uint8_t), (_second_len + 1) ); - - assert(_identifier); - assert(_data); - - - uint8_t* _p_it = _value; - size_t _num_it; - - for ( _num_it = 0; *_p_it != ' '; _num_it++ ){ - _identifier[_num_it] = *_p_it; - ++_p_it; - } - _identifier[_num_it] = '\0'; - ++_p_it; - - - for ( _num_it = 0; *_p_it != '\r'; _num_it++ ){ - _data[_num_it] = *_p_it; - ++_p_it; - } - _data[_num_it] = '\r'; - _data[_num_it + 1] = '\0'; - - msi_header_t* _retu = calloc(sizeof(msi_header_t), 1); - assert(_retu); - - _retu->_header_field = _identifier; - _retu->_header_value = _data; - - _retu->next = NULL; - - return _retu; -} - -msi_header_t* msi_parse_raw_data ( const uint8_t* _data ) -{ - assert(_data); - - uint8_t* _header_string; - - _header_string = (uint8_t*) strtok ((char*)_data, _RAW_TERMINATOR); - - msi_header_t* _head = msi_add_new_header(_header_string); - msi_header_t* _it = _head; - - while ( _header_string && _it ){ - - _header_string = (uint8_t*) strtok (NULL, _RAW_TERMINATOR); - _it->next = msi_add_new_header(_header_string); - if ( _it->next ){ - _it = _it->next; - } - } - - /* Iterate through list and remove all fault headers if any */ - - msi_header_t* _tmp = _it; - - for ( _it = _head; _it; _it = _it->next ){ - - if ( !_it->_header_value || !_it->_header_field ) { - _tmp ->next = _it->next; - - if ( _it->_header_field ) - free(_it->_header_field); - if ( _it->_header_value ) - free(_it->_header_value); - - if ( _it == _head ){ - _head = _head->next; - } - - free(_it); - _it = _tmp; - } else - _tmp = _it; - - } - - return _head; -} - - - diff --git a/toxmsi/toxmsi_header.h b/toxmsi/toxmsi_header.h deleted file mode 100644 index 599fafa3..00000000 --- a/toxmsi/toxmsi_header.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef _MSI_HEADER_ -#define _MSI_HEADER_ - -/* Basic format of the unparsed header string - * ( No spaces in field allowed ) - * Version 0.1.1\n\r - * Request INVITE\n\r - * Response\n\r - * Friend-id ( from ip )\n\r - * Call-type AUDIO\n\r - * User-agent phone-v.1.0.0\n\r - */ - - -/* define raw header terminator */ -static const char* _RAW_TERMINATOR = "\n\r"; - -/* define string formats for the identifiers */ -#define _VERSION_FIELD "Version" -#define _REQUEST_FIELD "Request" -#define _RESPONSE_FIELD "Response" -#define _FRIENDID_FIELD "Friend-id" -#define _CALLTYPE_FIELD "Call-type" -#define _USERAGENT_FIELD "User-agent" -#define _INFO_FIELD "INFO" -#define _REASON_FIELD "Reason" -#define _CALL_ID_FIELD "Call-id" - -#define HEADER_VALUES \ -/*uint8_t* _header_field */ \ -uint8_t* _header_value; - -typedef struct msi_header_s { /* raw header list */ - uint8_t* _header_field; - uint8_t* _header_value; - - struct msi_header_s* next; - -} msi_header_t; - - - -typedef struct msi_header_version_s { /* Defines our version */ - HEADER_VALUES - -} msi_header_version_t; - -typedef struct msi_header_request_s { /* Defines our request */ - HEADER_VALUES - -} msi_header_request_t; - -typedef struct msi_header_response_s { /* Defines our response */ - HEADER_VALUES - -} msi_header_response_t; - -typedef struct msi_header_friendid_s { /* Defines source that sent the message */ - HEADER_VALUES - -} msi_header_friendid_t; - -typedef struct msi_header_call_type_s { /* Defines the type of the call */ - HEADER_VALUES - -} msi_header_call_type_t; - -typedef struct msi_header_user_agent_s { /* Defines the device of the participant */ - HEADER_VALUES - -} msi_header_user_agent_t; - - -typedef struct msi_header_call_id_s { /* Call id that is used to identify the call */ - HEADER_VALUES - -} msi_header_call_id_t; - -typedef struct msi_header_info_s { /* Defines informational message header */ - HEADER_VALUES - -} msi_header_info_t; - -typedef struct msi_header_reason_s { /* Defines reason mostly for error messages */ - HEADER_VALUES - -} msi_header_reason_t; - -struct msi_msg_s; - -/* - * Parses the header list to header types - */ -int msi_parse_headers ( struct msi_msg_s* _msg ); - -/* Make sure it's null terminated */ -msi_header_t* msi_parse_raw_data ( const uint8_t* _data ); - -#endif /* _MSI_HEADER_ */ diff --git a/toxmsi/toxmsi_message.c b/toxmsi/toxmsi_message.c deleted file mode 100644 index 72d7ee01..00000000 --- a/toxmsi/toxmsi_message.c +++ /dev/null @@ -1,267 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "toxmsi_message.h" -#include -#include -#include "../toxrtp/toxrtp_helper.h" -#include -#include - -#define ALLOCATE_HEADER(_header_type, _var, _m_header_value) \ -_var = calloc( sizeof(_header_type), 1 ); \ -assert(_var); \ -_var->_header_value = t_strallcpy((const uint8_t*)_m_header_value); - -#define DEALLOCATE_HEADER(_header) \ -if ( _header && _header->_header_value ) { \ -free( _header->_header_value ); \ -free( _header ); } - -#define SET_HEADER(_header_type, _var, _m_header_value) \ -if ( _var ){ \ -free(_var->_header_value); \ -free(_var);} \ -ALLOCATE_HEADER( _header_type, _var, _m_header_value ) - - -/* Sets empty message - */ -void set_msg ( msi_msg_t* _msg ) -{ - _msg->_call_type = NULL; - _msg->_version = NULL; - _msg->_request = NULL; - _msg->_response = NULL; - _msg->_friend_id = NULL; - _msg->_user_agent = NULL; - _msg->_call_id = NULL; - _msg->_reason = NULL; - _msg->_info = NULL; - _msg->_next = NULL; - _msg->_headers = NULL; -} - -void msi_free_msg ( msi_msg_t* _msg ) -{ - assert(_msg); - - DEALLOCATE_HEADER(_msg->_call_type); - DEALLOCATE_HEADER(_msg->_friend_id); - DEALLOCATE_HEADER(_msg->_request); - DEALLOCATE_HEADER(_msg->_response); - DEALLOCATE_HEADER(_msg->_user_agent); - DEALLOCATE_HEADER(_msg->_version); - DEALLOCATE_HEADER(_msg->_info); - DEALLOCATE_HEADER(_msg->_reason); - DEALLOCATE_HEADER(_msg->_call_id); - - free(_msg); -} - -void append_header_to_string ( uint8_t* _dest, const uint8_t* _header_field, const uint8_t* _header_value ) -{ - assert(_dest); - assert(_header_value); - assert(_header_field); - - size_t _dest_len = t_memlen(_dest); - - uint8_t* _storage_iterator = _dest + _dest_len; - const uint8_t* _header_fit = _header_field; - const uint8_t* _header_val = _header_value; - const uint8_t* _term_it = (const uint8_t*) _RAW_TERMINATOR; - - while ( *_header_fit ){ - *_storage_iterator = *_header_fit; - ++_header_fit; - ++_storage_iterator; - } - - *_storage_iterator = ' '; /* place space */ - ++_storage_iterator; - - while ( *_header_val ){ - *_storage_iterator = *_header_val; - ++_header_val; - ++_storage_iterator; - } - - while ( *_term_it ){ - *_storage_iterator = *_term_it; - ++_term_it; - ++_storage_iterator; - } -} - -msi_msg_t* msi_parse_msg ( const uint8_t* _data ) -{ - assert(_data); - - msi_msg_t* _retu = calloc ( sizeof ( msi_msg_t ), 1 ); - assert(_retu); - - set_msg(_retu); - - _retu->_headers = msi_parse_raw_data ( _data ); - - if ( msi_parse_headers (_retu) == FAILURE ) { - msi_free_msg(_retu); - return NULL; - } - - if ( !_retu->_version || strcmp((const char*)_retu->_version->_header_value, VERSION_STRING) != 0 ){ - msi_free_msg(_retu); - return NULL; - } - - return _retu; -} - - -uint8_t* msi_msg_to_string ( msi_msg_t* _msg ) -{ - assert(_msg); - - uint8_t* _retu = calloc(sizeof(uint8_t), MSI_MAXMSG_SIZE ); - assert(_retu); - - t_memset(_retu, '\0', MSI_MAXMSG_SIZE); - - if ( _msg->_version ){ - append_header_to_string(_retu, (const uint8_t*)_VERSION_FIELD, _msg->_version->_header_value); - } - - if ( _msg->_request ){ - append_header_to_string(_retu, (const uint8_t*)_REQUEST_FIELD, _msg->_request->_header_value); - } - - if ( _msg->_response ){ - append_header_to_string(_retu, (const uint8_t*)_RESPONSE_FIELD, _msg->_response->_header_value); - } - - if ( _msg->_friend_id ){ - append_header_to_string(_retu, (const uint8_t*)_FRIENDID_FIELD, _msg->_friend_id->_header_value); - } - - if ( _msg->_call_type ){ - append_header_to_string(_retu, (const uint8_t*)_CALLTYPE_FIELD, _msg->_call_type->_header_value); - } - - if ( _msg->_user_agent ){ - append_header_to_string(_retu, (const uint8_t*)_USERAGENT_FIELD, _msg->_user_agent->_header_value); - } - - if ( _msg->_info ){ - append_header_to_string(_retu, (const uint8_t*)_INFO_FIELD, _msg->_info->_header_value); - } - - if ( _msg->_call_id ){ - append_header_to_string(_retu, (const uint8_t*)_CALL_ID_FIELD, _msg->_call_id->_header_value); - } - - if ( _msg->_reason ){ - append_header_to_string(_retu, (const uint8_t*)_REASON_FIELD, _msg->_reason->_header_value); - } - - return _retu; -} - -msi_msg_t* msi_msg_new ( uint8_t _type, const uint8_t* _typeid ) -{ - msi_msg_t* _retu = calloc ( sizeof ( msi_msg_t ), 1 ); - assert(_retu); - - set_msg(_retu); - - if ( _type == TYPE_REQUEST ){ - ALLOCATE_HEADER( msi_header_request_t, _retu->_request, _typeid ) - _retu->_response = NULL; - - } else if ( _type == TYPE_RESPONSE ) { - ALLOCATE_HEADER( msi_header_response_t, _retu->_response, _typeid ) - _retu->_request = NULL; - - } else { - msi_free_msg(_retu); - return NULL; - } - - - ALLOCATE_HEADER( msi_header_version_t, _retu->_version, VERSION_STRING) - - _retu->_friend_id = NULL; - _retu->_call_type = NULL; - _retu->_user_agent = NULL; - _retu->_info = NULL; - - _retu->_next = NULL; - - return _retu; -} - -uint8_t* msi_genterate_call_id ( uint8_t* _storage, size_t _len ) -{ - assert(_storage); - - static const char _alphanum[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; /* avoids warning */ - - uint8_t _val = 0; - size_t _it; - - /* Generate random values 1-255 */ - for ( _it = 0; _it < _len; _it ++ ) { - while ( !_val ) _val = (uint8_t) _alphanum[ t_random(61) ]; - - _storage[_it] = _val; - _val = 0; - } - - return _storage; -} - -/* HEADER SETTING - */ - -void msi_msg_set_call_type ( msi_msg_t* _msg, const uint8_t* _header_field ) -{ - assert(_msg); - assert(_header_field); - - SET_HEADER(msi_header_call_type_t, _msg->_call_type, _header_field) -} -void msi_msg_set_user_agent ( msi_msg_t* _msg, const uint8_t* _header_field ) -{ - assert(_msg); - assert(_header_field); - - SET_HEADER(msi_header_user_agent_t, _msg->_user_agent, _header_field) -} -void msi_msg_set_friend_id ( msi_msg_t* _msg, const uint8_t* _header_field ) -{ - assert(_msg); - assert(_header_field); - - SET_HEADER(msi_header_friendid_t, _msg->_friend_id, _header_field) -} -void msi_msg_set_info ( msi_msg_t* _msg, const uint8_t* _header_field ) -{ -} -void msi_msg_set_reason ( msi_msg_t* _msg, const uint8_t* _header_field ) -{ - assert(_msg); - assert(_header_field); - - SET_HEADER(msi_header_reason_t, _msg->_reason, _header_field) -} -void msi_msg_set_call_id ( msi_msg_t* _msg, const uint8_t* _header_field ) -{ - assert(_msg); - assert(_header_field); - - SET_HEADER(msi_header_call_id_t, _msg->_call_id, _header_field) -} diff --git a/toxmsi/toxmsi_message.h b/toxmsi/toxmsi_message.h deleted file mode 100644 index 87dfccc2..00000000 --- a/toxmsi/toxmsi_message.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef _MSI_MESSAGE_H_ -#define _MSI_MESSAGE_H_ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include "../toxcore/network.h" -#include "../toxcore/tox.h" - -#include "toxmsi_header.h" - -#define TYPE_REQUEST 1 -#define TYPE_RESPONSE 2 - -#define VERSION_STRING "0.2.2" - -#define MSI_MAXMSG_SIZE 65535 - -typedef enum { - _invite, - _start, - _cancel, - _reject, - _end, - -} msi_request_t; - -static inline const uint8_t *stringify_request(msi_request_t _request) -{ - static const uint8_t* strings[] = - { - (uint8_t*)"INVITE", - (uint8_t*)"START", - (uint8_t*)"CANCEL", - (uint8_t*)"REJECT", - (uint8_t*)"END" - }; - - return strings[_request]; -} - -typedef enum { - _trying, - _ringing, - _starting, - _ending, - _error - -} msi_response_t; - -static inline const uint8_t *stringify_response(msi_response_t _response) -{ - static const uint8_t* strings[] = - { - (uint8_t*)"trying", - (uint8_t*)"ringing", - (uint8_t*)"starting", - (uint8_t*)"ending", - (uint8_t*)"error" - }; - - return strings[_response]; -} - - -typedef struct msi_msg_s { - /* This is the header list which contains unparsed headers */ - msi_header_t* _headers; - - /* Headers parsed */ - msi_header_version_t* _version; - msi_header_request_t* _request; - msi_header_response_t* _response; - msi_header_friendid_t* _friend_id; - msi_header_call_type_t* _call_type; - msi_header_user_agent_t* _user_agent; - msi_header_info_t* _info; - msi_header_reason_t* _reason; - msi_header_call_id_t* _call_id; - - /* Pointer to next member since it's list duuh */ - struct msi_msg_s* _next; - -} msi_msg_t; - - -/* - * Parse data received from socket - */ -msi_msg_t* msi_parse_msg ( const uint8_t* _data ); - -/* - * Make new message. Arguments: _type: (request, response); _type_field ( value ) - */ -msi_msg_t* msi_msg_new ( uint8_t _type, const uint8_t* _type_field ); - -/* Header setting */ -void msi_msg_set_call_type ( msi_msg_t* _msg, const uint8_t* _header_field ); -void msi_msg_set_user_agent ( msi_msg_t* _msg, const uint8_t* _header_field ); -void msi_msg_set_friend_id ( msi_msg_t* _msg, const uint8_t* _header_field ); -void msi_msg_set_info ( msi_msg_t* _msg, const uint8_t* _header_field ); -void msi_msg_set_reason ( msi_msg_t* _msg, const uint8_t* _header_field ); -void msi_msg_set_call_id ( msi_msg_t* _msg, const uint8_t* _header_field ); - - -uint8_t* msi_genterate_call_id ( uint8_t* _storage, size_t _len ); -/* - * Parses message struct to string. - * Allocates memory so don't forget to free it - */ -uint8_t* msi_msg_to_string ( msi_msg_t* _msg ); - -/* - * msi_msg_s struct deallocator - */ -void msi_free_msg ( msi_msg_t* _msg ); - -#endif /* _MSI_MESSAGE_H_ */ -- cgit v1.2.3