diff --git a/toxav/phone.c b/toxav/phone.c
new file mode 100755
index 00000000..b55a072c
--- /dev/null
+++ b/toxav/phone.c
@@ -0,0 +1,737 @@
+/** phone.c
+ *
+ * NOTE NOTE NOTE NOTE NOTE NOTE
+ *
+ * This file is for testing/reference purposes only, hence
+ * it is _poorly_ designed and it does not fully reflect the
+ * quaility of msi nor rtp. Although toxmsi* and toxrtp* are tested
+ * there is always possiblity of crashes. If crash occures,
+ * contact me ( mannol ) on either irc channel #tox-dev @ freenode.net:6667
+ * or eniz_vukovic@hotmail.com
+ *
+ * NOTE NOTE NOTE NOTE NOTE NOTE
+ *
+ * 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 */
+
+#define _BSD_SOURCE
+#define _GNU_SOURCE
+
+#include
+#include
+#include
+
+#include "toxmsi.h"
+#include "toxrtp.h"
+#include
+#include
+#include
+
+#include "../toxcore/network.h"
+#include "../toxcore/event.h"
+#include "../toxcore/tox.h"
+
+/* Define client version */
+#define _USERAGENT "v.0.3.0"
+
+
+typedef struct av_friend_s {
+ int _id;
+ int _active; /* 0=false; 1=true; */
+} av_friend_t;
+
+typedef struct av_session_s {
+ MSISession* _msi;
+
+ RTPSession* _rtp_audio;
+ RTPSession* _rtp_video;
+
+ pthread_mutex_t _mutex;
+
+ Tox* _messenger;
+ av_friend_t* _friends;
+ int _friend_cout;
+ uint8_t _my_public_id[200];
+} av_session_t;
+
+
+void av_allocate_friend(av_session_t* _phone, int _id, int _active)
+{
+ static int _new_id = 0;
+
+ if ( !_phone->_friends ) {
+ _phone->_friends = calloc(sizeof(av_friend_t), 1);
+ _phone->_friend_cout = 1;
+ } else{
+ _phone->_friend_cout ++;
+ _phone->_friends = realloc(_phone->_friends, sizeof(av_friend_t) * _phone->_friend_cout);
+ }
+
+ if ( _id = -1 ) {
+ _phone->_friends->_id = _new_id;
+ _new_id ++;
+ } else _phone->_friends->_id = _id;
+
+ _phone->_friends->_active = _active;
+}
+av_friend_t* av_get_friend(av_session_t* _phone, int _id)
+{
+ av_friend_t* _friends = _phone->_friends;
+
+ if ( !_friends ) return NULL;
+
+ int _it = 0;
+ for (; _it < _phone->_friend_cout; _it ++)
+ if ( _friends[_it]._id == _id )
+ return _friends + _it;
+
+ return NULL;
+}
+
+
+/***************** MISC *****************/
+
+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);
+}
+
+unsigned char *hex_string_to_bin(char hex_string[])
+{
+ size_t i, len = strlen(hex_string);
+ unsigned char *val = calloc(sizeof(char), len);
+ char *pos = hex_string;
+
+ for (i = 0; i < len; ++i, pos += 2)
+ sscanf(pos, "%2hhx", &val[i]);
+
+ return val;
+}
+
+int getinput( char* _buff, size_t _limit, int* _len )
+{
+ if ( fgets(_buff, _limit, stdin) == NULL )
+ return -1;
+
+ *_len = strlen(_buff) - 1;
+
+ /* Get rid of newline */
+ _buff[*_len] = '\0';
+
+ return 0;
+}
+
+char* trim_spaces ( char* buff )
+{
+
+ int _i = 0, _len = strlen(buff);
+
+ char* container = calloc(sizeof(char), _len);
+ int _ci = 0;
+
+ for ( ; _i < _len; _i++ ) {
+ while ( _i < _len && buff[_i] == ' ' )
+ _i++;
+
+ if ( _i < _len ){
+ container[_ci] = buff[_i];
+ _ci ++;
+ }
+ }
+
+ memcpy( buff, container, _ci );
+ buff[_ci] = '\0';
+ free(container);
+ return buff;
+}
+
+#define FRADDR_TOSTR_CHUNK_LEN 8
+
+static void fraddr_to_str(uint8_t *id_bin, char *id_str)
+{
+ uint i, delta = 0, pos_extra, sum_extra = 0;
+
+ for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; i++) {
+ sprintf(&id_str[2 * i + delta], "%02hhX", id_bin[i]);
+
+ if ((i + 1) == TOX_CLIENT_ID_SIZE)
+ pos_extra = 2 * (i + 1) + delta;
+
+ if (i >= TOX_CLIENT_ID_SIZE)
+ sum_extra |= id_bin[i];
+
+ if (!((i + 1) % FRADDR_TOSTR_CHUNK_LEN)) {
+ id_str[2 * (i + 1) + delta] = ' ';
+ delta++;
+ }
+ }
+
+ id_str[2 * i + delta] = 0;
+
+ if (!sum_extra)
+ id_str[pos_extra] = 0;
+}
+
+void* phone_handle_media_transport_poll ( void* _hmtc_args_p )
+{
+ RTPMessage* _audio_msg, * _video_msg;
+ av_session_t* _phone = _hmtc_args_p;
+ MSISession* _session = _phone->_msi;
+
+ RTPSession* _rtp_audio = _phone->_rtp_audio;
+ RTPSession* _rtp_video = _phone->_rtp_video;
+
+
+ Tox* _messenger = _phone->_messenger;
+
+
+ while ( _session->call ) {
+
+ _audio_msg = rtp_recv_msg ( _rtp_audio );
+ _video_msg = rtp_recv_msg ( _rtp_video );
+
+ if ( _audio_msg ) {
+ /* Do whatever with msg
+ printf("%d - %s\n", _audio_msg->header->sequnum, _audio_msg->data);*/
+ rtp_free_msg ( _rtp_audio, _audio_msg );
+ }
+
+ if ( _video_msg ) {
+ /* Do whatever with msg
+ p rintf("%d - %s\n", _video_msg->header->sequnum, _video_msg->data);*/
+ rtp_free_msg ( _rtp_video, _video_msg );
+ }
+
+ /*
+ * Send test message to the 'remote'
+ */
+ rtp_send_msg ( _rtp_audio, _messenger, (const uint8_t*)"audio\0", 6 );
+
+ if ( _session->call->type_local == type_video ){ /* if local call send video */
+ rtp_send_msg ( _rtp_video, _messenger, (const uint8_t*)"video\0", 6 );
+ }
+
+ _audio_msg = _video_msg = NULL;
+
+
+ /* Send ~1k messages per second
+ * That _should_ be enough for both Audio and Video
+ */
+ usleep ( 1000 );
+ /* -------------------- */
+ }
+
+ if ( _audio_msg ) rtp_free_msg(_rtp_audio, _audio_msg);
+ rtp_release_session_recv(_rtp_audio);
+ rtp_terminate_session(_rtp_audio, _messenger);
+
+ if ( _video_msg ) rtp_free_msg(_rtp_video, _video_msg);
+ rtp_release_session_recv(_rtp_video);
+ rtp_terminate_session(_rtp_video, _messenger);
+
+ INFO("Media thread finished!");
+
+ pthread_exit ( NULL );
+}
+
+int phone_startmedia_loop ( av_session_t* _phone )
+{
+ if ( !_phone ){
+ return -1;
+ }
+
+ _phone->_rtp_audio = rtp_init_session (
+ type_audio,
+ _phone->_messenger,
+ _phone->_msi->call->peers[0],
+ _phone->_msi->call->key_peer,
+ _phone->_msi->call->key_local,
+ _phone->_msi->call->nonce_peer,
+ _phone->_msi->call->nonce_local
+ );
+
+ _phone->_rtp_audio = rtp_init_session (
+ type_video,
+ _phone->_messenger,
+ _phone->_msi->call->peers[0],
+ _phone->_msi->call->key_peer,
+ _phone->_msi->call->key_local,
+ _phone->_msi->call->nonce_peer,
+ _phone->_msi->call->nonce_local
+ );
+
+
+ if ( 0 > event.rise(phone_handle_media_transport_poll, _phone) )
+ {
+ printf("Error while starting phone_handle_media_transport_poll()\n");
+ return -1;
+ }
+ else return 0;
+}
+
+
+/* Some example callbacks */
+
+void* callback_recv_invite ( void* _arg )
+{
+ const char* _call_type;
+
+ MSISession* _msi = _arg;
+
+ switch ( _msi->call->type_peer[_msi->call->peer_count - 1] ){
+ case type_audio:
+ _call_type = "audio";
+ break;
+ case type_video:
+ _call_type = "video";
+ break;
+ }
+
+ INFO( "Incoming %s call!", _call_type );
+
+}
+void* callback_recv_ringing ( void* _arg )
+{
+ INFO ( "Ringing!" );
+}
+void* callback_recv_starting ( void* _arg )
+{
+ MSISession* _session = _arg;
+ if ( 0 != phone_startmedia_loop(_session->agent_handler) ){
+ INFO("Starting call failed!");
+ } else {
+ INFO ("Call started! ( press h to hangup )");
+ }
+}
+void* callback_recv_ending ( void* _arg )
+{
+ INFO ( "Call ended!" );
+}
+
+void* callback_recv_error ( void* _arg )
+{
+ MSISession* _session = _arg;
+
+ INFO( "Error: %s", _session->last_error_str );
+}
+
+void* callback_call_started ( void* _arg )
+{
+ MSISession* _session = _arg;
+ if ( 0 != phone_startmedia_loop(_session->agent_handler) ){
+ INFO("Starting call failed!");
+ } else {
+ INFO ("Call started! ( press h to hangup )");
+ }
+
+}
+void* callback_call_canceled ( void* _arg )
+{
+ INFO ( "Call canceled!" );
+}
+void* callback_call_rejected ( void* _arg )
+{
+ INFO ( "Call rejected!" );
+}
+void* callback_call_ended ( void* _arg )
+{
+ INFO ( "Call ended!" );
+}
+
+void* callback_requ_timeout ( void* _arg )
+{
+ INFO( "No answer! " );
+}
+
+int av_connect_to_dht(av_session_t* _phone, char* _dht_key, const char* _dht_addr, unsigned short _dht_port)
+{
+ unsigned char *_binary_string = hex_string_to_bin(_dht_key);
+
+ uint16_t _port = htons(_dht_port);
+
+ int _if = tox_bootstrap_from_address(_phone->_messenger, _dht_addr, 1, _port, _binary_string );
+
+ free(_binary_string);
+
+ return _if ? 0 : -1;
+}
+
+av_session_t* av_init_session()
+{
+ av_session_t* _retu = malloc(sizeof(av_session_t));
+
+ /* Initialize our mutex */
+ pthread_mutex_init ( &_retu->_mutex, NULL );
+
+ _retu->_messenger = tox_new(1);
+
+ if ( !_retu->_messenger ) {
+ fprintf ( stderr, "tox_new() failed!\n" );
+ return NULL;
+ }
+
+ _retu->_friends = NULL;
+
+ _retu->_rtp_audio = NULL;
+ _retu->_rtp_video = NULL;
+
+ uint8_t _byte_address[TOX_FRIEND_ADDRESS_SIZE];
+ tox_get_address(_retu->_messenger, _byte_address );
+ fraddr_to_str( _byte_address, _retu->_my_public_id );
+
+
+ /* Initialize msi */
+ _retu->_msi = msi_init_session ( _retu->_messenger, _USERAGENT );
+
+ if ( !_retu->_msi ) {
+ fprintf ( stderr, "msi_init_session() failed\n" );
+ return NULL;
+ }
+
+ _retu->_msi->agent_handler = _retu;
+
+ /* ------------------ */
+ msi_register_callback(callback_call_started, cb_onstart);
+ msi_register_callback(callback_call_canceled, cb_oncancel);
+ msi_register_callback(callback_call_rejected, cb_onreject);
+ msi_register_callback(callback_call_ended, cb_onend);
+ msi_register_callback(callback_recv_invite, cb_oninvite);
+
+ msi_register_callback(callback_recv_ringing, cb_ringing);
+ msi_register_callback(callback_recv_starting, cb_starting);
+ msi_register_callback(callback_recv_ending, cb_ending);
+
+ msi_register_callback(callback_recv_error, cb_error);
+ msi_register_callback(callback_requ_timeout, cb_timeout);
+ /* ------------------ */
+
+ return _retu;
+}
+
+int av_terminate_session(av_session_t* _phone)
+{
+ if ( _phone->_msi->call ){
+ msi_hangup(_phone->_msi); /* Hangup the phone first */
+ }
+
+ free(_phone->_friends);
+ msi_terminate_session(_phone->_msi);
+ pthread_mutex_destroy ( &_phone->_mutex );
+
+ Tox* _p = _phone->_messenger;
+ _phone->_messenger = NULL; usleep(100000); /* Wait for tox_pool to end */
+ tox_kill(_p);
+
+ printf("\r[i] Quit!\n");
+ return 0;
+}
+
+/****** AV HELPER FUNCTIONS ******/
+
+/* Auto accept friend request */
+void av_friend_requ(uint8_t *_public_key, uint8_t *_data, uint16_t _length, void *_userdata)
+{
+ av_session_t* _phone = _userdata;
+ av_allocate_friend (_phone, -1, 0);
+
+ INFO("Got friend request with message: %s", _data);
+
+ tox_add_friend_norequest(_phone->_messenger, _public_key);
+
+ INFO("Auto-accepted! Friend id: %d", _phone->_friends->_id );
+}
+
+void av_friend_active(Tox *_messenger, int _friendnumber, uint8_t *_string, uint16_t _length, void *_userdata)
+{
+ av_session_t* _phone = _userdata;
+ INFO("Friend no. %d is online", _friendnumber);
+
+ av_friend_t* _this_friend = av_get_friend(_phone, _friendnumber);
+
+ if ( !_this_friend ) {
+ INFO("But it's not registered!");
+ return;
+ }
+
+ (*_this_friend)._active = 1;
+}
+
+int av_add_friend(av_session_t* _phone, char* _friend_hash)
+{
+ trim_spaces(_friend_hash);
+
+ unsigned char *_bin_string = hex_string_to_bin(_friend_hash);
+ int _number = tox_add_friend(_phone->_messenger, _bin_string, (uint8_t *)"Tox phone "_USERAGENT, sizeof("Tox phone "_USERAGENT));
+ free(_bin_string);
+
+ if ( _number >= 0) {
+ INFO("Added friend as %d", _number );
+ av_allocate_friend(_phone, _number, 0);
+ }
+ else
+ INFO("Unknown error %i", _number );
+
+ return _number;
+}
+/*********************************/
+
+void do_phone ( av_session_t* _phone )
+{
+ INFO("Welcome to tox_phone version: " _USERAGENT "\n"
+ "Usage: \n"
+ "f [pubkey] (add friend)\n"
+ "c [a/v] (type) [friend] (friend id) (calls friend if online)\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 )
+ {
+ char _line [ 1500 ];
+ int _len;
+
+ if ( -1 == getinput(_line, 1500, &_len) ){
+ printf(" >> ");
+ fflush(stdout);
+ continue;
+ }
+
+ if ( _len > 1 && _line[1] != ' ' && _line[1] != '\n' ){
+ INFO("Invalid input!");
+ continue;
+ }
+
+ switch (_line[0]){
+
+ case 'f':
+ {
+ char _id [128];
+ strncpy(_id, _line + 2, 128);
+
+ av_add_friend(_phone, _id);
+
+ } break;
+ case 'c':
+ {
+ if ( _phone->_msi->call ){
+ INFO("Already in a call");
+ break;
+ }
+
+ MSICallType _ctype;
+
+ if ( _len < 5 ){
+ INFO("Invalid input; usage: c a/v [friend]");
+ break;
+ }
+ else if ( _line[2] == 'a' || _line[2] != 'v' ){ /* default and audio */
+ _ctype = type_audio;
+ }
+ else { /* video */
+ _ctype = type_video;
+ }
+
+ char* _end;
+ int _friend = strtol(_line + 4, &_end, 10);
+
+ if ( *_end ){
+ INFO("Friend num has to be numerical value");
+ break;
+ }
+
+ /* Set timeout */
+ msi_invite ( _phone->_msi, _ctype, 10 * 1000, _friend );
+ INFO("Calling friend: %d!", _friend);
+
+ } break;
+ case 'h':
+ {
+ if ( !_phone->_msi->call ){
+ INFO("No 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!");
+ return;
+ }
+ default:
+ {
+ INFO("Invalid command!");
+ } break;
+
+ }
+
+ }
+}
+
+void* tox_poll (void* _messenger_p)
+{
+ Tox** _messenger = _messenger_p;
+ while( *_messenger ) {
+ tox_do(*_messenger);
+ usleep(10000);
+ }
+
+ pthread_exit(NULL);
+}
+
+int av_wait_dht(av_session_t* _phone, int _wait_seconds, const char* _ip, char* _key, unsigned short _port)
+{
+ if ( !_wait_seconds )
+ return -1;
+
+ int _waited = 0;
+
+ while( !tox_isconnected(_phone->_messenger) ) {
+
+ if ( -1 == av_connect_to_dht(_phone, _key, _ip, _port) )
+ {
+ INFO("Could not connect to: %s", _ip);
+ av_terminate_session(_phone);
+ return -1;
+ }
+
+ if ( _waited >= _wait_seconds ) return 0;
+
+ printf(".");
+ fflush(stdout);
+
+ _waited ++;
+ usleep(1000000);
+ }
+
+ int _r = _wait_seconds - _waited;
+ return _r ? _r : 1;
+}
+/* ---------------------- */
+
+int print_help ( const char* _name )
+{
+ printf ( "Usage: %s [IP] [PORT] [KEY]\n"
+ "\t[IP] (DHT ip)\n"
+ "\t[PORT] (DHT port)\n"
+ "\t[KEY] (DHT public key)\n"
+ "P.S. Friends and key are stored in ./tox_phone.conf\n"
+ ,_name );
+ return 1;
+}
+
+int main ( int argc, char* argv [] )
+{
+ if ( argc < 1 || argc < 4 )
+ return print_help(argv[0]);
+
+ char* _convertable;
+
+ int _wait_seconds = 5;
+
+ const char* _ip = argv[1];
+ char* _key = argv[3];
+ unsigned short _port = strtol(argv[2], &_convertable, 10);
+
+ if ( *_convertable ){
+ printf("Invalid port: cannot convert string to long: %s", _convertable);
+ return 1;
+ }
+
+ av_session_t* _phone = av_init_session();
+
+ tox_callback_friend_request(_phone->_messenger, av_friend_requ, _phone);
+ tox_callback_status_message(_phone->_messenger, av_friend_active, _phone);
+
+ system("clear");
+
+ INFO("\r================================================================================\n"
+ "[!] Trying dht@%s:%d"
+ , _ip, _port);
+
+ /* Start tox protocol */
+ event.rise( tox_poll, &_phone->_messenger );
+
+ /* Just clean one line */
+ printf("\r \r");
+ fflush(stdout);
+
+ int _r;
+ for ( _r = 0; _r == 0; _r = av_wait_dht(_phone, _wait_seconds, _ip, _key, _port) ) _wait_seconds --;
+
+
+ if ( -1 == _r ) {
+ INFO("Error while connecting to dht: %s:%d", _ip, _port);
+ av_terminate_session(_phone);
+ return 1;
+ }
+
+ INFO("CONNECTED!\n"
+ "================================================================================\n"
+ "%s\n"
+ "================================================================================"
+ , _phone->_my_public_id );
+
+
+ do_phone (_phone);
+
+ av_terminate_session(_phone);
+
+ return 0;
+}
diff --git a/toxmsi/toxmedia.c b/toxav/toxmedia.c
similarity index 100%
rename from toxmsi/toxmedia.c
rename to toxav/toxmedia.c
diff --git a/toxmsi/toxmedia.h b/toxav/toxmedia.h
similarity index 98%
rename from toxmsi/toxmedia.h
rename to toxav/toxmedia.h
index 8734b173..7eea39ae 100644
--- a/toxmsi/toxmedia.h
+++ b/toxav/toxmedia.h
@@ -70,7 +70,7 @@
#define DEFAULT_WEBCAM "/dev/video0"
#endif
-#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
+#ifdef WIN32
#define VIDEO_DRIVER "vfwcap"
#define DEFAULT_WEBCAM "0"
#endif
diff --git a/toxav/toxmsi.c b/toxav/toxmsi.c
new file mode 100755
index 00000000..cf0914ab
--- /dev/null
+++ b/toxav/toxmsi.c
@@ -0,0 +1,1337 @@
+/** toxmsi.c
+ *
+ * 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 .
+ *
+ *
+ * Report bugs/suggestions to me ( mannol ) at either #tox-dev @ freenode.net:6667 or
+ * my email: eniz_vukovic@hotmail.com
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#define _BSD_SOURCE
+
+#include "toxmsi.h"
+#include "../toxcore/util.h"
+#include "../toxcore/network.h"
+#include "../toxcore/event.h"
+#include "../toxcore/Messenger.h"
+
+#include
+#include
+#include
+#include
+
+#define same(x, y) strcmp((const char*) x, (const char*) y) == 0
+
+#define MSI_MAXMSG_SIZE 1024
+
+#define TYPE_REQUEST 1
+#define TYPE_RESPONSE 2
+
+#define VERSION_STRING "0.3.1"
+#define VERSION_STRLEN 5
+
+#define CT_AUDIO_HEADER_VALUE "AUDIO"
+#define CT_VIDEO_HEADER_VALUE "VIDEO"
+
+
+/* Define default timeout for a request.
+ * There is no behavior specified by the msi on what will
+ * client do on timeout, but to call timeout callback.
+ */
+#define m_deftout 10000 /* in milliseconds */
+
+/**
+ * Protocol:
+ *
+ * | desc. ( 1 byte ) | length ( 2 bytes ) | value ( length bytes ) |
+ *
+ * ie.
+ *
+ * | 0x1 | 0x0 0x7 | "version"
+ *
+ * Means: it's field value with length of 7 bytes and value of "version"
+ * It's similar to amp protocol
+ */
+
+
+#define GENERIC_HEADER(header) \
+typedef struct _MSIHeader##header { \
+uint8_t* header_value; \
+uint16_t size; \
+} MSIHeader##header;
+
+
+GENERIC_HEADER ( Version )
+GENERIC_HEADER ( Request )
+GENERIC_HEADER ( Response )
+GENERIC_HEADER ( CallType )
+GENERIC_HEADER ( UserAgent )
+GENERIC_HEADER ( CallId )
+GENERIC_HEADER ( Info )
+GENERIC_HEADER ( Reason )
+GENERIC_HEADER ( CryptoKey )
+GENERIC_HEADER ( Nonce )
+
+
+/**
+ * @brief This is the message structure. It contains all of the headers and
+ * destination/source of the message stored in friend_id.
+ *
+ */
+typedef struct _MSIMessage {
+
+ MSIHeaderVersion version;
+ MSIHeaderRequest request;
+ MSIHeaderResponse response;
+ MSIHeaderCallType calltype;
+ MSIHeaderUserAgent useragent;
+ MSIHeaderInfo info;
+ MSIHeaderReason reason;
+ MSIHeaderCallId callid;
+ MSIHeaderCryptoKey cryptokey;
+ MSIHeaderNonce nonce;
+
+ struct _MSIMessage* next;
+
+ int friend_id;
+
+} MSIMessage;
+
+
+
+static MSICallback callbacks[9] = {0};
+
+
+/* define strings for the identifiers */
+#define VERSION_FIELD "Version"
+#define REQUEST_FIELD "Request"
+#define RESPONSE_FIELD "Response"
+#define INFO_FIELD "INFO"
+#define REASON_FIELD "Reason"
+#define CALLTYPE_FIELD "Call-type"
+#define USERAGENT_FIELD "User-agent"
+#define CALLID_FIELD "Call-id"
+#define CRYPTOKEY_FIELD "Crypto-key"
+#define NONCE_FIELD "Nonce"
+
+/* protocol descriptors */
+#define end_byte 0x0
+#define field_byte 0x1
+#define value_byte 0x2
+
+
+typedef enum {
+ invite,
+ start,
+ cancel,
+ reject,
+ end,
+
+} MSIRequest;
+
+
+/**
+ * @brief Get string value for request.
+ *
+ * @param request The request.
+ * @return const uint8_t* The string
+ */
+static inline const uint8_t *stringify_request ( MSIRequest 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 {
+ ringing,
+ starting,
+ ending,
+ error
+
+} MSIResponse;
+
+
+/**
+ * @brief Get string value for response.
+ *
+ * @param response The response.
+ * @return const uint8_t* The string
+ */
+static inline const uint8_t *stringify_response ( MSIResponse response ) {
+ static const uint8_t* strings[] = {
+ ( uint8_t* ) "ringing",
+ ( uint8_t* ) "starting",
+ ( uint8_t* ) "ending",
+ ( uint8_t* ) "error"
+ };
+
+ return strings[response];
+}
+
+
+#define ON_HEADER(iterator, header, descriptor, size_const) \
+( memcmp(iterator, descriptor, size_const) == 0){ /* Okay */ \
+ iterator += size_const; /* Set iterator at begining of value part */ \
+ if ( *iterator != value_byte ) { assert(0); return -1; }\
+ iterator ++;\
+ uint16_t _value_size = (uint16_t) *(iterator ) << 8 | \
+ (uint16_t) *(iterator + 1); \
+ header.header_value = calloc(sizeof(uint8_t), _value_size); \
+ header.size = _value_size; \
+ memcpy(header.header_value, iterator + 2, _value_size);\
+ iterator = iterator + 2 + _value_size; /* set iterator at new header or end_byte */ \
+}
+
+/**
+ * @brief Parse raw 'data' received from socket into MSIMessage struct.
+ * Every message has to have end value of 'end_byte' or _undefined_ behavior
+ * occures. The best practice is to check the end of the message at the handle_packet.
+ *
+ * @param msg Container.
+ * @param data The data.
+ * @return int
+ * @retval -1 Error occured.
+ * @retval 0 Success.
+ */
+int parse_raw_data ( MSIMessage* msg, const uint8_t* data ) {
+ assert ( msg );
+
+ const uint8_t* _it = data;
+
+ while ( *_it ) {/* until end_byte is hit */
+
+ if ( *_it == field_byte ) {
+ uint16_t _size = ( uint16_t ) * ( _it + 1 ) << 8 |
+ ( uint16_t ) * ( _it + 2 );
+
+ _it += 3; /*place it at the field value beginning*/
+
+ switch ( _size ) { /* Compare the size of the hardcoded values ( vary fast and convenient ) */
+
+ case 4: { /* INFO header */
+ if ON_HEADER ( _it, msg->info, INFO_FIELD, 4 )
+ }
+ break;
+
+ case 5: { /* NONCE header */
+ if ON_HEADER ( _it, msg->nonce, NONCE_FIELD, 5 )
+ }
+ break;
+
+ case 6: { /* Reason header */
+ if ON_HEADER ( _it, msg->reason, REASON_FIELD, 6 )
+ }
+ break;
+
+ case 7: { /* Version, Request, Call-id headers */
+ if ON_HEADER ( _it, msg->version, VERSION_FIELD, 7 )
+ else if ON_HEADER ( _it, msg->request, REQUEST_FIELD, 7 )
+ else if ON_HEADER ( _it, msg->callid, CALLID_FIELD, 7 )
+ }
+ break;
+
+ case 8: { /* Response header */
+ if ON_HEADER ( _it, msg->response, RESPONSE_FIELD, 8 )
+ }
+ break;
+
+ case 9: { /* Call-type header */
+ if ON_HEADER ( _it, msg->calltype, CALLTYPE_FIELD, 9 )
+ }
+ break;
+
+ case 10: { /* User-agent, Crypto-key headers */
+ if ON_HEADER ( _it, msg->useragent, USERAGENT_FIELD, 10 )
+ else if ON_HEADER ( _it, msg->cryptokey, CRYPTOKEY_FIELD, 10 )
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ } else return -1;
+ /* If it's anything else return failure as the message is invalid */
+
+ }
+
+ return 0;
+}
+
+
+#define ALLOCATE_HEADER( var, mheader_value, t_size) \
+var.header_value = calloc(sizeof *mheader_value, t_size); \
+memcpy(var.header_value, mheader_value, t_size); \
+var.size = t_size;
+
+
+/**
+ * @brief Speaks for it self.
+ *
+ * @param msg The message.
+ * @return void
+ */
+void free_message ( MSIMessage* msg ) {
+ assert ( msg );
+
+ free ( msg->calltype.header_value );
+ free ( msg->request.header_value );
+ free ( msg->response.header_value );
+ free ( msg->useragent.header_value );
+ free ( msg->version.header_value );
+ free ( msg->info.header_value );
+ free ( msg->cryptokey.header_value );
+ free ( msg->nonce.header_value );
+ free ( msg->reason.header_value );
+ free ( msg->callid.header_value );
+
+ free ( msg );
+}
+
+
+/**
+ * @brief Create the message.
+ *
+ * @param type Request or response.
+ * @param type_id Type of request/response.
+ * @return MSIMessage* Created message.
+ * @retval NULL Error occured.
+ */
+MSIMessage* msi_new_message ( uint8_t type, const uint8_t* type_id ) {
+ MSIMessage* _retu = calloc ( sizeof ( MSIMessage ), 1 );
+ assert ( _retu );
+
+ memset ( _retu, 0, sizeof ( MSIMessage ) );
+
+ if ( type == TYPE_REQUEST ) {
+ ALLOCATE_HEADER ( _retu->request, type_id, strlen ( type_id ) )
+
+ } else if ( type == TYPE_RESPONSE ) {
+ ALLOCATE_HEADER ( _retu->response, type_id, strlen ( type_id ) )
+
+ } else {
+ free_message ( _retu );
+ return NULL;
+ }
+
+ ALLOCATE_HEADER ( _retu->version, VERSION_STRING, strlen ( VERSION_STRING ) )
+
+ return _retu;
+}
+
+
+/**
+ * @brief Parse data from handle_packet.
+ *
+ * @param data The data.
+ * @return MSIMessage* Parsed message.
+ * @retval NULL Error occured.
+ */
+MSIMessage* parse_message ( const uint8_t* data ) {
+ assert ( data );
+
+ MSIMessage* _retu = calloc ( sizeof ( MSIMessage ), 1 );
+ assert ( _retu );
+
+ memset ( _retu, 0, sizeof ( MSIMessage ) );
+
+ if ( parse_raw_data ( _retu, data ) == -1 ) {
+
+ free_message ( _retu );
+ return NULL;
+ }
+
+ if ( !_retu->version.header_value || VERSION_STRLEN != _retu->version.size ||
+ memcmp ( _retu->version.header_value, VERSION_STRING, VERSION_STRLEN ) != 0 ) {
+
+ free_message ( _retu );
+ return NULL;
+ }
+
+ return _retu;
+}
+
+
+
+/**
+ * @brief Speaks for it self.
+ *
+ * @param dest Container.
+ * @param header_field Field.
+ * @param header_value Field value.
+ * @param value_len Length of field value.
+ * @param length Pointer to container length.
+ * @return uint8_t* Iterated container.
+ */
+uint8_t* append_header_to_string (
+ uint8_t* dest,
+ const uint8_t* header_field,
+ const uint8_t* header_value,
+ uint16_t value_len,
+ uint16_t* length )
+{
+ assert ( dest );
+ assert ( header_value );
+ assert ( header_field );
+
+ const uint8_t* _hvit = header_value;
+ uint16_t _total = 6 + value_len; /* 6 is known plus header value len + field len*/
+
+ *dest = field_byte; /* Set the first byte */
+
+ uint8_t* _getback_byte = dest + 1; /* remeber the byte we were on */
+ dest += 3; /* swith to 4th byte where field value starts */
+
+ /* Now set the field value and calculate it's length */
+ uint16_t _i = 0;
+ for ( ; header_field[_i]; ++_i ) {
+ *dest = header_field[_i];
+ ++dest;
+ };
+ _total += _i;
+
+ /* Now set the length of the field byte */
+ *_getback_byte = ( uint8_t ) _i >> 8;
+ _getback_byte++;
+ *_getback_byte = ( uint8_t ) _i;
+
+ /* for value part do it regulary */
+ *dest = value_byte;
+ dest++;
+
+ *dest = ( uint8_t ) value_len >> 8;
+ dest++;
+ *dest = ( uint8_t ) value_len;
+ dest++;
+
+ for ( _i = value_len; _i; --_i ) {
+ *dest = *_hvit;
+ ++_hvit;
+ ++dest;
+ }
+
+ *length += _total;
+ return dest;
+}
+
+
+#define CLEAN_ASSIGN(added, var, field, header)\
+if ( header.header_value ) { var = append_header_to_string(var, (const uint8_t*)field, header.header_value, header.size, &added); }
+
+
+/**
+ * @brief Convert MSIMessage struct to _sendable_ string.
+ *
+ * @param msg The message.
+ * @param dest Destination.
+ * @return uint16_t It's final size.
+ */
+uint16_t message_to_string ( MSIMessage* msg, uint8_t* dest ) {
+ assert ( msg );
+ assert ( dest );
+
+ uint8_t* _iterated = dest;
+ uint16_t _size = 0;
+
+ CLEAN_ASSIGN ( _size, _iterated, VERSION_FIELD, msg->version );
+ CLEAN_ASSIGN ( _size, _iterated, REQUEST_FIELD, msg->request );
+ CLEAN_ASSIGN ( _size, _iterated, RESPONSE_FIELD, msg->response );
+ CLEAN_ASSIGN ( _size, _iterated, CALLTYPE_FIELD, msg->calltype );
+ CLEAN_ASSIGN ( _size, _iterated, USERAGENT_FIELD, msg->useragent );
+ CLEAN_ASSIGN ( _size, _iterated, INFO_FIELD, msg->info );
+ CLEAN_ASSIGN ( _size, _iterated, CALLID_FIELD, msg->callid );
+ CLEAN_ASSIGN ( _size, _iterated, REASON_FIELD, msg->reason );
+ CLEAN_ASSIGN ( _size, _iterated, CRYPTOKEY_FIELD, msg->cryptokey );
+ CLEAN_ASSIGN ( _size, _iterated, NONCE_FIELD, msg->nonce );
+
+ *_iterated = end_byte;
+ _size ++;
+
+ return _size;
+}
+
+
+#define GENERIC_SETTER_DEFINITION(header) \
+void msi_msg_set_##header ( MSIMessage* _msg, const uint8_t* header_value, uint16_t _size ) \
+{ assert(_msg); assert(header_value); \
+ free(_msg->header.header_value); \
+ ALLOCATE_HEADER( _msg->header, header_value, _size )}
+
+GENERIC_SETTER_DEFINITION ( calltype )
+GENERIC_SETTER_DEFINITION ( useragent )
+GENERIC_SETTER_DEFINITION ( reason )
+GENERIC_SETTER_DEFINITION ( info )
+GENERIC_SETTER_DEFINITION ( callid )
+GENERIC_SETTER_DEFINITION ( cryptokey )
+GENERIC_SETTER_DEFINITION ( nonce )
+
+
+/**
+ * @brief Generate _random_ alphanumerical string.
+ *
+ * @param str Destination.
+ * @param size Size of string.
+ * @return void
+ */
+void t_randomstr ( uint8_t* str, size_t size ) {
+ assert ( str );
+
+ static const uint8_t _bytes[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+
+ int _it = 0;
+
+ for ( ; _it < size; _it++ ) {
+ str[_it] = _bytes[ randombytes_random() % 61 ];
+ }
+}
+
+
+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_no_crypto_key, /* no crypto key */
+
+ error_busy,
+
+} MSICallError; /* Error codes */
+
+
+/**
+ * @brief Stringify error code.
+ *
+ * @param error_code The code.
+ * @return const uint8_t* The string.
+ */
+static inline const uint8_t *stringify_error ( MSICallError 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* ) "No Crypto-key set",
+ ( uint8_t* ) "Callee busy"
+ };
+
+ return strings[error_code];
+}
+
+
+/**
+ * @brief Convert error_code into string.
+ *
+ * @param error_code The code.
+ * @return const uint8_t* The string.
+ */
+static inline const uint8_t *stringify_error_code ( MSICallError error_code ) {
+ static const uint8_t* strings[] = {
+ ( uint8_t* ) "",
+ ( uint8_t* ) "1",
+ ( uint8_t* ) "2",
+ ( uint8_t* ) "3",
+ ( uint8_t* ) "4",
+ ( uint8_t* ) "5",
+ ( uint8_t* ) "6"
+ };
+
+ return strings[error_code];
+}
+
+
+/**
+ * @brief Speaks for it self.
+ *
+ * @param session Control session.
+ * @param msg The message.
+ * @param to Where to.
+ * @return int
+ * @retval -1 Error occured.
+ * @retval 0 Success.
+ */
+int send_message ( MSISession* session, MSIMessage* msg, uint32_t to )
+{
+ msi_msg_set_callid ( msg, session->call->id, CALL_ID_LEN );
+
+ uint8_t _msg_string_final [MSI_MAXMSG_SIZE];
+ uint16_t _length = message_to_string ( msg, _msg_string_final );
+
+ return m_msi_packet((struct Messenger*) session->messenger_handle, to, _msg_string_final, _length) ? 0 : -1;
+}
+
+
+/**
+ * @brief Speaks for it self.
+ *
+ * @param session Control session.
+ * @param msg The message.
+ * @param peer_id The peer.
+ * @return void
+ */
+void flush_peer_type ( MSISession* session, MSIMessage* msg, int peer_id ) {
+ if ( msg->calltype.header_value ) {
+ if ( strcmp ( ( const char* ) msg->calltype.header_value, CT_AUDIO_HEADER_VALUE ) == 0 ) {
+ session->call->type_peer[peer_id] = type_audio;
+
+ } else if ( strcmp ( ( const char* ) msg->calltype.header_value, CT_VIDEO_HEADER_VALUE ) == 0 ) {
+ session->call->type_peer[peer_id] = type_video;
+ } else {} /* Error */
+ } else {} /* Error */
+}
+
+
+
+/**
+ * @brief Sends error response to peer.
+ *
+ * @param session The session.
+ * @param errid The id.
+ * @param to Where to?
+ * @return int
+ * @retval 0 It's always success.
+ */
+int handle_error ( MSISession* session, MSICallError errid, uint32_t to ) {
+ MSIMessage* _msg_error = msi_new_message ( TYPE_RESPONSE, stringify_response ( error ) );
+
+ const uint8_t* _error_code_str = stringify_error_code ( errid );
+
+ msi_msg_set_reason ( _msg_error, _error_code_str, strlen ( ( const char* ) _error_code_str ) );
+ send_message ( session, _msg_error, to );
+ free_message ( _msg_error );
+
+ session->last_error_id = errid;
+ session->last_error_str = stringify_error ( errid );
+
+ event.rise ( callbacks[cb_error], session );
+
+ return 0;
+}
+
+
+/**
+ * @brief Determine the error if any.
+ *
+ * @param session Control session.
+ * @param msg The message.
+ * @return int
+ * @retval -1 No error.
+ * @retval 0 Error occured and response sent.
+ */
+int has_call_error ( MSISession* session, MSIMessage* msg ) {
+ if ( !msg->callid.header_value ) {
+ return handle_error ( session, error_no_callid, msg->friend_id );
+
+ } else if ( !session->call ) {
+ return handle_error ( session, error_no_call, msg->friend_id );
+
+ } else if ( memcmp ( session->call->id, msg->callid.header_value, CALL_ID_LEN ) != 0 ) {
+ return handle_error ( session, error_id_mismatch, msg->friend_id );
+
+ }
+
+ return -1;
+}
+
+
+/**
+ * @brief Function called at request timeout.
+ *
+ * @param arg Control session
+ * @return void*
+ */
+void* handle_timeout ( void* arg )
+{
+ /* Send hangup either way */
+ MSISession* _session = arg;
+
+ uint32_t* _peers = _session->call->peers;
+ uint16_t _peer_count = _session->call->peer_count;
+
+
+ /* Cancel all? */
+ uint16_t _it = 0;
+ for ( ; _it < _peer_count; _it++ )
+ msi_cancel ( arg, _peers[_it] );
+
+
+ ( *callbacks[cb_timeout] ) ( arg );
+ ( *callbacks[cb_ending ] ) ( arg );
+
+ return NULL;
+}
+
+
+/**
+ * @brief Add peer to peer list.
+ *
+ * @param call What call.
+ * @param peer_id Its id.
+ * @return void
+ */
+void add_peer( MSICall* call, int peer_id )
+{
+ if ( !call->peers ) {
+ call->peers = calloc(sizeof(int), 1);
+ call->peer_count = 1;
+ } else{
+ call->peer_count ++;
+ call->peers = realloc( call->peers, sizeof(int) * call->peer_count);
+ }
+
+ call->peers[call->peer_count - 1] = peer_id;
+}
+
+
+/**
+ * @brief 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.
+ *
+ *
+ */
+void msi_handle_packet ( Messenger* messenger, int source, uint8_t* data, uint16_t length, void* object )
+{
+ MSISession* _session = object;
+ MSIMessage* _msg;
+
+ _msg = parse_message ( data );
+
+ if ( !_msg ) return;
+
+ _msg->friend_id = source;
+
+
+ /* Now handle message */
+
+ if ( _msg->request.header_value ) { /* Handle request */
+
+ const uint8_t* _request_value = _msg->request.header_value;
+
+ if ( same ( _request_value, stringify_request ( invite ) ) ) {
+ handle_recv_invite ( _session, _msg );
+
+ } else if ( same ( _request_value, stringify_request ( start ) ) ) {
+ handle_recv_start ( _session, _msg );
+
+ } else if ( same ( _request_value, stringify_request ( cancel ) ) ) {
+ handle_recv_cancel ( _session, _msg );
+
+ } else if ( same ( _request_value, stringify_request ( reject ) ) ) {
+ handle_recv_reject ( _session, _msg );
+
+ } else if ( same ( _request_value, stringify_request ( end ) ) ) {
+ handle_recv_end ( _session, _msg );
+ }
+
+ else {
+ free_message ( _msg );
+ return;
+ }
+
+ } else if ( _msg->response.header_value ) { /* Handle response */
+
+ const uint8_t* _response_value = _msg->response.header_value;
+
+ if ( same ( _response_value, stringify_response ( ringing ) ) ) {
+ handle_recv_ringing ( _session, _msg );
+
+ } else if ( same ( _response_value, stringify_response ( starting ) ) ) {
+ handle_recv_starting ( _session, _msg );
+
+ } else if ( same ( _response_value, stringify_response ( ending ) ) ) {
+ handle_recv_ending ( _session, _msg );
+
+ } else if ( same ( _response_value, stringify_response ( error ) ) ) {
+ handle_recv_error ( _session, _msg );
+ } else {
+ free_message ( _msg );
+ return;
+ }
+
+ /* Got response so cancel timer */
+ if ( _session->call )
+ event.timer_release ( _session->call->request_timer_id );
+
+ }
+
+ free_message ( _msg );
+}
+
+
+/**
+ * @brief Speaks for it self.
+ *
+ * @param session Control session.
+ * @param peers Amount of peers. (Currently it only supports 1)
+ * @param ringing_timeout Ringing timeout.
+ * @return MSICall* The created call.
+ */
+MSICall* init_call ( MSISession* session, int peers, int ringing_timeout ) {
+ assert ( session );
+ assert ( peers );
+
+ MSICall* _call = calloc ( sizeof ( MSICall ), 1 );
+ _call->type_peer = calloc ( sizeof ( MSICallType ), peers );
+
+ assert ( _call );
+ assert ( _call->type_peer );
+
+ /*_call->_participant_count = _peers;*/
+
+ _call->request_timer_id = 0;
+ _call->ringing_timer_id = 0;
+
+ _call->key_local = NULL;
+ _call->key_peer = NULL;
+ _call->nonce_local = NULL;
+ _call->nonce_peer = NULL;
+
+ _call->ringing_tout_ms = ringing_timeout;
+
+ pthread_mutex_init ( &_call->mutex, NULL );
+
+ return _call;
+}
+
+
+/**
+ * @brief Terminate the call.
+ *
+ * @param session Control session.
+ * @return int
+ * @retval -1 Error occured.
+ * @retval 0 Success.
+ */
+int terminate_call ( MSISession* session ) {
+ assert ( session );
+
+ if ( !session->call )
+ return -1;
+
+
+ /* Check event loop and cancel timed events if there are any
+ * Notice: This has to be done before possibly
+ * locking the mutex the second time
+ */
+ event.timer_release ( session->call->request_timer_id );
+ event.timer_release ( session->call->ringing_timer_id );
+
+ /* Get a handle */
+ pthread_mutex_lock ( &session->call->mutex );
+
+ MSICall* _call = session->call;
+ session->call = NULL;
+
+ free ( _call->type_peer );
+ free ( _call->key_local );
+ free ( _call->key_peer );
+ free ( _call->peers);
+
+ /* Release handle */
+ pthread_mutex_unlock ( &_call->mutex );
+
+ pthread_mutex_destroy ( &_call->mutex );
+
+ free ( _call );
+
+ return 0;
+}
+
+
+/********** Request handlers **********/
+int handle_recv_invite ( MSISession* session, MSIMessage* msg ) {
+ assert ( session );
+
+ if ( session->call ) {
+ handle_error ( session, error_busy, msg->friend_id );
+ return 0;
+ }
+ if ( !msg->callid.header_value ) {
+ handle_error ( session, error_no_callid, msg->friend_id );
+ return 0;
+ }
+
+ session->call = init_call ( session, 1, 0 );
+ memcpy ( session->call->id, msg->callid.header_value, CALL_ID_LEN );
+ session->call->state = call_starting;
+
+ add_peer( session->call, msg->friend_id);
+
+ flush_peer_type ( session, msg, 0 );
+
+ MSIMessage* _msg_ringing = msi_new_message ( TYPE_RESPONSE, stringify_response ( ringing ) );
+ send_message ( session, _msg_ringing, msg->friend_id );
+ free_message ( _msg_ringing );
+
+ event.rise ( callbacks[cb_oninvite], session );
+
+ return 1;
+}
+int handle_recv_start ( MSISession* session, MSIMessage* msg ) {
+ assert ( session );
+
+ if ( has_call_error ( session, msg ) == 0 )
+ return 0;
+
+ if ( !msg->cryptokey.header_value )
+ return handle_error ( session, error_no_crypto_key, msg->friend_id );
+
+ session->call->state = call_active;
+
+ session->call->key_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES );
+ memcpy ( session->call->key_peer, msg->cryptokey.header_value, crypto_secretbox_KEYBYTES );
+
+ session->call->nonce_peer = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES );
+ memcpy ( session->call->nonce_peer, msg->nonce.header_value, crypto_box_NONCEBYTES );
+
+ flush_peer_type ( session, msg, 0 );
+
+ event.rise ( callbacks[cb_onstart], session );
+
+ return 1;
+}
+int handle_recv_reject ( MSISession* session, MSIMessage* msg ) {
+ assert ( session );
+
+ if ( has_call_error ( session, msg ) == 0 )
+ return 0;
+
+
+ MSIMessage* _msg_end = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) );
+ send_message ( session, _msg_end, msg->friend_id );
+ free_message ( _msg_end );
+
+ event.timer_release ( session->call->request_timer_id );
+ event.rise ( callbacks[cb_onreject], session );
+ session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
+
+ return 1;
+}
+int handle_recv_cancel ( MSISession* session, MSIMessage* msg ) {
+ assert ( session );
+
+ if ( has_call_error ( session, msg ) == 0 )
+ return 0;
+
+
+ terminate_call ( session );
+
+ event.rise ( callbacks[cb_oncancel], session );
+
+ return 1;
+}
+int handle_recv_end ( MSISession* session, MSIMessage* msg ) {
+ assert ( session );
+
+ if ( has_call_error ( session, msg ) == 0 )
+ return 0;
+
+
+ MSIMessage* _msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) );
+ send_message ( session, _msg_ending, msg->friend_id );
+ free_message ( _msg_ending );
+
+ terminate_call ( session );
+
+ event.rise ( callbacks[cb_onend], session );
+
+ return 1;
+}
+
+/********** Response handlers **********/
+int handle_recv_ringing ( MSISession* session, MSIMessage* msg ) {
+ assert ( session );
+
+ if ( has_call_error ( session, msg ) == 0 )
+ return 0;
+
+ session->call->ringing_timer_id = event.timer_alloc ( handle_timeout, session, session->call->ringing_tout_ms );
+ event.rise ( callbacks[cb_ringing], session );
+
+ return 1;
+}
+int handle_recv_starting ( MSISession* session, MSIMessage* msg ) {
+ assert ( session );
+
+ if ( has_call_error ( session, msg ) == 0 )
+ return 0;
+
+ if ( !msg->cryptokey.header_value ) {
+ return handle_error ( session, error_no_crypto_key, msg->friend_id );
+ }
+
+ /* Generate local key/nonce to send */
+ session->call->key_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES );
+ new_symmetric_key ( session->call->key_local );
+
+ session->call->nonce_local = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES );
+ new_nonce ( session->call->nonce_local );
+
+ /* Save peer key/nonce */
+ session->call->key_peer = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES );
+ memcpy ( session->call->key_peer, msg->cryptokey.header_value, crypto_secretbox_KEYBYTES );
+
+ session->call->nonce_peer = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES );
+ memcpy ( session->call->nonce_peer, msg->nonce.header_value, crypto_box_NONCEBYTES );
+
+ session->call->state = call_active;
+
+ MSIMessage* _msg_start = msi_new_message ( TYPE_REQUEST, stringify_request ( start ) );
+ msi_msg_set_cryptokey ( _msg_start, session->call->key_local, crypto_secretbox_KEYBYTES );
+ msi_msg_set_nonce ( _msg_start, session->call->nonce_local, crypto_box_NONCEBYTES );
+ send_message ( session, _msg_start, msg->friend_id );
+ free_message ( _msg_start );
+
+ flush_peer_type ( session, msg, 0 );
+
+ event.rise ( callbacks[cb_starting], session );
+ event.timer_release ( session->call->ringing_timer_id );
+
+ return 1;
+}
+int handle_recv_ending ( MSISession* session, MSIMessage* msg ) {
+ assert ( session );
+
+ if ( has_call_error ( session, msg ) == 0 )
+ return 0;
+
+
+ terminate_call ( session );
+
+ event.rise ( callbacks[cb_ending], session );
+
+ return 1;
+}
+int handle_recv_error ( MSISession* session, MSIMessage* msg ) {
+ assert ( session );
+ assert ( session->call );
+
+ /* Handle error accordingly */
+ if ( msg->reason.header_value ) {
+ session->last_error_id = atoi ( ( const char* ) msg->reason.header_value );
+ session->last_error_str = stringify_error ( session->last_error_id );
+ }
+
+ terminate_call ( session );
+
+ event.rise ( callbacks[cb_ending], session );
+
+ return 1;
+}
+
+
+/********************************************************************************************************************
+ * *******************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ *
+ *
+ *
+ * PUBLIC API FUNCTIONS IMPLEMENTATIONS
+ *
+ *
+ *
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************/
+
+
+
+
+
+
+
+
+/**
+ * @brief Callback setter.
+ *
+ * @param callback The callback.
+ * @param id The id.
+ * @return void
+ */
+void msi_register_callback ( MSICallback callback, MSICallbackID id )
+{
+ callbacks[id] = callback;
+}
+
+
+/**
+ * @brief Start the control session.
+ *
+ * @param messenger Tox* object.
+ * @param user_agent User agent, i.e. 'Venom'; 'QT-gui'
+ * @return MSISession* The created session.
+ * @retval NULL Error occured.
+ */
+MSISession* msi_init_session ( Tox* messenger, const uint8_t* user_agent ) {
+ assert ( messenger );
+ assert ( user_agent );
+
+ MSISession* _retu = calloc ( sizeof ( MSISession ), 1 );
+ assert ( _retu );
+
+ _retu->user_agent = user_agent;
+ _retu->messenger_handle = messenger;
+ _retu->agent_handler = NULL;
+
+ _retu->call = NULL;
+
+ _retu->frequ = 10000; /* default value? */
+ _retu->call_timeout = 30000; /* default value? */
+
+
+ m_callback_msi_packet((struct Messenger*) messenger, msi_handle_packet, _retu );
+
+
+ return _retu;
+}
+
+
+/**
+ * @brief Terminate control session.
+ *
+ * @param session The session
+ * @return int
+ */
+int msi_terminate_session ( MSISession* session ) {
+ assert ( session );
+
+ int _status = 0;
+
+ terminate_call ( session );
+
+ /* TODO: Clean it up more? */
+
+ free ( session );
+ return _status;
+}
+
+
+/**
+ * @brief Send invite request to friend_id.
+ *
+ * @param session Control session.
+ * @param call_type Type of the call. Audio or Video(both audio and video)
+ * @param rngsec Ringing timeout.
+ * @param friend_id The friend.
+ * @return int
+ */
+int msi_invite ( MSISession* session, MSICallType call_type, uint32_t rngsec, uint32_t friend_id ) {
+ assert ( session );
+
+ MSIMessage* _msg_invite = msi_new_message ( TYPE_REQUEST, stringify_request ( invite ) );
+
+ session->call = init_call ( session, 1, rngsec ); /* Just one for now */
+ t_randomstr ( session->call->id, CALL_ID_LEN );
+
+ add_peer(session->call, friend_id );
+
+ session->call->type_local = call_type;
+ /* Do whatever with message */
+
+ if ( call_type == type_audio ) {
+ msi_msg_set_calltype
+ ( _msg_invite, ( const uint8_t* ) CT_AUDIO_HEADER_VALUE, strlen ( CT_AUDIO_HEADER_VALUE ) );
+ } else {
+ msi_msg_set_calltype
+ ( _msg_invite, ( const uint8_t* ) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) );
+ }
+
+ send_message ( session, _msg_invite, friend_id );
+ free_message ( _msg_invite );
+
+ session->call->state = call_inviting;
+
+ session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
+
+ return 0;
+}
+
+
+/**
+ * @brief Hangup active call.
+ *
+ * @param session Control session.
+ * @return int
+ * @retval -1 Error occured.
+ * @retval 0 Success.
+ */
+int msi_hangup ( MSISession* session ) {
+ assert ( session );
+
+ if ( !session->call && session->call->state != call_active )
+ return -1;
+
+ MSIMessage* _msg_ending = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) );
+
+ /* hangup for each peer */
+ int _it = 0;
+ for ( ; _it < session->call->peer_count; _it ++ )
+ send_message ( session, _msg_ending, session->call->peers[_it] );
+
+
+ free_message ( _msg_ending );
+
+ session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
+
+ return 0;
+}
+
+
+/**
+ * @brief Answer active call request.
+ *
+ * @param session Control session.
+ * @param call_type Answer with Audio or Video(both).
+ * @return int
+ */
+int msi_answer ( MSISession* session, MSICallType call_type ) {
+ assert ( session );
+
+ MSIMessage* _msg_starting = msi_new_message ( TYPE_RESPONSE, stringify_response ( starting ) );
+ session->call->type_local = call_type;
+
+ if ( call_type == type_audio ) {
+ msi_msg_set_calltype
+ ( _msg_starting, ( const uint8_t* ) CT_AUDIO_HEADER_VALUE, strlen ( CT_AUDIO_HEADER_VALUE ) );
+ } else {
+ msi_msg_set_calltype
+ ( _msg_starting, ( const uint8_t* ) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) );
+ }
+
+ /* Now set the local encryption key and pass it with STARTING message */
+
+ session->call->key_local = calloc ( sizeof ( uint8_t ), crypto_secretbox_KEYBYTES );
+ new_symmetric_key ( session->call->key_local );
+
+ session->call->nonce_local = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES );
+ new_nonce ( session->call->nonce_local );
+
+ msi_msg_set_cryptokey ( _msg_starting, session->call->key_local, crypto_secretbox_KEYBYTES );
+ msi_msg_set_nonce ( _msg_starting, session->call->nonce_local, crypto_box_NONCEBYTES );
+
+ send_message ( session, _msg_starting, session->call->peers[session->call->peer_count - 1] );
+ free_message ( _msg_starting );
+
+ session->call->state = call_active;
+
+ return 0;
+}
+
+
+/**
+ * @brief Cancel request.
+ *
+ * @param session Control session.
+ * @param friend_id The friend.
+ * @return int
+ */
+int msi_cancel ( MSISession* session, int friend_id ) {
+ assert ( session );
+
+ MSIMessage* _msg_cancel = msi_new_message ( TYPE_REQUEST, stringify_request ( cancel ) );
+ send_message ( session, _msg_cancel, friend_id );
+ free_message ( _msg_cancel );
+
+ terminate_call ( session );
+
+ return 0;
+}
+
+
+/**
+ * @brief Reject request.
+ *
+ * @param session Control session.
+ * @return int
+ */
+int msi_reject ( MSISession* session ) {
+ assert ( session );
+
+ MSIMessage* _msg_reject = msi_new_message ( TYPE_REQUEST, stringify_request ( reject ) );
+ send_message ( session, _msg_reject, session->call->peers[session->call->peer_count - 1] );
+ free_message ( _msg_reject );
+
+ session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
+
+ return 0;
+}
+
+
+/**
+ * @brief Terminate the current call.
+ *
+ * @param session Control session.
+ * @return int
+ */
+int msi_stopcall ( MSISession* session ) {
+ assert ( session );
+
+ if ( !session->call )
+ return -1;
+
+ /* just terminate it */
+
+ terminate_call ( session );
+
+ return 0;
+}
\ No newline at end of file
diff --git a/toxav/toxmsi.h b/toxav/toxmsi.h
new file mode 100755
index 00000000..c45662a6
--- /dev/null
+++ b/toxav/toxmsi.h
@@ -0,0 +1,231 @@
+/** toxmsi.h
+ *
+ * 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 .
+ *
+ *
+ * Report bugs/suggestions to me ( mannol ) at either #tox-dev @ freenode.net:6667 or
+ * my email: eniz_vukovic@hotmail.com
+ */
+
+#ifndef __TOXMSI
+#define __TOXMSI
+
+#include
+#include "../toxcore/tox.h"
+#include
+
+/* define size for call_id */
+#define CALL_ID_LEN 12
+
+
+typedef void* ( *MSICallback ) ( void* arg );
+
+
+/**
+ * @brief Call type identifier. Also used as rtp callback prefix.
+ */
+typedef enum {
+ type_audio = 70,
+ type_video,
+} MSICallType;
+
+
+/**
+ * @brief Call state identifiers.
+ */
+typedef enum {
+ call_inviting, /* when sending call invite */
+ call_starting, /* when getting call invite */
+ call_active,
+ call_hold
+
+} MSICallState;
+
+
+
+/**
+ * @brief The call struct.
+ *
+ */
+typedef struct _MSICall { /* Call info structure */
+ MSICallState state;
+
+ MSICallType type_local; /* Type of payload user is ending */
+ MSICallType* type_peer; /* Type of payload others are sending */
+
+ uint8_t id[CALL_ID_LEN]; /* Random value identifying the call */
+
+ uint8_t* key_local; /* The key for encryption */
+ uint8_t* key_peer; /* The key for decryption */
+
+ uint8_t* nonce_local; /* Local nonce */
+ uint8_t* nonce_peer; /* Peer nonce */
+
+ int ringing_tout_ms; /* Ringing timeout in ms */
+
+ int request_timer_id; /* Timer id for outgoing request/action */
+ int ringing_timer_id; /* Timer id for ringing timeout */
+
+ pthread_mutex_t mutex; /* It's to be assumed that call will have
+ * seperate thread so add mutex
+ */
+ uint32_t* peers;
+ uint16_t peer_count;
+
+
+} MSICall;
+
+
+/**
+ * @brief Control session struct
+ *
+ */
+typedef struct _MSISession {
+
+ /* Call handler */
+ struct _MSICall* call;
+
+ 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 */
+ Tox* messenger_handle;
+
+ uint32_t frequ;
+ uint32_t call_timeout; /* Time of the timeout for some action to end; 0 if infinite */
+
+
+} MSISession;
+
+
+/**
+ * @brief Callbacks ids that handle the states
+ */
+typedef enum {
+ /* Requests */
+ cb_oninvite,
+ cb_onstart,
+ cb_oncancel,
+ cb_onreject,
+ cb_onend,
+
+ /* Responses */
+ cb_ringing,
+ cb_starting,
+ cb_ending,
+
+ /* Protocol */
+ cb_error,
+ cb_timeout,
+
+} MSICallbackID;
+
+
+/**
+ * @brief Callback setter.
+ *
+ * @param callback The callback.
+ * @param id The id.
+ * @return void
+ */
+void msi_register_callback(MSICallback callback, MSICallbackID id);
+
+
+/**
+ * @brief Start the control session.
+ *
+ * @param messenger Tox* object.
+ * @param user_agent User agent, i.e. 'Venom'; 'QT-gui'
+ * @return MSISession* The created session.
+ * @retval NULL Error occured.
+ */
+MSISession* msi_init_session ( Tox* messenger, const uint8_t* user_agent );
+
+
+/**
+ * @brief Terminate control session.
+ *
+ * @param session The session
+ * @return int
+ */
+int msi_terminate_session ( MSISession* session );
+
+
+/**
+ * @brief Send invite request to friend_id.
+ *
+ * @param session Control session.
+ * @param call_type Type of the call. Audio or Video(both audio and video)
+ * @param rngsec Ringing timeout.
+ * @param friend_id The friend.
+ * @return int
+ */
+int msi_invite ( MSISession* session, MSICallType call_type, uint32_t rngsec, uint32_t friend_id );
+
+
+/**
+ * @brief Hangup active call.
+ *
+ * @param session Control session.
+ * @return int
+ * @retval -1 Error occured.
+ * @retval 0 Success.
+ */
+int msi_hangup ( MSISession* session );
+
+
+/**
+ * @brief Answer active call request.
+ *
+ * @param session Control session.
+ * @param call_type Answer with Audio or Video(both).
+ * @return int
+ */
+int msi_answer ( MSISession* session, MSICallType call_type );
+
+
+/**
+ * @brief Cancel request.
+ *
+ * @param session Control session.
+ * @param friend_id The friend.
+ * @return int
+ */
+int msi_cancel ( MSISession* session, int friend_id );
+
+
+/**
+ * @brief Reject request.
+ *
+ * @param session Control session.
+ * @return int
+ */
+int msi_reject ( MSISession* session );
+
+
+/**
+ * @brief Terminate the current call.
+ *
+ * @param session Control session.
+ * @return int
+ */
+int msi_stopcall ( MSISession* session );
+
+#endif /* __TOXMSI */
diff --git a/toxav/toxrtp.c b/toxav/toxrtp.c
new file mode 100755
index 00000000..2363deea
--- /dev/null
+++ b/toxav/toxrtp.c
@@ -0,0 +1,878 @@
+/** toxrtp.c
+ *
+ * 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 .
+ *
+ *
+ * Report bugs/suggestions to me ( mannol ) at either #tox-dev @ freenode.net:6667 or
+ * my email: eniz_vukovic@hotmail.com
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include "toxrtp.h"
+#include
+#include
+#include
+
+#include "../toxcore/util.h"
+#include "../toxcore/network.h"
+#include "../toxcore/net_crypto.h"
+#include "../toxcore/Messenger.h"
+
+#define PAYLOAD_ID_VALUE_OPUS 1
+#define PAYLOAD_ID_VALUE_VP8 2
+
+#define MAX_SEQU_NUM 65535
+
+#define size_32 4
+
+#define inline__ inline __attribute__((always_inline))
+
+
+#define ADD_FLAG_VERSION(_h, _v) do { ( _h->flags ) &= 0x3F; ( _h->flags ) |= ( ( ( _v ) << 6 ) & 0xC0 ); } while(0)
+#define ADD_FLAG_PADDING(_h, _v) do { if ( _v > 0 ) _v = 1; ( _h->flags ) &= 0xDF; ( _h->flags ) |= ( ( ( _v ) << 5 ) & 0x20 ); } while(0)
+#define ADD_FLAG_EXTENSION(_h, _v) do { if ( _v > 0 ) _v = 1; ( _h->flags ) &= 0xEF;( _h->flags ) |= ( ( ( _v ) << 4 ) & 0x10 ); } while(0)
+#define ADD_FLAG_CSRCC(_h, _v) do { ( _h->flags ) &= 0xF0; ( _h->flags ) |= ( ( _v ) & 0x0F ); } while(0)
+#define ADD_SETTING_MARKER(_h, _v) do { if ( _v > 1 ) _v = 1; ( _h->marker_payloadt ) &= 0x7F; ( _h->marker_payloadt ) |= ( ( ( _v ) << 7 ) /*& 0x80 */ ); } while(0)
+#define ADD_SETTING_PAYLOAD(_h, _v) do { if ( _v > 127 ) _v = 127; ( _h->marker_payloadt ) &= 0x80; ( _h->marker_payloadt ) |= ( ( _v ) /* & 0x7F */ ); } while(0)
+
+#define GET_FLAG_VERSION(_h) (( _h->flags & 0xd0 ) >> 6)
+#define GET_FLAG_PADDING(_h) (( _h->flags & 0x20 ) >> 5)
+#define GET_FLAG_EXTENSION(_h) (( _h->flags & 0x10 ) >> 4)
+#define GET_FLAG_CSRCC(_h) ( _h->flags & 0x0f )
+#define GET_SETTING_MARKER(_h) (( _h->marker_payloadt ) >> 7)
+#define GET_SETTING_PAYLOAD(_h) ((_h->marker_payloadt) & 0x7f)
+
+
+
+/**
+ * @brief Checks if message came in late.
+ *
+ * @param session Control session.
+ * @param msg The message.
+ * @return int
+ * @retval -1 The message came in order.
+ * @retval 0 The message came late.
+ */
+inline__ int check_late_message (RTPSession* session, RTPMessage* msg)
+{
+ /*
+ * Check Sequence number. If this new msg has lesser number then the session->rsequnum
+ * it shows that the message came in late. Also check timestamp to be 100% certain.
+ *
+ */
+ return ( msg->header->sequnum < session->rsequnum && msg->header->timestamp < session->timestamp ) ? 0 : -1;
+}
+
+
+/**
+ * @brief Increases nonce value by 'target'
+ *
+ * @param nonce The nonce
+ * @param target The target
+ * @return void
+ */
+inline__ void increase_nonce(uint8_t* nonce, uint16_t target)
+{
+ uint16_t _nonce_counter = ((uint16_t)(
+ (((uint16_t) nonce [crypto_box_NONCEBYTES - 1]) << 8 ) |
+ (((uint16_t) nonce [crypto_box_NONCEBYTES - 2]) )));
+
+ /* Check overflow */
+ if (_nonce_counter > USHRT_MAX - target ) { /* 2 bytes are not long enough */
+ int _it = 3;
+ while ( _it <= crypto_box_NONCEBYTES ) _it += ++nonce[crypto_box_NONCEBYTES - _it] ? crypto_box_NONCEBYTES : 1;
+
+ _nonce_counter = _nonce_counter - (USHRT_MAX - target ); /* Assign the rest of it */
+ } else { /* Increase nonce */
+
+ _nonce_counter+= target;
+ }
+
+ /* Assign the 8 last bytes */
+
+ nonce [crypto_box_NONCEBYTES - 1] = (uint8_t) (_nonce_counter >> 8);
+ nonce [crypto_box_NONCEBYTES - 2] = (uint8_t) (_nonce_counter);
+}
+
+
+/**
+ * @brief Speaks for it self.
+ *
+ */
+static const uint32_t payload_table[] =
+{
+ 8000, 8000, 8000, 8000, 8000, 8000, 16000, 8000, 8000, 8000, /* 0-9 */
+ 44100, 44100, 0, 0, 90000, 8000, 11025, 22050, 0, 0, /* 10-19 */
+ 0, 0, 0, 0, 0, 90000, 90000, 0, 90000, 0, /* 20-29 */
+ 0, 90000, 90000, 90000, 90000, 0, 0, 0, 0, 0, /* 30-39 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40-49 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50-59 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60-69 */
+ PAYLOAD_ID_VALUE_OPUS, PAYLOAD_ID_VALUE_VP8, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-79 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-89 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90-99 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 100-109 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 110-119 */
+ 0, 0, 0, 0, 0, 0, 0, 0 /* 120-127 */
+};
+
+
+/**
+ * @brief Extracts header from payload.
+ *
+ * @param payload The payload.
+ * @param length The size of payload.
+ * @return RTPHeader* Extracted header.
+ * @retval NULL Error occurred while extracting header.
+ */
+RTPHeader* extract_header ( const uint8_t* payload, size_t length )
+{
+ if ( !payload ) {
+ return NULL;
+ }
+
+ const uint8_t* _it = payload;
+
+ RTPHeader* _retu = calloc(sizeof(RTPHeader), 1);
+ assert(_retu);
+
+ _retu->flags = *_it; ++_it;
+
+ /* This indicates if the first 2 bytes are valid.
+ * Now it my happen that this is out of order but
+ * it cuts down chances of parsing some invalid value
+ */
+ if ( GET_FLAG_VERSION(_retu) != RTP_VERSION ){
+ /* Deallocate */
+ free(_retu);
+ return NULL;
+ }
+
+ /*
+ * Added a check for the size of the header little sooner so
+ * I don't need to parse the other stuff if it's bad
+ */
+ uint8_t _cc = GET_FLAG_CSRCC ( _retu );
+ uint32_t _length = 12 /* Minimum header len */ + ( _cc * 4 );
+
+ if ( length < _length ) {
+ /* Deallocate */
+ free(_retu);
+ return NULL;
+ }
+
+ if ( _cc > 0 ) {
+ _retu->csrc = calloc ( sizeof ( uint32_t ), _cc );
+ assert(_retu->csrc);
+
+ } else { /* But this should not happen ever */
+ /* Deallocate */
+ free(_retu);
+ return NULL;
+ }
+
+
+ _retu->marker_payloadt = *_it; ++_it;
+ _retu->length = _length;
+
+ _retu->timestamp = ( ( uint32_t ) * _it << 24 ) |
+ ( ( uint32_t ) * ( _it + 1 ) << 16 ) |
+ ( ( uint32_t ) * ( _it + 2 ) << 8 ) |
+ ( * ( _it + 3 ) ) ;
+
+ _it += 4;
+
+ _retu->ssrc = ( ( uint32_t ) * _it << 24 ) |
+ ( ( uint32_t ) * ( _it + 1 ) << 16 ) |
+ ( ( uint32_t ) * ( _it + 2 ) << 8 ) |
+ ( ( uint32_t ) * ( _it + 3 ) ) ;
+
+
+ size_t _x;
+ for ( _x = 0; _x < _cc; _x++ ) {
+ _it += 4;
+ _retu->csrc[_x] = ( ( uint32_t ) * _it << 24 ) |
+ ( ( uint32_t ) * ( _it + 1 ) << 16 ) |
+ ( ( uint32_t ) * ( _it + 2 ) << 8 ) |
+ ( ( uint32_t ) * ( _it + 3 ) ) ;
+ }
+
+ return _retu;
+}
+
+/**
+ * @brief Extracts external header from payload. Must be called AFTER extract_header()!
+ *
+ * @param payload The ITERATED payload.
+ * @param length The size of payload.
+ * @return RTPExtHeader* Extracted extension header.
+ * @retval NULL Error occurred while extracting extension header.
+ */
+RTPExtHeader* extract_ext_header ( const uint8_t* payload, size_t length )
+{
+ const uint8_t* _it = payload;
+
+ RTPExtHeader* _retu = calloc(sizeof(RTPExtHeader), 1);
+ assert(_retu);
+
+ uint16_t _ext_length = ( ( uint16_t ) * _it << 8 ) | * ( _it + 1 ); _it += 2;
+
+ if ( length < ( _ext_length * sizeof(uint32_t) ) ) {
+ return NULL;
+ }
+
+ _retu->length = _ext_length;
+ _retu->type = ( ( uint16_t ) * _it << 8 ) | * ( _it + 1 ); _it -= 2;
+
+ _retu->table = calloc(sizeof(uint32_t), _ext_length );
+ assert(_retu->table);
+
+ uint32_t* _table = _retu->table;
+ size_t _i;
+ for ( _i = 0; _i < _ext_length; _i++ ) {
+ _it += 4;
+ _table[_i] = ( ( uint32_t ) * _it << 24 ) |
+ ( ( uint32_t ) * ( _it + 1 ) << 16 ) |
+ ( ( uint32_t ) * ( _it + 2 ) << 8 ) |
+ ( ( uint32_t ) * ( _it + 3 ) ) ;
+ }
+
+ return _retu;
+}
+
+/**
+ * @brief Adds header to payload. Make sure _payload_ has enough space.
+ *
+ * @param header The header.
+ * @param payload The payload.
+ * @return uint8_t* Iterated position.
+ */
+uint8_t* add_header ( RTPHeader* header, uint8_t* payload )
+{
+ uint8_t _cc = GET_FLAG_CSRCC ( header );
+
+ uint8_t* _it = payload;
+
+
+ /* Add sequence number first */
+ *_it = ( header->sequnum >> 8 ); ++_it;
+ *_it = ( header->sequnum ); ++_it;
+
+ *_it = header->flags; ++_it;
+ *_it = header->marker_payloadt; ++_it;
+
+
+ uint32_t _timestamp = header->timestamp;
+ *_it = ( _timestamp >> 24 ); ++_it;
+ *_it = ( _timestamp >> 16 ); ++_it;
+ *_it = ( _timestamp >> 8 ); ++_it;
+ *_it = ( _timestamp ); ++_it;
+
+ uint32_t _ssrc = header->ssrc;
+ *_it = ( _ssrc >> 24 ); ++_it;
+ *_it = ( _ssrc >> 16 ); ++_it;
+ *_it = ( _ssrc >> 8 ); ++_it;
+ *_it = ( _ssrc );
+
+ uint32_t *_csrc = header->csrc;
+ size_t _x;
+ for ( _x = 0; _x < _cc; _x++ ) {
+ ++_it;
+ *_it = ( _csrc[_x] >> 24 ); ++_it;
+ *_it = ( _csrc[_x] >> 16 ); ++_it;
+ *_it = ( _csrc[_x] >> 8 ); ++_it;
+ *_it = ( _csrc[_x] );
+ }
+
+ return _it;
+}
+
+/**
+ * @brief Adds extension header to payload. Make sure _payload_ has enough space.
+ *
+ * @param header The header.
+ * @param payload The payload.
+ * @return uint8_t* Iterated position.
+ */
+uint8_t* add_ext_header ( RTPExtHeader* header, uint8_t* payload )
+{
+ uint8_t* _it = payload;
+
+ *_it = ( header->length >> 8 ); _it++;
+ *_it = ( header->length ); _it++;
+
+ *_it = ( header->type >> 8 ); ++_it;
+ *_it = ( header->type );
+
+ size_t x;
+
+ uint32_t* _hd_ext = header->table;
+ for ( x = 0; x < header->length; x++ ) {
+ ++_it;
+ *_it = ( _hd_ext[x] >> 24 ); ++_it;
+ *_it = ( _hd_ext[x] >> 16 ); ++_it;
+ *_it = ( _hd_ext[x] >> 8 ); ++_it;
+ *_it = ( _hd_ext[x] );
+ }
+
+ return _it;
+}
+
+/**
+ * @brief Builds header from control session values.
+ *
+ * @param session Control session.
+ * @return RTPHeader* Created header.
+ */
+RTPHeader* build_header ( RTPSession* session )
+{
+ RTPHeader* _retu;
+ _retu = calloc ( sizeof * _retu, 1 );
+ assert(_retu);
+
+ ADD_FLAG_VERSION ( _retu, session->version );
+ ADD_FLAG_PADDING ( _retu, session->padding );
+ ADD_FLAG_EXTENSION ( _retu, session->extension );
+ ADD_FLAG_CSRCC ( _retu, session->cc );
+ ADD_SETTING_MARKER ( _retu, session->marker );
+ ADD_SETTING_PAYLOAD ( _retu, session->payload_type );
+
+ _retu->sequnum = session->sequnum;
+ _retu->timestamp = ((uint32_t)(current_time() / 1000)); /* micro to milli */
+ _retu->ssrc = session->ssrc;
+
+ if ( session->cc > 0 ) {
+ _retu->csrc = calloc(sizeof(uint32_t), session->cc);
+ assert(_retu->csrc);
+
+ int i;
+
+ for ( i = 0; i < session->cc; i++ ) {
+ _retu->csrc[i] = session->csrc[i];
+ }
+ } else {
+ _retu->csrc = NULL;
+ }
+
+ _retu->length = 12 /* Minimum header len */ + ( session->cc * size_32 );
+
+ return _retu;
+}
+
+
+/**
+ * @brief Parses data into RTPMessage struct. Stores headers separately from the payload data
+ * and so the length variable is set accordingly. _sequnum_ argument is
+ * passed by the handle_packet() since it's parsed already.
+ *
+ * @param session Control session.
+ * @param sequnum Sequence number that's parsed from payload in handle_packet()
+ * @param data Payload data.
+ * @param length Payload size.
+ * @return RTPMessage*
+ * @retval NULL Error occurred.
+ */
+RTPMessage* msg_parse ( RTPSession* session, uint16_t sequnum, const uint8_t* data, uint32_t length )
+{
+ assert( length != -1);
+
+ RTPMessage* _retu = calloc(sizeof(RTPMessage), 1);
+ assert(_retu);
+
+ _retu->header = extract_header ( data, length ); /* It allocates memory and all */
+
+ if ( !_retu->header ){
+ free(_retu);
+ return NULL;
+ }
+ _retu->header->sequnum = sequnum;
+
+ _retu->length = length - _retu->header->length;
+
+ uint16_t _from_pos = _retu->header->length - 2 /* Since sequ num is excluded */ ;
+
+
+ if ( GET_FLAG_EXTENSION ( _retu->header ) ) {
+ _retu->ext_header = extract_ext_header ( data + _from_pos, length );
+ if ( _retu->ext_header ){
+ _retu->length -= ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
+ _from_pos += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
+ } else {
+ free (_retu->ext_header);
+ free (_retu->header);
+ free (_retu);
+ return NULL;
+ }
+ } else {
+ _retu->ext_header = NULL;
+ }
+
+ /* Get the payload */
+ _retu->data = calloc ( sizeof ( uint8_t ), _retu->length );
+ assert(_retu->data);
+
+ memcpy ( _retu->data, data + _from_pos, length - _from_pos );
+
+ _retu->next = NULL;
+
+
+ if ( session && check_late_message ( session, _retu) < 0 ){
+ session->rsequnum = _retu->header->sequnum;
+ session->timestamp = _retu->header->timestamp;
+ }
+
+ return _retu;
+}
+
+/**
+ * @brief Callback for networking core.
+ *
+ * @param object RTPSession object.
+ * @param ip_port Where the message comes from.
+ * @param data Message data.
+ * @param length Message length.
+ * @return int
+ * @retval -1 Error occurred.
+ * @retval 0 Success.
+ */
+int rtp_handle_packet ( void* object, IP_Port ip_port, uint8_t* data, uint32_t length )
+{
+ RTPSession* _session = object;
+ RTPMessage* _msg;
+
+ if ( !_session )
+ return -1;
+
+ uint8_t _plain[MAX_UDP_PACKET_SIZE];
+
+ uint16_t _sequnum = ( ( uint16_t ) data[1] << 8 ) | data[2];
+
+ /* Clculate the right nonce */
+ uint8_t _calculated[crypto_box_NONCEBYTES];
+ memcpy(_calculated, _session->decrypt_nonce, crypto_box_NONCEBYTES);
+ increase_nonce ( _calculated, _sequnum );
+
+ /* Decrypt message */
+ int _decrypted_length = decrypt_data_symmetric(
+ (uint8_t*)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
+
+ /* This packet is either not encrypted properly or late
+ */
+ if ( -1 == _decrypted_length ){
+
+ /* If this is the case, then the packet is most likely late.
+ * Try with old nonce cycle.
+ */
+ if ( _session->rsequnum < _sequnum ) {
+ _decrypted_length = decrypt_data_symmetric(
+ (uint8_t*)_session->decrypt_key, _session->nonce_cycle, data + 3, length - 3, _plain );
+
+ if ( !_decrypted_length ) return -1; /* This packet is not encrypted properly */
+
+ /* Otherwise, if decryption is ok with new cycle, set new cycle
+ */
+ } else {
+ increase_nonce ( _calculated, MAX_SEQU_NUM );
+ _decrypted_length = decrypt_data_symmetric(
+ (uint8_t*)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
+
+ if ( !_decrypted_length ) return -1; /* This is just an error */
+
+ /* A new cycle setting. */
+ memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_box_NONCEBYTES);
+ memcpy(_session->decrypt_nonce, _calculated, crypto_box_NONCEBYTES);
+ }
+ }
+
+ _msg = msg_parse ( NULL, _sequnum, _plain, _decrypted_length );
+
+ if ( !_msg )
+ return -1;
+
+ /* Hopefully this goes well
+ * NOTE: Is this even used?
+ */
+ memcpy(&_msg->from, &ip_port, sizeof(tox_IP_Port));
+
+ /* Check if message came in late */
+ if ( check_late_message(_session, _msg) < 0 ) { /* Not late */
+ _session->rsequnum = _msg->header->sequnum;
+ _session->timestamp = _msg->header->timestamp;
+ }
+
+ 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);
+
+ return 0;
+}
+
+
+
+/**
+ * @brief Stores headers and payload data in one container ( data )
+ * and the length is set accordingly. Returned message is used for sending _only_.
+ *
+ * @param session The control session.
+ * @param data Payload data to send ( This is what you pass ).
+ * @param length Size of the payload data.
+ * @return RTPMessage* Created message.
+ * @retval NULL Error occurred.
+ */
+RTPMessage* rtp_new_message ( RTPSession* session, const uint8_t* data, uint32_t length )
+{
+ if ( !session )
+ return NULL;
+
+ uint8_t* _from_pos;
+ RTPMessage* _retu = calloc(sizeof(RTPMessage), 1);
+ assert(_retu);
+
+ /* Sets header values and copies the extension header in _retu */
+ _retu->header = build_header ( session ); /* It allocates memory and all */
+ _retu->ext_header = session->ext_header;
+
+
+ uint32_t _total_length = length + _retu->header->length;
+
+ if ( _retu->ext_header ) {
+ _total_length += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
+ /* Allocate Memory for _retu->_data */
+ _retu->data = calloc ( sizeof _retu->data, _total_length );
+ assert(_retu->data);
+
+ _from_pos = add_header ( _retu->header, _retu->data );
+ _from_pos = add_ext_header ( _retu->ext_header, _from_pos + 1 );
+ } else {
+ /* Allocate Memory for _retu->_data */
+ _retu->data = calloc ( sizeof _retu->data, _total_length );
+ assert(_retu->data);
+
+ _from_pos = add_header ( _retu->header, _retu->data );
+ }
+
+ /*
+ * Parses the extension header into the message
+ * Of course if any
+ */
+
+ /* Appends _data on to _retu->_data */
+ memcpy ( _from_pos + 1, data, length );
+
+ _retu->length = _total_length;
+
+ _retu->next = NULL;
+
+ return _retu;
+}
+
+
+/********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ *
+ *
+ *
+ * PUBLIC API FUNCTIONS IMPLEMENTATIONS
+ *
+ *
+ *
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************
+ ********************************************************************************************************************/
+
+
+
+
+
+
+
+
+
+/**
+ * @brief Release all messages held by session.
+ *
+ * @param session The session.
+ * @return int
+ * @retval -1 Error occurred.
+ * @retval 0 Success.
+ */
+int rtp_release_session_recv ( RTPSession* session )
+{
+ if ( !session ){
+ return -1;
+ }
+
+ RTPMessage* _tmp,* _it;
+
+ pthread_mutex_lock(&session->mutex);
+
+ for ( _it = session->oldest_msg; _it; _it = _tmp ){
+ _tmp = _it->next;
+ rtp_free_msg( session, _it);
+ }
+
+ session->last_msg = session->oldest_msg = NULL;
+
+ pthread_mutex_unlock(&session->mutex);
+
+ return 0;
+}
+
+
+/**
+ * @brief Get's oldes message in the list.
+ *
+ * @param session Where the list is.
+ * @return RTPMessage* The message. You _must_ call rtp_msg_free() to free it.
+ * @retval NULL No messages in the list, or no list.
+ */
+RTPMessage* rtp_recv_msg ( RTPSession* session )
+{
+ if ( !session )
+ return NULL;
+
+ RTPMessage* _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;
+}
+
+
+/**
+ * @brief Sends data to _RTPSession::dest
+ *
+ * @param session The session.
+ * @param messenger Tox* object.
+ * @param data The payload.
+ * @param length Size of the payload.
+ * @return int
+ * @retval -1 On error.
+ * @retval 0 On success.
+ */
+int rtp_send_msg ( RTPSession* session, Tox* messenger, const uint8_t* data, uint16_t length )
+{
+ RTPMessage* msg = rtp_new_message (session, data, length);
+
+ if ( !msg ) return -1;
+
+ uint8_t _send_data [ MAX_UDP_PACKET_SIZE ];
+
+ _send_data[0] = session->prefix;
+
+ /* Generate the right nonce */
+ uint8_t _calculated[crypto_box_NONCEBYTES];
+ memcpy(_calculated, session->encrypt_nonce, crypto_box_NONCEBYTES);
+ increase_nonce ( _calculated, msg->header->sequnum );
+
+ /* Need to skip 2 bytes that are for sequnum */
+ int encrypted_length = encrypt_data_symmetric(
+ (uint8_t*) session->encrypt_key, _calculated, msg->data + 2, msg->length - 2, _send_data + 3 );
+
+ int full_length = encrypted_length + 3;
+
+ _send_data[1] = msg->data[0];
+ _send_data[2] = msg->data[1];
+
+
+ if ( full_length != sendpacket ( ((Messenger*)messenger)->net, *((IP_Port*) &session->dest), _send_data, full_length) ) {
+ printf("Rtp error: %s\n", strerror(errno));
+ return -1;
+ }
+
+
+ /* Set sequ number */
+ if ( session->sequnum >= MAX_SEQU_NUM ) {
+ session->sequnum = 0;
+ memcpy(session->encrypt_nonce, _calculated, crypto_box_NONCEBYTES);
+ } else {
+ session->sequnum++;
+ }
+
+ rtp_free_msg ( session, msg );
+ return 0;
+}
+
+
+/**
+ * @brief Speaks for it self.
+ *
+ * @param session The control session msg belongs to. It can be NULL.
+ * @param msg The message.
+ * @return void
+ */
+void rtp_free_msg ( RTPSession* session, RTPMessage* msg )
+{
+ free ( msg->data );
+
+ if ( !session ){
+ free ( msg->header->csrc );
+ if ( msg->ext_header ){
+ free ( msg->ext_header->table );
+ free ( msg->ext_header );
+ }
+ } else {
+ if ( session->csrc != msg->header->csrc )
+ free ( msg->header->csrc );
+ if ( msg->ext_header && session->ext_header != msg->ext_header ) {
+ free ( msg->ext_header->table );
+ free ( msg->ext_header );
+ }
+ }
+
+ free ( msg->header );
+ free ( msg );
+}
+
+
+/**
+ * @brief Must be called before calling any other rtp function. It's used
+ * to initialize RTP control session.
+ *
+ * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType
+ * @param messenger Tox* object.
+ * @param friend_num Friend id.
+ * @param encrypt_key Speaks for it self.
+ * @param decrypt_key Speaks for it self.
+ * @param encrypt_nonce Speaks for it self.
+ * @param decrypt_nonce Speaks for it self.
+ * @return RTPSession* Created control session.
+ * @retval NULL Error occurred.
+ */
+RTPSession* rtp_init_session ( int payload_type,
+ Tox* messenger,
+ int friend_num,
+ const uint8_t* encrypt_key,
+ const uint8_t* decrypt_key,
+ const uint8_t* encrypt_nonce,
+ const uint8_t* decrypt_nonce
+)
+{
+ Messenger* _messenger_casted = (Messenger*) messenger;
+
+ IP_Port _dest = get_friend_ipport(_messenger_casted, friend_num );
+
+ /* This should be enough eh? */
+ if ( _dest.port == 0) {
+ return NULL;
+ }
+
+ RTPSession* _retu = calloc(sizeof(RTPSession), 1);
+ assert(_retu);
+
+ networking_registerhandler(_messenger_casted->net, payload_type, rtp_handle_packet, _retu);
+
+ _retu->version = RTP_VERSION; /* It's always 2 */
+ _retu->padding = 0; /* If some additional data is needed about the packet */
+ _retu->extension = 0; /* If extension to header is needed */
+ _retu->cc = 1; /* Amount of contributors */
+ _retu->csrc = NULL; /* Container */
+ _retu->ssrc = randombytes_random();
+ _retu->marker = 0;
+ _retu->payload_type = payload_table[payload_type];
+
+ _retu->dest = *((tox_IP_Port*)&_dest);
+
+ _retu->rsequnum = _retu->sequnum = 1;
+
+ _retu->ext_header = NULL; /* When needed allocate */
+ _retu->framerate = -1;
+ _retu->resolution = -1;
+
+ _retu->encrypt_key = encrypt_key;
+ _retu->decrypt_key = decrypt_key;
+
+ /* Need to allocate new memory */
+ _retu->encrypt_nonce = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES ); assert(_retu->encrypt_nonce);
+ _retu->decrypt_nonce = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES ); assert(_retu->decrypt_nonce);
+ _retu->nonce_cycle = calloc ( sizeof ( uint8_t ), crypto_box_NONCEBYTES ); assert(_retu->nonce_cycle);
+
+ memcpy(_retu->encrypt_nonce, encrypt_nonce, crypto_box_NONCEBYTES);
+ memcpy(_retu->decrypt_nonce, decrypt_nonce, crypto_box_NONCEBYTES);
+ memcpy(_retu->nonce_cycle , decrypt_nonce, crypto_box_NONCEBYTES);
+
+ _retu->csrc = calloc(sizeof(uint32_t), 1);
+ assert(_retu->csrc);
+
+ _retu->csrc[0] = _retu->ssrc; /* Set my ssrc to the list receive */
+
+ /* Also set payload type as prefix */
+ _retu->prefix = payload_type;
+
+ _retu->oldest_msg = _retu->last_msg = NULL;
+
+ pthread_mutex_init(&_retu->mutex, NULL);
+ /*
+ *
+ */
+ return _retu;
+}
+
+
+/**
+ * @brief Terminate the session.
+ *
+ * @param session The session.
+ * @param messenger The messenger who owns the session
+ * @return int
+ * @retval -1 Error occurred.
+ * @retval 0 Success.
+ */
+int rtp_terminate_session ( RTPSession* session, Tox* messenger )
+{
+ if ( !session )
+ return -1;
+
+ networking_registerhandler(((Messenger*)messenger)->net, session->prefix, NULL, NULL);
+
+ free ( session->ext_header );
+ free ( session->csrc );
+ free ( session->decrypt_nonce );
+ free ( session->encrypt_nonce );
+ free ( session->nonce_cycle );
+
+ pthread_mutex_destroy(&session->mutex);
+
+ /* And finally free session */
+ free ( session );
+
+ return 0;
+}
\ No newline at end of file
diff --git a/toxav/toxrtp.h b/toxav/toxrtp.h
new file mode 100755
index 00000000..b4275aba
--- /dev/null
+++ b/toxav/toxrtp.h
@@ -0,0 +1,211 @@
+/** toxrtp.h
+ *
+ * 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 .
+ *
+ *
+ * Report bugs/suggestions to me ( mannol ) at either #tox-dev @ freenode.net:6667 or
+ * my email: eniz_vukovic@hotmail.com
+ */
+
+#ifndef __TOXRTP
+#define __TOXRTP
+
+#define RTP_VERSION 2
+#include
+#include "../toxcore/tox.h"
+
+/**
+ * Standard rtp header
+ */
+
+typedef struct _RTPHeader {
+ uint8_t flags; /* Version(2),Padding(1), Ext(1), Cc(4) */
+ uint8_t marker_payloadt; /* Marker(1), PlayLoad Type(7) */
+ uint16_t sequnum; /* Sequence Number */
+ uint32_t timestamp; /* Timestamp */
+ uint32_t ssrc; /* SSRC */
+ uint32_t* csrc; /* CSRC's table */
+ uint32_t length; /* Length of the header in payload string. */
+
+} RTPHeader;
+
+
+/**
+ * @brief Standard rtp extension header.
+ *
+ */
+typedef struct _RTPExtHeader {
+ uint16_t type; /* Extension profile */
+ uint16_t length; /* Number of extensions */
+ uint32_t* table; /* Extension's table */
+
+} RTPExtHeader;
+
+
+/**
+ * @brief Standard rtp message.
+ *
+ */
+typedef struct _RTPMessage {
+ RTPHeader* header;
+ RTPExtHeader* ext_header;
+
+ uint8_t* data;
+ uint32_t length;
+ tox_IP_Port from;
+
+ struct _RTPMessage* next;
+} RTPMessage;
+
+
+/**
+ * @brief Our main session descriptor.
+ * It measures the session variables and controls
+ * the entire session. There are functions for manipulating
+ * the session so tend to use those instead of directly modifying
+ * session parameters.
+ *
+ */
+typedef struct _RTPSession {
+ uint8_t version;
+ uint8_t padding;
+ uint8_t extension;
+ uint8_t cc;
+ uint8_t marker;
+ uint8_t payload_type;
+ uint16_t sequnum; /* Set when sending */
+ uint16_t rsequnum; /* Check when recving msg */
+ uint32_t timestamp;
+ uint32_t ssrc;
+ uint32_t* csrc;
+
+ /* If some additional data must be sent via message
+ * apply it here. Only by allocating this member you will be
+ * automatically placing it within a message.
+ */
+ RTPExtHeader* ext_header;
+
+ /* External header identifiers */
+ int resolution;
+ int framerate;
+
+
+ /* Since these are only references of the
+ * call structure don't allocate or free
+ */
+
+ const uint8_t* encrypt_key;
+ const uint8_t* decrypt_key;
+ uint8_t* encrypt_nonce;
+ uint8_t* decrypt_nonce;
+
+ uint8_t* nonce_cycle;
+
+ RTPMessage* oldest_msg;
+ RTPMessage* last_msg; /* tail */
+
+ /* Msg prefix for core to know when recving */
+ uint8_t prefix;
+
+ pthread_mutex_t mutex;
+ tox_IP_Port dest;
+
+} RTPSession;
+
+
+/**
+ * @brief Release all messages held by session.
+ *
+ * @param session The session.
+ * @return int
+ * @retval -1 Error occurred.
+ * @retval 0 Success.
+ */
+int rtp_release_session_recv ( RTPSession* session );
+
+
+/**
+ * @brief Get's oldest message in the list.
+ *
+ * @param session Where the list is.
+ * @return RTPMessage* The message. You need to call rtp_msg_free() to free it.
+ * @retval NULL No messages in the list, or no list.
+ */
+RTPMessage* rtp_recv_msg ( RTPSession* session );
+
+
+/**
+ * @brief Sends msg to _RTPSession::dest
+ *
+ * @param session The session.
+ * @param msg The message
+ * @param messenger Tox* object.
+ * @return int
+ * @retval -1 On error.
+ * @retval 0 On success.
+ */
+int rtp_send_msg ( RTPSession* session, Tox* messenger, const uint8_t* data, uint16_t length );
+
+
+/**
+ * @brief Speaks for it self.
+ *
+ * @param session The control session msg belongs to. It can be NULL.
+ * @param msg The message.
+ * @return void
+ */
+void rtp_free_msg ( RTPSession* session, RTPMessage* msg );
+
+
+/**
+ * @brief Must be called before calling any other rtp function. It's used
+ * to initialize RTP control session.
+ *
+ * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType
+ * @param messenger Tox* object.
+ * @param friend_num Friend id.
+ * @param encrypt_key Speaks for it self.
+ * @param decrypt_key Speaks for it self.
+ * @param encrypt_nonce Speaks for it self.
+ * @param decrypt_nonce Speaks for it self.
+ * @return RTPSession* Created control session.
+ * @retval NULL Error occurred.
+ */
+RTPSession* rtp_init_session ( int payload_type,
+ Tox* messenger,
+ int friend_num,
+ const uint8_t* encrypt_key,
+ const uint8_t* decrypt_key,
+ const uint8_t* encrypt_nonce,
+ const uint8_t* decrypt_nonce );
+
+
+/**
+ * @brief Terminate the session.
+ *
+ * @param session The session.
+ * @param messenger The messenger who owns the session
+ * @return int
+ * @retval -1 Error occurred.
+ * @retval 0 Success.
+ */
+int rtp_terminate_session ( RTPSession* session, Tox* messenger );
+
+
+
+#endif /* __TOXRTP */
diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc
index 51b4c20b..6c4e297f 100644
--- a/toxcore/Makefile.inc
+++ b/toxcore/Makefile.inc
@@ -29,6 +29,8 @@ libtoxcore_la_SOURCES = ../toxcore/DHT.h \
../toxcore/group_chats.c \
../toxcore/assoc.h \
../toxcore/assoc.c \
+ ../toxcore/event.h \
+ ../toxcore/event.c \
../toxcore/onion.h \
../toxcore/onion.c \
../toxcore/onion_announce.h \
diff --git a/toxcore/event.c b/toxcore/event.c
new file mode 100755
index 00000000..17e68c87
--- /dev/null
+++ b/toxcore/event.c
@@ -0,0 +1,335 @@
+/** event.c
+ *
+ * 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 .
+ *
+ *
+ * Report bugs/suggestions to me ( mannol ) at either #tox-dev @ freenode.net:6667 or
+ * my email: eniz_vukovic@hotmail.com
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include
+#include "event.h"
+
+#include "util.h"
+
+#define _GNU_SOURCE
+
+#include
+#include
+#include
+#include
+#include
+
+#define RUN_IN_THREAD(func, args) { pthread_t _tid; \
+ pthread_create(&_tid, NULL, func, args); assert( pthread_detach(_tid) == 0 ); }
+
+#define LOCK(event_handler) pthread_mutex_lock (&event_handler->mutex)
+#define UNLOCK(event_handler) pthread_mutex_unlock(&event_handler->mutex)
+
+#define FREQUENCY 10000
+
+#define inline__ inline __attribute__((always_inline))
+
+
+typedef struct _EventContainer {
+ void* (*func)(void*);
+ void* func_args;
+ unsigned timeout;
+ long long id;
+
+} EventContainer;
+
+typedef struct _EventHandler {
+ EventContainer* timed_events;
+ size_t timed_events_count;
+
+ int running;
+
+ pthread_mutex_t mutex;
+
+} EventHandler;
+
+int throw_event( void* (func)(void*), void* arg );
+int reset_timer_event ( int id, uint32_t timeout );
+int throw_timer_event ( void* (func)(void*), void* arg, unsigned timeout);
+int cancel_timer_event ( int id );
+int execute_timer_event ( int id );
+
+struct _Event event =
+{
+ throw_event,
+ /* reset_timer_event */ NULL,
+ throw_timer_event,
+ cancel_timer_event,
+ /*execute_timer_event*/ NULL
+};
+
+/*
+ * Random functions used by this file
+ */
+void clear_events (EventContainer** event_container, size_t* counter)
+{
+ free(*event_container );
+
+ *event_container = NULL;
+ *counter = 0;
+}
+
+int pop_id ( EventContainer** event_container, size_t* counter, int id )
+{
+ if ( !*event_container || !*counter || !id )
+ return -1;
+
+ EventContainer* _it = *event_container;
+ int i;
+
+ for ( i = *counter; i; -- i ){
+ if ( _it->id == id ) { /* Hit! */
+ break;
+ }
+ ++_it;
+ }
+
+ if ( i ) {
+ for ( ; i; -- i ){ *_it = *(_it + 1); ++_it; }
+ -- (*counter );
+ *event_container = realloc(*event_container, sizeof(EventContainer) * (*counter )); /* resize */
+
+ return 0;
+
+ }
+
+ /* not found here */
+
+ return -1;
+}
+
+void push_event ( EventContainer** container, size_t* counter, void* (func)(void*), void* arg )
+{
+ (*container ) = realloc((*container ), sizeof(EventContainer) * ((*counter ) + 1));
+ assert((*container ) != NULL);
+
+ (*container )[*counter].func = func;
+ (*container )[*counter].func_args = arg;
+ (*container )[*counter].timeout = 0;
+ (*container )[*counter].id = 0;
+
+ (*counter )++;
+}
+
+void reorder_events ( size_t counter, EventContainer* container, unsigned timeout )
+{
+ if ( counter > 1 ) {
+
+ int i = counter - 1;
+
+ /* start from behind excluding last added member */
+ EventContainer* _it = &container[i - 1];
+
+ EventContainer _last_added = container[i];
+
+ for ( ; i; --i ) {
+ if ( _it->timeout > timeout ){
+ *(_it + 1) = *_it;
+ *_it = _last_added; -- _it;
+ }
+ }
+
+ }
+}
+
+/* ============================================= */
+
+/* main poll for event execution */
+void* event_poll( void* arg )
+{
+ EventHandler* _event_handler = arg;
+
+ while ( _event_handler->running )
+ {
+
+ LOCK( _event_handler );
+
+ if ( _event_handler->timed_events ){
+
+ uint32_t _time = ((uint32_t)(current_time() / 1000));
+
+ if ( _event_handler->timed_events[0].timeout < _time ) {
+
+ RUN_IN_THREAD ( _event_handler->timed_events[0].func,
+ _event_handler->timed_events[0].func_args );
+
+ pop_id(&_event_handler->timed_events,
+ &_event_handler->timed_events_count,
+ _event_handler->timed_events[0].id);
+
+ }
+
+ }
+
+ UNLOCK( _event_handler );
+
+ usleep(FREQUENCY);
+ }
+
+LOCK( _event_handler );
+
+ clear_events(&_event_handler->timed_events, &_event_handler->timed_events_count);
+
+UNLOCK( _event_handler );
+
+ _event_handler->running = -1;
+ pthread_exit(NULL);
+}
+
+int throw_event( void* (func)(void*), void* arg )
+{
+ pthread_t _tid;
+ int _rc =
+ pthread_create(&_tid, NULL, func, arg );
+
+ return (0 != _rc ) ? _rc : pthread_detach(_tid);
+}
+
+EventHandler event_handler;
+
+/* Place and order array of timers */
+int throw_timer_event ( void* (func)(void*), void* arg, unsigned timeout)
+{
+ static int _unique_id = 1;
+
+ 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 + ((uint32_t)(current_time() / 1000));
+ event_handler.timed_events[_counter - 1].id = _unique_id; ++_unique_id;
+
+
+ /* reorder */
+
+ reorder_events(_counter, event_handler.timed_events, timeout );
+
+ return _unique_id - 1;
+}
+
+int execute_timer_event ( int id )
+{
+ int _status;
+
+LOCK((&event_handler));
+ EventContainer* _it = event_handler.timed_events;
+
+ int _i = event_handler.timed_events_count;
+
+ /* Find it and execute */
+ for ( ; _i; _i-- ) {
+ if ( _it->id == id ) {
+ RUN_IN_THREAD ( _it->func, _it->func_args );
+ break;
+ }
+ ++_it;
+ }
+
+ /* Now remove it from the queue */
+
+ if ( _i ) {
+ for ( ; _i; -- _i ){ *_it = *(_it + 1); ++_it; }
+ -- event_handler.timed_events_count;
+
+ event_handler.timed_events = realloc
+ (event_handler.timed_events, sizeof(EventContainer) * event_handler.timed_events_count); /* resize */
+
+ _status = 0;
+
+ }
+ else _status = -1;
+
+UNLOCK((&event_handler));
+
+ return _status;
+}
+
+int reset_timer_event ( int id, uint32_t timeout )
+{
+ int _status;
+
+LOCK((&event_handler));
+
+ EventContainer* _it = event_handler.timed_events;
+
+ int _i = event_handler.timed_events_count;
+
+ /* Find it and change */
+ for ( ; _i; _i-- ) {
+ if ( _it->id == id ) {
+ _it->timeout = timeout + ((uint32_t)(current_time() / 1000));
+ break;
+ }
+ ++_it;
+ }
+
+ _status = _i ? -1 : 0;
+
+UNLOCK((&event_handler));
+
+ return _status;
+}
+
+/* Remove timer from array */
+inline__ int cancel_timer_event ( int id )
+{
+ return pop_id (&event_handler.timed_events, &event_handler.timed_events_count, id );
+}
+
+
+/* Initialization and termination of event polls
+ * This will be run at the beginning and the end of the program execution.
+ * I think that's the best way to do it.
+ */
+
+void __attribute__((constructor)) init_event_poll ()
+{
+ event_handler.timed_events = NULL;
+ event_handler.timed_events_count = 0;
+
+ event_handler.running = 1;
+
+ pthread_mutex_init(&event_handler.mutex, NULL);
+
+ RUN_IN_THREAD(event_poll, &event_handler);
+}
+
+void __attribute__((destructor)) terminate_event_poll()
+{
+ /* Exit thread */
+ event_handler.running = 0;
+
+ /* Keep the global until thread exits */
+ while (event_handler.running > -1) {
+ event_handler.running;
+ usleep(FREQUENCY*2);
+ }
+
+ pthread_mutex_destroy( &event_handler.mutex );
+}
diff --git a/toxcore/event.h b/toxcore/event.h
new file mode 100755
index 00000000..690cc1ca
--- /dev/null
+++ b/toxcore/event.h
@@ -0,0 +1,51 @@
+/** event.h
+ *
+ * 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 .
+ *
+ *
+ * Report bugs/suggestions to me ( mannol ) at either #tox-dev @ freenode.net:6667 or
+ * my email: eniz_vukovic@hotmail.com
+ */
+
+
+#ifndef __TOXEVENT
+#define __TOXEVENT
+
+
+/**
+ * - Events are, in fact, ran in their own threads upon execution.
+ * - Event handler is initialized at the start, before the main() function
+ * and terminated after it's execution.
+ * - Timers are checked for timeout every ~10000 ns.
+ * - Timers can be canceled or ran immediately via
+ * timer_release() or timer_now() functions.
+ * - Timeout is measured in milliseconds.
+ *
+ * NOTE: timer_reset () and timer_now() are not tested nor usable atm
+ *
+ */
+extern struct _Event
+{
+ int (*rise) (void* ( func ) ( void* ), void* arg);
+ int (*timer_reset ) ( int id, unsigned timeout );
+ int (*timer_alloc) (void* ( func ) ( void* ), void* arg, unsigned timeout);
+ int (*timer_release) (int id);
+ int (*timer_now) ( int id );
+} event;
+
+#endif /* _MSI__EVENT_H_ */
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/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_ */
diff --git a/toxrtp/Makefile.inc b/toxrtp/Makefile.inc
deleted file mode 100644
index 801a7fd3..00000000
--- a/toxrtp/Makefile.inc
+++ /dev/null
@@ -1,34 +0,0 @@
-if BUILD_AV
-
-lib_LTLIBRARIES += libtoxrtp.la
-
-libtoxrtp_la_include_HEADERS = \
- ../toxrtp/toxrtp.h
-
-libtoxrtp_la_includedir = $(includedir)/tox
-
-libtoxrtp_la_SOURCES = ../toxrtp/toxrtp_error.h \
- ../toxrtp/toxrtp_error.c \
- ../toxrtp/toxrtp_error_id.h \
- ../toxrtp/toxrtp_helper.h \
- ../toxrtp/toxrtp_helper.c \
- ../toxrtp/toxrtp.h \
- ../toxrtp/toxrtp.c \
- ../toxrtp/toxrtp_message.h \
- ../toxrtp/toxrtp_message.c \
- ../toxcore/network.h \
- ../toxcore/network.c \
- ../toxcore/util.h \
- ../toxcore/util.c
-
-libtoxrtp_la_CFLAGS = -I../toxcore \
- -I../toxrtp \
- $(NACL_CFLAGS)
-
-libtoxrtp_la_LDFLAGS = $(TOXRTP_LT_LDFLAGS) \
- $(NACL_LDFLAGS) \
- $(EXTRA_LT_LDFLAGS)
-
-libtoxrtp_la_LIBS = $(NACL_LIBS)
-
-endif
diff --git a/toxrtp/tests/Makefile.inc b/toxrtp/tests/Makefile.inc
deleted file mode 100644
index 8d1c8b69..00000000
--- a/toxrtp/tests/Makefile.inc
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/toxrtp/tests/test_bidirect.c b/toxrtp/tests/test_bidirect.c
deleted file mode 100644
index b5a0899e..00000000
--- a/toxrtp/tests/test_bidirect.c
+++ /dev/null
@@ -1,109 +0,0 @@
-#define _BSD_SOURCE
-
-#include "../toxrtp.h"
-#include "../toxrtp_message.h"
-#include
-#include
-#include
-#include
-#include
-
-#include "test_helper.h"
-#include "../../toxcore/tox.h"
-
-#ifdef _CT_BIDIRECT
-
-int _print_help( const char* name )
-{
- char* _help = malloc( 300 );
- memset(_help, '\0', 300);
-
- strcat(_help, " Usage: ");
- strcat(_help, name);
- strcat(_help, "\n -d IP ( destination )\n"
- " -p PORT ( dest Port )\n"
- " -l PORT ( listen Port ) \n");
-
- puts ( _help );
-
- free(_help);
- return FAILURE;
-}
-
-int main( int argc, char* argv[] )
-{
- int status;
- tox_IP_Port Ip_port;
- const char* ip, *psend, *plisten;
- uint16_t port_send, port_listen;
- const uint8_t* test_bytes = "0123456789012345678901234567890123456789012345678901234567890123456789"
- "0123456789012345678901234567890123456789012345678901234567890123456789"
- "0123456789012345678901234567890123456789012345678901234567890123456789"
- "0123456789012345678901234567890123456789012345678901234567890123456789";
-
-
- rtp_session_t* _m_session;
- rtp_msg_t *_m_msg_R, *_m_msg_S;
- arg_t* _list = parse_args ( argc, argv );
-
- ip = find_arg_duble(_list, "-d");
- psend = find_arg_duble(_list, "-p");
- plisten = find_arg_duble(_list, "-l");
-
- if ( !ip || !plisten || !psend )
- return _print_help(argv[0]);
-
- port_send = atoi(psend);
- port_listen = atoi(plisten);
-
- IP_Port local, remote;
-
- /*
- * This is the Local ip. We initiate networking on
- * this value for it's the local one. To make stuff simpler we receive over this value
- * and send on the other one ( see remote )
- */
- local.ip.i = htonl(INADDR_ANY);
- local.port = port_listen;
- Networking_Core* _networking = new_networking(local.ip, port_listen);
-
- if ( !_networking )
- return FAILURE;
-
- int _socket = _networking->sock;
- /*
- * Now this is the remote. It's used by rtp_session_t to determine the receivers ip etc.
- */
- t_setipport ( ip, port_send, &remote );
- _m_session = rtp_init_session(-1, -1);
- rtp_add_receiver( _m_session, &remote );
-
- /* Now let's start our main loop in both recv and send mode */
-
- for ( ;; )
- {
- /*
- * This part checks for received messages and if gotten one
- * display 'Received msg!' indicator and free message
- */
- _m_msg_R = rtp_recv_msg ( _m_session );
-
- if ( _m_msg_R ) {
- puts ( "Received msg!" );
- rtp_free_msg(_m_session, _m_msg_R);
- }
- /* -------------------- */
-
- /*
- * This one makes a test msg and sends that message to the 'remote'
- */
- _m_msg_S = rtp_msg_new ( _m_session, test_bytes, 280 ) ;
- rtp_send_msg ( _m_session, _m_msg_S, _socket );
- usleep ( 10000 );
- /* -------------------- */
- }
-
- return SUCCESS;
-}
-
-#endif /* _CT_BIDIRECT */
diff --git a/toxrtp/tests/test_headers.c b/toxrtp/tests/test_headers.c
deleted file mode 100644
index be3f1375..00000000
--- a/toxrtp/tests/test_headers.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/* test_headers.c
- *
- * Tests header parsing. You probably won't need this. !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 .
- *
- */
-
-#include "test_helper.h"
-#include "../toxrtp.h"
-#include "../toxrtp_message.h"
-
-#include
-#include
-#include
-#include
-#include
-#include "../toxrtp_error_id.h"
-
-#define _CT_HEADERS_
-
-#ifdef _CT_HEADERS
-
-int _socket;
-pthread_mutex_t _mutex;
-
-int print_help()
-{
- puts (
- " Usage: Tuxrtp [-s (send mode) -d IP ( destination ) -p PORT ( dest Port )] \n"
- " [-r ( recv mode ) ]"
- );
- return FAILURE;
-}
-
-void print_session_stats ( rtp_session_t* _m_session )
-{
- printf
- (
- "Session test:\n"
- "\tPackets sent:%d\n"
- "\tPackets recv:%d\n\n"
- "\tBytes sent:%d\n"
- "\tBytes recv:%d\n\n"
- "\tHeader CCSRs:%d\n"
- ,
- _m_session->_packets_sent,
- _m_session->_packets_recv,
- _m_session->_bytes_sent,
- _m_session->_bytes_recv,
- _m_session->_cc
- );
-
- uint8_t i;
- for ( i = 0; i < _m_session->_cc; i++ ) {
- printf (
- "\t%d > :%d\n", i, _m_session->_csrc[i]
- );
- }
-}
-
-void print_header_info ( rtp_header_t* _header )
-{
- printf
- (
- "Header info:\n"
- "\tVersion :%d\n"
- "\tPadding :%d\n"
- "\tExtension :%d\n"
- "\tCSRC count :%d\n"
- "\tPayload type :%d\n"
- "\tMarker :%d\n\n"
-
- "\tSSrc :%d\n"
- "\tSequence num :%d\n"
- "\tLenght: :%d\n"
- "\tCSRC's:\n"
- ,
- rtp_header_get_flag_version ( _header ),
- rtp_header_get_flag_padding ( _header ),
- rtp_header_get_flag_extension ( _header ),
- rtp_header_get_flag_CSRC_count ( _header ),
- rtp_header_get_setting_payload_type ( _header ),
- rtp_header_get_setting_marker ( _header ),
-
- _header->_ssrc,
- _header->_sequence_number,
- _header->_length
- );
-
-
- uint8_t i;
- for ( i = 0; i < rtp_header_get_flag_CSRC_count ( _header ); i++ ) {
- printf (
- "\t%d > :%d\n", i, _header->_csrc[i]
- );
- }
-
- puts ( "\n" );
-}
-
-void print_ext_header_info(rtp_ext_header_t* _ext_header)
-{
- printf
- (
- "External Header info: \n"
- "\tLenght :%d\n"
- "\tID :%d\n"
- "\tValue H :%d\n"
- "\tValue W :%d\n\n",
- _ext_header->_ext_len,
- _ext_header->_ext_type,
- rtp_get_resolution_marking_height(_ext_header, 0),
- rtp_get_resolution_marking_width(_ext_header, 0)
- );
-}
-
-int rtp_handlepacket ( rtp_session_t* _session, rtp_msg_t* _msg )
-{
- if ( !_msg )
- return FAILURE;
-
- if ( rtp_check_late_message(_session, _msg) < 0 ) {
- rtp_register_msg(_session, _msg);
- }
-
- if ( _session->_last_msg ) {
- _session->_last_msg->_next = _msg;
- _session->_last_msg = _msg;
- } else {
- _session->_last_msg = _session->_oldest_msg = _msg;
- }
-
-
- return SUCCESS;
-}
-
-void* receivepacket_callback(void* _p_session)
-{
- rtp_msg_t* _msg;
- rtp_session_t* _session = _p_session;
-
- uint32_t _bytes;
- tox_IP_Port _from;
- uint8_t _socket_data[MAX_UDP_PACKET_SIZE];
-
- int _m_socket = _socket;
-
- while ( 1 )
- {
- int _status = receivepacket ( _m_socket, &_from, _socket_data, &_bytes );
-
- if ( _status == FAILURE ) { /* nothing recved */
- usleep(1000);
- continue;
- }
-
- pthread_mutex_lock ( &_mutex );
-
- _msg = rtp_msg_parse ( NULL, _socket_data, _bytes );
- rtp_handlepacket(_session, _msg);
-
- pthread_mutex_unlock ( &_mutex );
- }
-
- pthread_exit(NULL);
-}
-
-int main ( int argc, char* argv[] )
-{
- arg_t* _list = parse_args ( argc, argv );
-
- if ( _list == NULL ) { /* failed */
- return print_help();
- }
-
- pthread_mutex_init ( &_mutex, NULL );
-
- int status;
- IP_Port Ip_port;
- const char* ip;
- uint16_t port;
-
-
- const uint8_t* test_bytes [300];
- memset(test_bytes, 'a', 300);
-
- rtp_session_t* _m_session;
- rtp_msg_t* _m_msg;
-
- if ( find_arg_simple ( _list, "-r" ) != FAILURE ) { /* Server mode */
-
- IP_Port LOCAL_IP; /* since you need at least 1 recv-er */
- LOCAL_IP.ip.i = htonl(INADDR_ANY);
- LOCAL_IP.port = RTP_PORT;
- LOCAL_IP.padding = -1;
-
- _m_session = rtp_init_session ( -1, -1 );
- Networking_Core* _networking = new_networking(LOCAL_IP.ip, RTP_PORT_LISTEN);
- _socket = _networking->sock;
-
-
- if ( !_networking ){
- pthread_mutex_destroy ( &_mutex );
- return FAILURE;
- }
-
- int _socket = _networking->sock;
-
- if ( status < 0 ) {
- pthread_mutex_destroy ( &_mutex );
- return FAILURE;
- }
- /* -- start in recv mode, get 1 message and then analyze it -- */
- pthread_t _tid;
- RUN_IN_THREAD(receivepacket_callback, _tid, _m_session)
-
- for ( ; ; ) { /* Recv for x seconds */
- _m_msg = rtp_recv_msg ( _m_session );
-
- /* _m_msg = rtp_session_get_message_queded ( _m_session ); DEPRECATED */
- if ( _m_msg ) {
- /*rtp_free_msg(_m_session, _m_msg);
- _m_msg = NULL;*/
- printf("Timestamp: %d\n", _m_msg->_header->_timestamp);
- }
-
- usleep ( 10000 );
- }
-
- if ( _m_msg->_header ) {
- rtp_header_print ( _m_msg->_header );
- }
- if ( _m_msg->_ext_header ){
- print_ext_header_info(_m_msg->_ext_header);
- }
-
- //print_session_stats ( _m_session );
-
-
- //printf ( "Payload: ( %d ) \n%s\n", _m_msg->_length, _m_msg->_data );
-
-
- } else if ( find_arg_simple ( _list, "-s" ) != FAILURE ) {
- ip = find_arg_duble ( _list, "-d" );
-
- if ( ip == NULL ) {
- pthread_mutex_destroy ( &_mutex );
- return FAILURE;
- }
-
- const char* _port = find_arg_duble ( _list, "-p" );
-
- if ( _port != NULL ) {
- port = atoi ( _port );
- }
-
- t_setipport ( ip, port, &Ip_port );
- printf ( "Remote: %s:%d\n", ip, port );
-
- Networking_Core* _networking = new_networking(Ip_port.ip, RTP_PORT);
-
- if ( !_networking ){
- pthread_mutex_destroy ( &_mutex );
- return FAILURE;
- }
-
- int _socket = _networking->sock;
-
- _m_session = rtp_init_session ( -1, -1 );
- rtp_add_receiver( _m_session, &Ip_port );
- //rtp_add_resolution_marking(_m_session, 1920, 1080);
- //rtp_add_framerate_marking(_m_session, 1000);
-
- puts ( "Now sending payload!\n" );
- uint16_t _first_sequ = _m_session->_sequence_number;
-
- /* use already defined buffer lenght */
- while ( 1 ){
- _m_msg = rtp_msg_new ( _m_session, test_bytes, 300 );
- rtp_send_msg ( _m_session, _m_msg, _socket );
- usleep(10000);
- }
-
- if ( _m_session->_last_error ) {
- puts ( _m_session->_last_error );
- }
-
- return rtp_terminate_session(_m_session);
-
- } else {
- pthread_mutex_destroy ( &_mutex );
- return FAILURE;
- }
- pthread_mutex_destroy ( &_mutex );
-
- return SUCCESS;
-}
-
-#endif /* _CT_HEADERS */
diff --git a/toxrtp/tests/test_helper.c b/toxrtp/tests/test_helper.c
deleted file mode 100644
index 526b6b38..00000000
--- a/toxrtp/tests/test_helper.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* test_helper.c
- *
- * Tests support. !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 .
- *
- */
-
-#include "test_helper.h"
-
-#include
-#include
-
-arg_t* parse_args ( int argc, char* argv[] )
-{
- arg_t* _list = calloc(sizeof(arg_t), 1);
- _list->next = _list->prev = NULL;
-
- arg_t* it = _list;
-
- size_t val;
- for ( val = 0; val < argc; val ++ ) {
- it->value = argv[val];
-
- if ( val < argc - 1 ) { /* just about to end */
- it->next = calloc(sizeof(arg_t), 1);
- it->next->prev = it;
- it = it->next;
- it->next = NULL;
- }
- }
-
- return _list;
-}
-
-int find_arg_simple ( arg_t* _head, const char* _id )
-{
- arg_t* it = _head;
-
- int i;
- for ( i = 1; it != NULL; it = it->next ) {
- if ( strcmp ( _id, it->value ) == 0 ) {
- return i;
- }
-
- i++;
- }
-
- return FAILURE;
-}
-
-const char* find_arg_duble ( arg_t* _head, const char* _id )
-{
- arg_t* _it;
- for ( _it = _head; _it != NULL; _it = _it->next ) {
- if ( strcmp ( _id, _it->value ) == 0 ) {
- if ( _it->next && _it->next->value[0] != '-' ) { /* exclude option */
- return _it->next->value;
- } else {
- return NULL;
- }
- }
- }
-
- return NULL;
-}
-
diff --git a/toxrtp/tests/test_helper.h b/toxrtp/tests/test_helper.h
deleted file mode 100644
index de654743..00000000
--- a/toxrtp/tests/test_helper.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* test_helper.h
- *
- * Tests support. !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 _TEST__HELPER_
-#define _TEST__HELPER_
-
-#include "../toxrtp_helper.h"
-
-#define RTP_PORT 31003
-#define RTP_PORT_LISTEN 31001
-
-#define _SLEEP_INTERVAL 1000
-
-typedef struct arg_s {
- const char* value;
- struct arg_s* next;
- struct arg_s* prev;
-
-} arg_t;
-
-
-
-/* Parses arguments into d-list arg_t */
-arg_t* parse_args ( int argc, char* argv[] );
-
-/* Get a single argument ( i.e. ./test -s |find if has 's' >> | find_arg_simple(_t, "-s") )
- * A little error checking, of course, returns FAILURE if not found and if found returns position
- * where it's found.
- */
-int find_arg_simple ( arg_t* _head, const char* _id );
-
-/* Get a single argument ( i.e. ./test -d 127.0.0.1 |get 'd' value >> | find_arg_duble(_t, "-d") )
- * A little error checking, of course, returns NULL if not found and if found returns value
- * of that argument ( i.e. '127.0.0.1').
- */
-const char* find_arg_duble ( arg_t* _head, const char* _id );
-
-#endif /* _TEST__HELPER_ */
-
-
diff --git a/toxrtp/toxrtp.c b/toxrtp/toxrtp.c
deleted file mode 100644
index 6844b0b1..00000000
--- a/toxrtp/toxrtp.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/* rtp_impl.c
- *
- * Rtp implementation includes rtp_session_s struct which is a session identifier.
- * It contains session information and it's a must for every session.
- * It's best if you don't touch any variable directly but use callbacks to do so. !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 .
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include "toxrtp.h"
-#include "toxrtp_message.h"
-#include "toxrtp_helper.h"
-#include
-#include
-#include "../toxcore/util.h"
-#include "../toxcore/network.h"
-
-/* Some defines */
-#define PAYLOAD_ID_VALUE_OPUS 1
-#define PAYLOAD_ID_VALUE_VP8 2
-
-#define size_32 4
-/* End of defines */
-
-#ifdef _USE_ERRORS
-#include "toxrtp_error_id.h"
-#endif /* _USE_ERRORS */
-
-static const uint32_t _payload_table[] = /* PAYLOAD TABLE */
-{
- 8000, 8000, 8000, 8000, 8000, 8000, 16000, 8000, 8000, 8000, /* 0-9 */
- 44100, 44100, 0, 0, 90000, 8000, 11025, 22050, 0, 0, /* 10-19 */
- 0, 0, 0, 0, 0, 90000, 90000, 0, 90000, 0, /* 20-29 */
- 0, 90000, 90000, 90000, 90000, 0, 0, 0, 0, 0, /* 30-39 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40-49 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50-59 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60-69 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70-79 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-89 */
- 0, 0, 0, 0, 0, 0, PAYLOAD_ID_VALUE_OPUS, 0, 0, 0, /* 90-99 */
- 0, 0, 0, 0, 0, 0, PAYLOAD_ID_VALUE_VP8, 0, 0, 0, /* 100-109 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 110-119 */
- 0, 0, 0, 0, 0, 0, 0, 0 /* 120-127 */
-};
-
-/* Current compatibility solution */
-int m_sendpacket(Networking_Core* _core_handler, void *ip_port, uint8_t *data, uint32_t length)
-{
- return sendpacket(_core_handler, *((IP_Port*) ip_port), data, length);
-}
-
-rtp_session_t* rtp_init_session ( int max_users, int _multi_session )
-{
-#ifdef _USE_ERRORS
- REGISTER_RTP_ERRORS
-#endif /* _USE_ERRORS */
-
- rtp_session_t* _retu = calloc(sizeof(rtp_session_t), 1);
- assert(_retu);
-
- _retu->_dest_list = _retu->_last_user = NULL;
-
- _retu->_max_users = max_users;
- _retu->_packets_recv = 0;
- _retu->_packets_sent = 0;
- _retu->_bytes_sent = 0;
- _retu->_bytes_recv = 0;
- _retu->_last_error = NULL;
- _retu->_packet_loss = 0;
-
- /*
- * SET HEADER FIELDS
- */
-
- _retu->_version = RTP_VERSION; /* It's always 2 */
- _retu->_padding = 0; /* If some additional data is needed about
- * the packet */
- _retu->_extension = 0; /* If extension to header is needed */
- _retu->_cc = 1; /* It basically represents amount of contributors */
- _retu->_csrc = NULL; /* Container */
- _retu->_ssrc = t_random ( -1 );
- _retu->_marker = 0;
- _retu->_payload_type = 0; /* You should specify payload type */
-
- /* Sequence starts at random number and goes to _MAX_SEQU_NUM */
- _retu->_sequence_number = t_random ( _MAX_SEQU_NUM );
- _retu->_last_sequence_number = _retu->_sequence_number; /* Do not touch this variable */
-
- _retu->_initial_time = t_time(); /* In seconds */
- assert(_retu->_initial_time);
- _retu->_time_elapsed = 0; /* In seconds */
-
- _retu->_ext_header = NULL; /* When needed allocate */
- _retu->_exthdr_framerate = -1;
- _retu->_exthdr_resolution = -1;
-
- _retu->_csrc = calloc(sizeof(uint32_t), 1);
- assert(_retu->_csrc);
-
- _retu->_csrc[0] = _retu->_ssrc; /* Set my ssrc to the list receive */
-
- _retu->_prefix_length = 0;
- _retu->_prefix = NULL;
-
- _retu->_multi_session = _multi_session;
-
- /* Initial */
- _retu->_current_framerate = 0;
-
-
- _retu->_oldest_msg = _retu->_last_msg = NULL;
-
- pthread_mutex_init(&_retu->_mutex, NULL);
- /*
- *
- */
- return _retu;
-}
-
-int rtp_terminate_session ( rtp_session_t* _session )
-{
- if ( !_session )
- return FAILURE;
-
- if ( _session->_dest_list ){
- rtp_dest_list_t* _fordel = NULL;
- rtp_dest_list_t* _tmp = _session->_dest_list;
-
- while( _tmp ){
- _fordel = _tmp;
- _tmp = _tmp->next;
- free(_fordel);
- }
- }
-
- if ( _session->_ext_header )
- free ( _session->_ext_header );
-
- if ( _session->_csrc )
- free ( _session->_csrc );
-
- if ( _session->_prefix )
- free ( _session->_prefix );
-
- pthread_mutex_destroy(&_session->_mutex);
-
- /* And finally free session */
- free ( _session );
-
- return SUCCESS;
-}
-
-uint16_t rtp_get_resolution_marking_height ( rtp_ext_header_t* _header, uint32_t _position )
-{
- if ( _header->_ext_type & RTP_EXT_TYPE_RESOLUTION )
- return _header->_hd_ext[_position];
- else
- return 0;
-}
-
-uint16_t rtp_get_resolution_marking_width ( rtp_ext_header_t* _header, uint32_t _position )
-{
- if ( _header->_ext_type & RTP_EXT_TYPE_RESOLUTION )
- return ( _header->_hd_ext[_position] >> 16 );
- else
- return 0;
-}
-
-void rtp_free_msg ( rtp_session_t* _session, rtp_msg_t* _message )
-{
- free ( _message->_data );
-
- if ( !_session ){
- free ( _message->_header->_csrc );
- if ( _message->_ext_header ){
- free ( _message->_ext_header->_hd_ext );
- free ( _message->_ext_header );
- }
- } else {
- if ( _session->_csrc != _message->_header->_csrc )
- free ( _message->_header->_csrc );
- if ( _message->_ext_header && _session->_ext_header != _message->_ext_header ) {
- free ( _message->_ext_header->_hd_ext );
- free ( _message->_ext_header );
- }
- }
-
- free ( _message->_header );
- free ( _message );
-}
-
-rtp_header_t* rtp_build_header ( rtp_session_t* _session )
-{
- rtp_header_t* _retu;
- _retu = calloc ( sizeof * _retu, 1 );
- assert(_retu);
-
- rtp_header_add_flag_version ( _retu, _session->_version );
- rtp_header_add_flag_padding ( _retu, _session->_padding );
- rtp_header_add_flag_extension ( _retu, _session->_extension );
- rtp_header_add_flag_CSRC_count ( _retu, _session->_cc );
- rtp_header_add_setting_marker ( _retu, _session->_marker );
- rtp_header_add_setting_payload ( _retu, _session->_payload_type );
-
- _retu->_sequence_number = _session->_sequence_number;
- _session->_time_elapsed = t_time() - _session->_initial_time;
- _retu->_timestamp = t_time();
- _retu->_ssrc = _session->_ssrc;
-
- if ( _session->_cc > 0 ) {
- _retu->_csrc = calloc(sizeof(uint32_t), _session->_cc);
- assert(_retu->_csrc);
-
- int i;
-
- for ( i = 0; i < _session->_cc; i++ ) {
- _retu->_csrc[i] = _session->_csrc[i];
- }
- } else {
- _retu->_csrc = NULL;
- }
-
- _retu->_length = _MIN_HEADER_LENGTH + ( _session->_cc * size_32 );
-
- return _retu;
-}
-
-void rtp_set_payload_type ( rtp_session_t* _session, uint8_t _payload_value )
-{
- _session->_payload_type = _payload_value;
-}
-uint32_t rtp_get_payload_type ( rtp_session_t* _session )
-{
- return _payload_table[_session->_payload_type];
-}
-
-int rtp_add_receiver ( rtp_session_t* _session, tox_IP_Port* _dest )
-{
- if ( !_session )
- return FAILURE;
-
- rtp_dest_list_t* _new_user = calloc(sizeof(rtp_dest_list_t), 1);
- assert(_new_user);
-
- _new_user->next = NULL;
- _new_user->_dest = *_dest;
-
- if ( _session->_last_user == NULL ) { /* New member */
- _session->_dest_list = _session->_last_user = _new_user;
-
- } else { /* Append */
- _session->_last_user->next = _new_user;
- _session->_last_user = _new_user;
- }
-
- return SUCCESS;
-}
-
-int rtp_send_msg ( rtp_session_t* _session, rtp_msg_t* _msg, void* _core_handler )
-{
- if ( !_msg || _msg->_data == NULL || _msg->_length <= 0 ) {
- t_perror ( RTP_ERROR_EMPTY_MESSAGE );
- return FAILURE;
- }
-
- int _last;
- unsigned long long _total = 0;
-
- size_t _length = _msg->_length;
- uint8_t _send_data [ MAX_UDP_PACKET_SIZE ];
-
- uint16_t _prefix_length = _session->_prefix_length;
-
- _send_data[0] = 70;
-
- if ( _session->_prefix && _length + _prefix_length < MAX_UDP_PACKET_SIZE ) {
- /*t_memcpy(_send_data, _session->_prefix, _prefix_length);*/
- t_memcpy ( _send_data + 1, _msg->_data, _length );
- } else {
- t_memcpy ( _send_data + 1, _msg->_data, _length );
- }
-
- /* Set sequ number */
- if ( _session->_sequence_number >= _MAX_SEQU_NUM ) {
- _session->_sequence_number = 0;
- } else {
- _session->_sequence_number++;
- }
-
- /* Start sending loop */
- rtp_dest_list_t* _it;
- for ( _it = _session->_dest_list; _it != NULL; _it = _it->next ) {
-
- _last = m_sendpacket ( _core_handler, &_it->_dest, _send_data, _length + 1);
-
- if ( _last < 0 ) {
- t_perror ( RTP_ERROR_STD_SEND_FAILURE );
- printf("Stderror: %s", strerror(errno));
- } else {
- _session->_packets_sent ++;
- _total += _last;
- }
-
- }
-
- rtp_free_msg ( _session, _msg );
- _session->_bytes_sent += _total;
- return SUCCESS;
-}
-
-rtp_msg_t* rtp_recv_msg ( rtp_session_t* _session )
-{
- if ( !_session )
- return NULL;
-
- rtp_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 rtp_store_msg ( rtp_session_t* _session, rtp_msg_t* _msg )
-{
- if ( rtp_check_late_message(_session, _msg) < 0 ) {
- rtp_register_msg(_session, _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);
- return;
-}
-
-int rtp_release_session_recv ( rtp_session_t* _session )
-{
- if ( !_session ){
- return FAILURE;
- }
-
- rtp_msg_t* _tmp,* _it;
-
- pthread_mutex_lock(&_session->_mutex);
-
- for ( _it = _session->_oldest_msg; _it; _it = _tmp ){
- _tmp = _it->_next;
- rtp_free_msg(_session, _it);
- }
-
- _session->_last_msg = _session->_oldest_msg = NULL;
-
- pthread_mutex_unlock(&_session->_mutex);
-
- return SUCCESS;
-}
-
-rtp_msg_t* rtp_msg_new ( rtp_session_t* _session, const uint8_t* _data, uint32_t _length )
-{
- if ( !_session )
- return NULL;
-
- uint8_t* _from_pos;
- rtp_msg_t* _retu = calloc(sizeof(rtp_msg_t), 1);
- assert(_retu);
-
- /* Sets header values and copies the extension header in _retu */
- _retu->_header = rtp_build_header ( _session ); /* It allocates memory and all */
- _retu->_ext_header = _session->_ext_header;
-
- uint32_t _total_lenght = _length + _retu->_header->_length;
-
- if ( _retu->_ext_header ) {
-
- _total_lenght += ( _MIN_EXT_HEADER_LENGTH + _retu->_ext_header->_ext_len * size_32 );
- /* Allocate Memory for _retu->_data */
- _retu->_data = calloc ( sizeof _retu->_data, _total_lenght );
- assert(_retu->_data);
-
- _from_pos = rtp_add_header ( _retu->_header, _retu->_data );
- _from_pos = rtp_add_extention_header ( _retu->_ext_header, _from_pos + 1 );
- } else {
- /* Allocate Memory for _retu->_data */
- _retu->_data = calloc ( sizeof _retu->_data, _total_lenght );
- assert(_retu->_data);
-
- _from_pos = rtp_add_header ( _retu->_header, _retu->_data );
- }
-
- /*
- * Parses the extension header into the message
- * Of course if any
- */
-
- /* Appends _data on to _retu->_data */
- t_memcpy ( _from_pos + 1, _data, _length );
-
- _retu->_length = _total_lenght;
-
- _retu->_next = NULL;
-
- return _retu;
-}
-
-rtp_msg_t* rtp_msg_parse ( rtp_session_t* _session, const uint8_t* _data, uint32_t _length )
-{
- rtp_msg_t* _retu = calloc(sizeof(rtp_msg_t), 1);
- assert(_retu);
-
- _retu->_header = rtp_extract_header ( _data, _length ); /* It allocates memory and all */
- if ( !_retu->_header ){
- free(_retu);
- return NULL;
- }
-
- _retu->_length = _length - _retu->_header->_length;
-
- uint16_t _from_pos = _retu->_header->_length;
-
-
- if ( rtp_header_get_flag_extension ( _retu->_header ) ) {
- _retu->_ext_header = rtp_extract_ext_header ( _data + _from_pos, _length );
- if ( _retu->_ext_header ){
- _retu->_length -= ( _MIN_EXT_HEADER_LENGTH + _retu->_ext_header->_ext_len * size_32 );
- _from_pos += ( _MIN_EXT_HEADER_LENGTH + _retu->_ext_header->_ext_len * size_32 );
- } else {
- free (_retu->_ext_header);
- free (_retu->_header);
- free (_retu);
- return NULL;
- }
- } else {
- _retu->_ext_header = NULL;
- }
-
- /* Get the payload */
- _retu->_data = calloc ( sizeof ( uint8_t ), _retu->_length );
- assert(_retu->_data);
-
- t_memcpy ( _retu->_data, _data + _from_pos, _length - _from_pos );
-
- _retu->_next = NULL;
-
-
- if ( _session && !_session->_multi_session && rtp_check_late_message(_session, _retu) < 0 ){
- rtp_register_msg(_session, _retu);
- }
-
- return _retu;
-}
-
-int rtp_check_late_message (rtp_session_t* _session, rtp_msg_t* _msg)
-{
- /*
- * Check Sequence number. If this new msg has lesser number then the _session->_last_sequence_number
- * it shows that the message came in late
- */
- if ( _msg->_header->_sequence_number < _session->_last_sequence_number &&
- _msg->_header->_timestamp < _session->_current_timestamp
- ) {
- return SUCCESS; /* Drop the packet. You can check if the packet dropped by checking _packet_loss increment. */
- }
- return FAILURE;
-}
-
-void rtp_register_msg ( rtp_session_t* _session, rtp_msg_t* _msg )
-{
- _session->_last_sequence_number = _msg->_header->_sequence_number;
- _session->_current_timestamp = _msg->_header->_timestamp;
-}
-
-
-int rtp_add_resolution_marking ( rtp_session_t* _session, uint16_t _width, uint16_t _height )
-{
- if ( !_session )
- return FAILURE;
-
- rtp_ext_header_t* _ext_header = _session->_ext_header;
- _session->_exthdr_resolution = 0;
-
- if ( ! ( _ext_header ) ) {
- _session->_ext_header = calloc (sizeof(rtp_ext_header_t), 1);
- assert(_session->_ext_header);
-
- _session->_extension = 1;
- _session->_ext_header->_ext_len = 1;
- _ext_header = _session->_ext_header;
- _session->_ext_header->_hd_ext = calloc(sizeof(uint32_t), 1);
- assert(_session->_ext_header->_hd_ext);
-
- } else { /* If there is need for more headers this will be needed to change */
- if ( !(_ext_header->_ext_type & RTP_EXT_TYPE_RESOLUTION) ){
- uint32_t _exthdr_framerate = _ext_header->_hd_ext[_session->_exthdr_framerate];
- /* it's position is at 2nd place by default */
- _session->_exthdr_framerate ++;
-
- /* Update length */
- _ext_header->_ext_len++;
-
- /* Allocate the value */
- _ext_header->_hd_ext = realloc(_ext_header->_hd_ext, sizeof(rtp_ext_header_t) * _ext_header->_ext_len);
- assert(_ext_header->_hd_ext);
-
- /* Reset other values */
- _ext_header->_hd_ext[_session->_exthdr_framerate] = _exthdr_framerate;
- }
- }
-
- /* Add flag */
- _ext_header->_ext_type |= RTP_EXT_TYPE_RESOLUTION;
-
- _ext_header->_hd_ext[_session->_exthdr_resolution] = _width << 16 | ( uint32_t ) _height;
-
- return SUCCESS;
-}
-
-int rtp_remove_resolution_marking ( rtp_session_t* _session )
-{
- if ( _session->_extension == 0 || ! ( _session->_ext_header ) ) {
- t_perror ( RTP_ERROR_INVALID_EXTERNAL_HEADER );
- return FAILURE;
- }
-
- if ( !( _session->_ext_header->_ext_type & RTP_EXT_TYPE_RESOLUTION ) ) {
- t_perror ( RTP_ERROR_INVALID_EXTERNAL_HEADER );
- return FAILURE;
- }
-
- _session->_ext_header->_ext_type &= ~RTP_EXT_TYPE_RESOLUTION; /* Remove the flag */
- _session->_exthdr_resolution = -1; /* Remove identifier */
-
- /* Check if extension is empty */
- if ( _session->_ext_header->_ext_type == 0 ){
-
- free ( _session->_ext_header->_hd_ext );
- free ( _session->_ext_header );
-
- _session->_ext_header = NULL; /* It's very important */
- _session->_extension = 0;
-
- } else {
- _session->_ext_header->_ext_len --;
-
- /* this will also be needed to change if there are more than 2 headers */
- if ( _session->_ext_header->_ext_type & RTP_EXT_TYPE_FRAMERATE ){
- memcpy(_session->_ext_header->_hd_ext + 1, _session->_ext_header->_hd_ext, _session->_ext_header->_ext_len);
- _session->_exthdr_framerate = 0;
- _session->_ext_header->_hd_ext = realloc( _session->_ext_header->_hd_ext, sizeof( rtp_ext_header_t ) * _session->_ext_header->_ext_len );
- assert(_session->_ext_header->_hd_ext);
- }
- }
-
- return SUCCESS;
-}
-
-int rtp_add_framerate_marking ( rtp_session_t* _session, uint32_t _value )
-{
- if ( !_session )
- return FAILURE;
-
- rtp_ext_header_t* _ext_header = _session->_ext_header;
- _session->_exthdr_framerate = 0;
-
- if ( ! ( _ext_header ) ) {
- _session->_ext_header = calloc (sizeof(rtp_ext_header_t), 1);
- assert(_session->_ext_header);
-
- _session->_extension = 1;
- _session->_ext_header->_ext_len = 1;
- _ext_header = _session->_ext_header;
- _session->_ext_header->_hd_ext = calloc(sizeof(uint32_t), 1);
- assert(_session->_ext_header->_hd_ext);
- } else { /* If there is need for more headers this will be needed to change */
- if ( !(_ext_header->_ext_type & RTP_EXT_TYPE_FRAMERATE) ){
- /* it's position is at 2nd place by default */
- _session->_exthdr_framerate ++;
-
- /* Update length */
- _ext_header->_ext_len++;
-
- /* Allocate the value */
- _ext_header->_hd_ext = realloc(_ext_header->_hd_ext, sizeof(rtp_ext_header_t) * _ext_header->_ext_len);
- assert(_ext_header->_hd_ext);
-
- }
- }
-
- /* Add flag */
- _ext_header->_ext_type |= RTP_EXT_TYPE_FRAMERATE;
-
- _ext_header->_hd_ext[_session->_exthdr_framerate] = _value;
-
- return SUCCESS;
-}
-
-
-int rtp_remove_framerate_marking ( rtp_session_t* _session )
-{
- if ( _session->_extension == 0 || ! ( _session->_ext_header ) ) {
- t_perror ( RTP_ERROR_INVALID_EXTERNAL_HEADER );
- return FAILURE;
- }
-
- if ( !( _session->_ext_header->_ext_type & RTP_EXT_TYPE_FRAMERATE ) ) {
- t_perror ( RTP_ERROR_INVALID_EXTERNAL_HEADER );
- return FAILURE;
- }
-
- _session->_ext_header->_ext_type &= ~RTP_EXT_TYPE_FRAMERATE; /* Remove the flag */
- _session->_exthdr_framerate = -1; /* Remove identifier */
- _session->_ext_header->_ext_len --;
-
- /* Check if extension is empty */
- if ( _session->_ext_header->_ext_type == 0 ){
-
- free ( _session->_ext_header->_hd_ext );
- free ( _session->_ext_header );
-
- _session->_ext_header = NULL; /* It's very important */
- _session->_extension = 0;
-
- } else if ( !_session->_ext_header->_ext_len ) {
-
- /* this will also be needed to change if there are more than 2 headers */
- _session->_ext_header->_hd_ext = realloc( _session->_ext_header->_hd_ext, sizeof( rtp_ext_header_t ) * _session->_ext_header->_ext_len );
- assert(_session->_ext_header->_hd_ext);
-
- }
-
- return SUCCESS;
-}
-
-uint32_t rtp_get_framerate_marking ( rtp_ext_header_t* _header )
-{
- if ( _header->_ext_len == 1 ){
- return _header->_hd_ext[0];
- } else {
- return _header->_hd_ext[1];
- }
-}
-
-int rtp_set_prefix ( rtp_session_t* _session, uint8_t* _prefix, uint16_t _prefix_length )
-{
- if ( !_session )
- return FAILURE;
-
- if ( _session->_prefix ) {
- free ( _session->_prefix );
- }
-
- _session->_prefix = calloc ( ( sizeof * _session->_prefix ), _prefix_length );
- assert(_session->_prefix);
-
- t_memcpy ( _session->_prefix, _prefix, _prefix_length );
- _session->_prefix_length = _prefix_length;
-
- return SUCCESS;
-}
diff --git a/toxrtp/toxrtp.h b/toxrtp/toxrtp.h
deleted file mode 100644
index 0aa89993..00000000
--- a/toxrtp/toxrtp.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/* rtp_impl.h
- *
- * Rtp implementation includes rtp_session_s struct which is a session identifier.
- * It contains session information and it's a must for every session.
- * It's best if you don't touch any variable directly but use callbacks to do so. !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 _RTP__IMPL_H_
-#define _RTP__IMPL_H_
-
-#define RTP_VERSION 2
-#include
-#include "tox.h"
-#include
-/* Extension header flags */
-#define RTP_EXT_TYPE_RESOLUTION 0x01
-#define RTP_EXT_TYPE_FRAMERATE 0x02
-
-/* Some defines */
-
-#define RTP_PACKET 70
-
-/* Payload identifiers */
-
-/* Audio */
-#define _PAYLOAD_OPUS 96
-
-/* Video */
-#define _PAYLOAD_VP8 106
-
-/* End of Payload identifiers */
-
-/* End of defines */
-
-
-/* Our main session descriptor.
- * It measures the session variables and controls
- * the entire session. There are functions for manipulating
- * the session so tend to use those instead of directly accessing
- * session parameters.
- */
-typedef struct rtp_session_s {
- uint8_t _version;
- uint8_t _padding;
- uint8_t _extension;
- uint8_t _cc;
- uint8_t _marker;
- uint8_t _payload_type;
- uint16_t _sequence_number; /* Set when sending */
- uint16_t _last_sequence_number; /* Check when recving msg */
- uint32_t _initial_time;
- uint32_t _time_elapsed;
- uint32_t _current_timestamp;
- uint32_t _ssrc;
- uint32_t *_csrc;
-
-
- /* If some additional data must be sent via message
- * apply it here. Only by allocating this member you will be
- * automatically placing it within a message.
- */
-
- struct rtp_ext_header_s *_ext_header;
- /* External header identifiers */
- int _exthdr_resolution;
- int _exthdr_framerate;
-
- int _max_users; /* -1 undefined */
-
- uint64_t _packets_sent; /* measure packets */
- uint64_t _packets_recv;
-
- uint64_t _bytes_sent;
- uint64_t _bytes_recv;
-
- uint64_t _packet_loss;
-
- const char *_last_error;
-
- struct rtp_dest_list_s *_dest_list;
- struct rtp_dest_list_s *_last_user; /* a tail for faster appending */
-
- struct rtp_msg_s *_oldest_msg;
- struct rtp_msg_s *_last_msg; /* tail */
-
- uint16_t _prefix_length;
- uint8_t *_prefix;
-
- /* Specifies multiple session use.
- * When using one session it uses default value ( -1 )
- * Otherwise it's set to 1 and rtp_register_msg () is required
- */
- int _multi_session;
-
- uint32_t _current_framerate;
-
- pthread_mutex_t _mutex;
-
-} rtp_session_t;
-
-
-/*
- * Now i don't believe we need to store this _from thing every time
- * since we have csrc table but will leave it like this for a while
- */
-
-
-void rtp_free_msg ( rtp_session_t *_session, struct rtp_msg_s *_msg );
-int rtp_release_session_recv ( rtp_session_t *_session );
-
-/* Functions handling receiving */
-struct rtp_msg_s *rtp_recv_msg ( rtp_session_t *_session );
-void rtp_store_msg ( rtp_session_t *_session, struct rtp_msg_s *_msg );
-
-/*
- * rtp_msg_parse() stores headers separately from the payload data
- * and so the _length variable is set accordingly
- */
-struct rtp_msg_s *rtp_msg_parse ( rtp_session_t *_session, const uint8_t *_data, uint32_t _length );
-
-int rtp_check_late_message (rtp_session_t *_session, struct rtp_msg_s *_msg);
-void rtp_register_msg ( rtp_session_t *_session, struct rtp_msg_s * );
-
-/* Functions handling sending */
-int rtp_send_msg ( rtp_session_t *_session, struct rtp_msg_s *_msg, void *_core_handler );
-
-/*
- * rtp_msg_new() stores headers and payload data in one container ( _data )
- * and the _length is set accordingly. Returned message is used for sending only
- * so there is not much use of the headers there
- */
-struct rtp_msg_s *rtp_msg_new ( rtp_session_t *_session, const uint8_t *_data, uint32_t _length );
-
-
-/* Convenient functions for creating a header */
-struct rtp_header_s *rtp_build_header ( rtp_session_t *_session );
-
-/* Functions handling session control */
-
-/* Handling an rtp packet */
-/* int rtp_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); */
-
-/* Session initiation and termination.
- * Set _multi_session to -1 if not using multiple sessions
- */
-rtp_session_t *rtp_init_session ( int _max_users, int _multi_session );
-int rtp_terminate_session ( rtp_session_t *_session );
-
-/* Adding receiver */
-int rtp_add_receiver ( rtp_session_t *_session, tox_IP_Port *_dest );
-
-/* Convenient functions for marking the resolution */
-int rtp_add_resolution_marking ( rtp_session_t *_session, uint16_t _width, uint16_t _height );
-int rtp_remove_resolution_marking ( rtp_session_t *_session );
-uint16_t rtp_get_resolution_marking_height ( struct rtp_ext_header_s *_header, uint32_t _position );
-uint16_t rtp_get_resolution_marking_width ( struct rtp_ext_header_s *_header, uint32_t _position );
-
-int rtp_add_framerate_marking ( rtp_session_t *_session, uint32_t _value );
-int rtp_remove_framerate_marking ( rtp_session_t *_session );
-uint32_t rtp_get_framerate_marking ( struct rtp_ext_header_s *_header );
-/* Convenient functions for marking the payload */
-void rtp_set_payload_type ( rtp_session_t *_session, uint8_t _payload_value );
-uint32_t rtp_get_payload_type ( rtp_session_t *_session );
-
-/* When using RTP in core be sure to set prefix when sending via rtp_send_msg */
-int rtp_set_prefix ( rtp_session_t *_session, uint8_t *_prefix, uint16_t _prefix_length );
-
-#endif /* _RTP__IMPL_H_ */
diff --git a/toxrtp/toxrtp_error.c b/toxrtp/toxrtp_error.c
deleted file mode 100644
index 3a7ff9a5..00000000
--- a/toxrtp/toxrtp_error.c
+++ /dev/null
@@ -1,68 +0,0 @@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include "toxrtp_error.h"
-#include "toxrtp_helper.h"
-
-#include
-#include
-#include
-#include
-#include
-
-typedef struct rtp_error_s {
- char* _message;
- int _id;
-
-} rtp_error_t;
-
-static rtp_error_t* _register = NULL;
-static size_t _it = 0;
-
-void t_rtperr_register ( int _id, const char* _info )
-{
- size_t _info_size = strlen ( _info );
-
- if ( !_register ) {
- _register = calloc ( sizeof ( rtp_error_t ), 1 );
- } else {
- _register = realloc ( _register, sizeof ( rtp_error_t ) * ( _it + 1 ) );
- }
- assert(_register);
-
-
- rtp_error_t* _current = & _register[_it];
-
- _current->_id = _id;
- _current->_message = calloc ( sizeof(char), _info_size );
- assert(_current->_message);
-
- t_memcpy ( (uint8_t*)_current->_message, (const uint8_t*)_info, _info_size );
- _it ++;
-}
-
-const char* t_rtperr ( int _errno )
-{
- if ( !_register )
- return "Unregistered";
-
- uint32_t _i;
-
- for ( _i = _it; _i--; ) {
- if ( _register[_i]._id == _errno ) {
- return _register[_i]._message;
- }
- }
-
- return "Invalid error id!";
-}
-
-void t_rtperr_print ( const char* _val, ... )
-{
- va_list _args;
- va_start ( _args, _val );
- vfprintf ( stderr, _val, _args );
- va_end ( _args );
-}
diff --git a/toxrtp/toxrtp_error.h b/toxrtp/toxrtp_error.h
deleted file mode 100644
index 0e017246..00000000
--- a/toxrtp/toxrtp_error.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _RTP_ERROR_
-#define _RTP_ERROR_
-
-#define PRINT_FORMAT "Error %d: %s at %s:%d\n"
-#define PRINT_ARGS( _errno ) _errno, t_rtperr(_errno), __FILE__, __LINE__
-
-
-const char* t_rtperr ( int _errno );
-void t_rtperr_register ( int _id, const char* _info );
-
-void t_invoke_error ( int _id );
-void t_rtperr_print ( const char* _val, ... );
-
-
-#ifdef _USE_ERRORS
-#define t_perror( _errno ) t_rtperr_print ( PRINT_FORMAT, PRINT_ARGS ( _errno ) )
-#else
-#define t_perror( _errno )do { } while(0)
-#endif /* _USE_ERRORS */
-
-#ifdef _STDIO_H
-#define t_errexit( _errno ) exit(-_errno)
-#endif /* _STDIO_H */
-
-#endif /* _RTP_ERROR_ */
diff --git a/toxrtp/toxrtp_error_id.h b/toxrtp/toxrtp_error_id.h
deleted file mode 100644
index 201aa936..00000000
--- a/toxrtp/toxrtp_error_id.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _RTP_ERROR_ID_
-#define _RTP_ERROR_ID_
-
-#include "toxrtp_error.h"
-
-typedef enum error_s {
- RTP_ERROR_PACKET_DROPED = 1,
- RTP_ERROR_EMPTY_MESSAGE,
- RTP_ERROR_STD_SEND_FAILURE,
- RTP_ERROR_NO_EXTERNAL_HEADER,
- RTP_ERROR_INVALID_EXTERNAL_HEADER,
- RTP_ERROR_HEADER_PARSING,
- RTP_ERROR_PAYLOAD_NULL,
- RTP_ERROR_PAYLOAD_INVALID,
-
-} error_t;
-
-
-/* Only needed to be called once */
-#ifndef REGISTER_RTP_ERRORS
-#define REGISTER_RTP_ERRORS \
- t_rtperr_register( RTP_ERROR_PACKET_DROPED, "Ivalid sequence number, packet is late" ); \
- t_rtperr_register( RTP_ERROR_EMPTY_MESSAGE, "Tried to send an empty message" ); \
- t_rtperr_register( RTP_ERROR_STD_SEND_FAILURE, "Failed call function: sendto" ); \
- t_rtperr_register( RTP_ERROR_NO_EXTERNAL_HEADER, "While parsing external header" ); \
- t_rtperr_register( RTP_ERROR_INVALID_EXTERNAL_HEADER, "While parsing external header" ); \
- t_rtperr_register( RTP_ERROR_HEADER_PARSING, "While parsing header" ); \
- t_rtperr_register( RTP_ERROR_PAYLOAD_NULL, "Payload is NULL" ); \
- t_rtperr_register( RTP_ERROR_PAYLOAD_INVALID, "Invalid payload size" );
-#endif /* REGISTER_RTP_ERRORS */
-
-#endif /* _RTP_ERROR_ID_ */
diff --git a/toxrtp/toxrtp_helper.c b/toxrtp/toxrtp_helper.c
deleted file mode 100644
index 6f952359..00000000
--- a/toxrtp/toxrtp_helper.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* rtp_helper.c
-*
-* Has some standard functions. !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 .
-*
-*/
-
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include "toxrtp_helper.h"
-#include "../toxcore/network.h"
-
-#include
-
-#ifdef WIN
-#include
-#endif /* WIN */
-
-
-static int _seed = 0; /* Not initiated */
-
-int t_setipport ( const char *_ip, unsigned short _port, void *_dest )
-{
- assert(_dest);
-
- IP_Port *_dest_c = ( IP_Port * ) _dest;
- ip_init(&_dest_c->ip, 0);
-
- IP_Port _ipv6_garbage;
-
- if ( !addr_resolve(_ip, &_dest_c->ip, &_ipv6_garbage.ip) )
- return FAILURE;
-
- _dest_c->port = htons ( _port );
-
- return SUCCESS;
-}
-
-uint32_t t_random ( uint32_t _max )
-{
- if ( !_seed ) {
- srand ( t_time() );
- _seed++;
- }
-
- if ( _max <= 0 ) {
- return ( unsigned ) rand();
- } else {
- return ( unsigned ) rand() % _max;
- }
-}
-
-void t_memcpy ( uint8_t *_dest, const uint8_t *_source, size_t _size )
-{
- /*
- * Using countdown to zero method
- * It's faster than for(_it = 0; _it < _size; _it++);
- */
- size_t _it = _size;
-
- do {
- _it--;
- _dest[_it] = _source[_it];
- } while ( _it );
-
-}
-
-uint8_t *t_memset ( uint8_t *_dest, uint8_t _valu, size_t _size )
-{
- /*
- * Again using countdown to zero method
- */
- size_t _it = _size;
-
- do {
- _it--;
- _dest[_it] = _valu;
- } while ( _it );
-
- return _dest;
-}
-
-size_t t_memlen ( const uint8_t *_valu)
-{
- const uint8_t *_it;
- size_t _retu = 0;
-
- for ( _it = _valu; *_it; ++_it ) ++_retu;
-
- return _retu;
-}
-
-uint8_t *t_strallcpy ( const uint8_t *_source ) /* string alloc and copy */
-{
- assert(_source);
-
- size_t _length = t_memlen(_source) + 1; /* make space for null character */
-
- uint8_t *_dest = calloc( sizeof ( uint8_t ), _length );
- assert(_dest);
-
- t_memcpy(_dest, _source, _length);
-
- return _dest;
-}
-
-size_t t_strfind ( const uint8_t *_str, const uint8_t *_substr )
-{
- size_t _pos = 0;
- size_t _it, _delit = 0;
-
- for ( _it = 0; _str[_it] != '\0'; _it++ ) {
- if ( _str[_it] == _substr[_delit] ) {
- _pos = _it;
-
- while ( _str[_it] == _substr[_delit] && _str[_it] != '\0' ) {
- _it ++;
- _delit++;
-
- if ( _substr[_delit] == '\0' ) {
- return _pos;
- }
- }
-
- _delit = 0;
- _pos = 0;
- }
- }
-
- return _pos;
-}
-
-#ifdef WIN
-#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
-#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
-#else
-#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
-#endif
-
-struct timezone {
- int tz_minuteswest; /* minutes W of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-
-int gettimeofday(struct timeval *tv, struct timezone *tz)
-{
- FILETIME ft;
- unsigned __int64 tmpres = 0;
- static int tzflag;
-
- if (NULL != tv) {
- GetSystemTimeAsFileTime(&ft);
-
- tmpres |= ft.dwHighDateTime;
- tmpres <<= 32;
- tmpres |= ft.dwLowDateTime;
-
- /*converting file time to unix epoch*/
- tmpres -= DELTA_EPOCH_IN_MICROSECS;
- tmpres /= 10; /*convert into microseconds*/
- tv->tv_sec = (long)(tmpres / 1000000UL);
- tv->tv_usec = (long)(tmpres % 1000000UL);
- }
-
- if (NULL != tz) {
- if (!tzflag) {
- _tzset();
- tzflag++;
- }
-
- tz->tz_minuteswest = _timezone / 60;
- tz->tz_dsttime = _daylight;
- }
-
- return 0;
-}
-#endif /* WIN */
-
-
-uint64_t t_time()
-{
- struct timeval _tv;
- gettimeofday(&_tv, NULL);
- uint64_t _retu_usec = _tv.tv_sec % 1000000; /* get 6 digits an leave space for 3 more */
- _retu_usec = _retu_usec * 1000 + (_tv.tv_usec / 1000 );
- return _retu_usec;
-}
diff --git a/toxrtp/toxrtp_helper.h b/toxrtp/toxrtp_helper.h
deleted file mode 100644
index c9bcfcca..00000000
--- a/toxrtp/toxrtp_helper.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* rtp_helper.h
-*
-* Has some standard functions. !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 _RTP__HELPER_H_
-#define _RTP__HELPER_H_
-
-#include
-#include
-
-/* Current time, unix format */
-/*#define _time ((uint32_t)time(NULL))*/
-
-#define SUCCESS 0
-#define FAILURE -1
-
-#define _USE_ERRORS
-
-#define RUN_IN_THREAD(_func, _thread_id, _arg_ptr) \
-if ( pthread_create ( &_thread_id, NULL, _func, _arg_ptr ) ) { \
- pthread_detach ( _thread_id ); \
-}
-
-/* Core adaptation helper */
-int t_setipport ( const char* _ip, unsigned short _port, void* _cont );
-uint32_t t_random ( uint32_t _max );
-
-/* It's a bit faster than the memcpy it self and more optimized for using
- * a uint8_t since memcpy has optimizations when copying "words" i.e. long type.
- * Otherwise it just copies char's while we need only uint8_t
- */
-void t_memcpy ( uint8_t* _dest, const uint8_t* _source, size_t _size );
-
-
-/* This is our memset. It's also a bit faster than the memset for it
- * does not cast _dest to char* and uses faster loop algorithm.
- */
-uint8_t* t_memset ( uint8_t* _dest, uint8_t _valu, size_t _size );
-
-/* Get null terminated len */
-size_t t_memlen ( const uint8_t* _valu );
-
-/* finds location of substring */
-size_t t_strfind ( const uint8_t* _str, const uint8_t* _substr );
-
-/* string alloc and copy ( ! must be null terminated ) */
-uint8_t* t_strallcpy ( const uint8_t* _source );
-
-/* Get current time in milliseconds */
-uint64_t t_time();
-
-
-#endif /* _RTP__HELPER_H_ */
-
-
-
-
diff --git a/toxrtp/toxrtp_message.c b/toxrtp/toxrtp_message.c
deleted file mode 100644
index e7f1f2c0..00000000
--- a/toxrtp/toxrtp_message.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/* rtp_message.c
- *
- * Rtp Message handler. It handles message/header parsing.
- * Refer to RTP: A Transport Protocol for Real-Time Applications ( RFC 3550 ) for more info. !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 .
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#include "toxrtp_message.h"
-#include "toxrtp.h"
-#include
-
-#ifdef _USE_ERRORS
-#include "toxrtp_error_id.h"
-#endif /* _USE_ERRORS */
-
-#include
-
-/* Some defines */
-
-/* End of defines */
-
-void rtp_header_print (const rtp_header_t* _header)
-{
- printf("Header: \n"
- "Version: %d\n"
- "Padding: %d\n"
- "Ext: %d\n"
- "CC: %d\n"
- "marker: %d\n"
- "payload typ:%d\n\n"
- "sequ num: %d\n"
- "Timestamp: %d\n"
- "SSrc: %d\n"
- "CSrc: %d\n"
- "Lenght: %d\n"
- ,rtp_header_get_flag_version(_header)
- ,rtp_header_get_flag_padding(_header)
- ,rtp_header_get_flag_extension(_header)
- ,rtp_header_get_flag_CSRC_count(_header)
- ,rtp_header_get_setting_marker(_header)
- ,rtp_header_get_setting_payload_type(_header)
- ,_header->_sequence_number
- ,_header->_timestamp
- ,_header->_ssrc
- ,_header->_csrc[0]
- ,_header->_length
- );
-}
-
-rtp_header_t* rtp_extract_header ( const uint8_t* _payload, size_t _bytes )
-{
- if ( !_payload ) {
- t_perror ( RTP_ERROR_PAYLOAD_NULL );
- return NULL;
- }
- const uint8_t* _it = _payload;
-
- rtp_header_t* _retu = calloc(sizeof(rtp_header_t), 1);
- assert(_retu);
-
- _retu->_flags = *_it; ++_it;
-
- /* This indicates if the first 2 bytes are valid.
- * Now it my happen that this is out of order but
- * it cuts down chances of parsing some invalid value
- */
- if ( rtp_header_get_flag_version(_retu) != RTP_VERSION ){
- printf("Invalid version: %d\n", rtp_header_get_flag_version(_retu));
- //assert(rtp_header_get_flag_version(_retu) == RTP_VERSION);
- /* Deallocate */
- //DEALLOCATOR(_retu);
- //return NULL;
- }
-
- /*
- * Added a check for the size of the header little sooner so
- * I don't need to parse the other stuff if it's bad
- */
- uint8_t cc = rtp_header_get_flag_CSRC_count ( _retu );
- uint32_t _lenght = _MIN_HEADER_LENGTH + ( cc * 4 );
-
- if ( _bytes < _lenght ) {
- t_perror ( RTP_ERROR_PAYLOAD_INVALID );
- return NULL;
- }
-
- if ( cc > 0 ) {
- _retu->_csrc = calloc ( sizeof ( uint32_t ), cc );
- assert(_retu->_csrc);
-
- } else { /* But this should not happen ever */
- t_perror ( RTP_ERROR_HEADER_PARSING );
- return NULL;
- }
-
-
- _retu->_marker_payload_t = *_it; ++_it;
- _retu->_length = _lenght;
- _retu->_sequence_number = ( ( uint16_t ) * _it << 8 ) | * ( _it + 1 );
-
- _it += 2;
-
- _retu->_timestamp = ( ( uint32_t ) * _it << 24 ) |
- ( ( uint32_t ) * ( _it + 1 ) << 16 ) |
- ( ( uint32_t ) * ( _it + 2 ) << 8 ) |
- ( * ( _it + 3 ) ) ;
-
- _it += 4;
-
- _retu->_ssrc = ( ( uint32_t ) * _it << 24 ) |
- ( ( uint32_t ) * ( _it + 1 ) << 16 ) |
- ( ( uint32_t ) * ( _it + 2 ) << 8 ) |
- ( ( uint32_t ) * ( _it + 3 ) ) ;
-
-
- size_t x;
- for ( x = 0; x < cc; x++ ) {
- _it += 4;
- _retu->_csrc[x] = ( ( uint32_t ) * _it << 24 ) |
- ( ( uint32_t ) * ( _it + 1 ) << 16 ) |
- ( ( uint32_t ) * ( _it + 2 ) << 8 ) |
- ( ( uint32_t ) * ( _it + 3 ) ) ;
- }
-
- return _retu;
-}
-
-rtp_ext_header_t* rtp_extract_ext_header ( const uint8_t* _payload, size_t _bytes )
-{
- if ( !_payload ) {
- t_perror ( RTP_ERROR_PAYLOAD_NULL );
- return NULL;
- }
-
-
-
- const uint8_t* _it = _payload;
-
- rtp_ext_header_t* _retu = calloc(sizeof(rtp_ext_header_t), 1);
- assert(_retu);
-
- uint16_t _ext_len = ( ( uint16_t ) * _it << 8 ) | * ( _it + 1 ); _it += 2;
-
- if ( _bytes < ( _ext_len * sizeof(uint32_t) ) ) {
- t_perror ( RTP_ERROR_PAYLOAD_INVALID );
- return NULL;
- }
-
- _retu->_ext_len = _ext_len;
- _retu->_ext_type = ( ( uint16_t ) * _it << 8 ) | * ( _it + 1 ); _it -= 2;
-
- _retu->_hd_ext = calloc(sizeof(uint32_t), _ext_len);
- assert(_retu->_hd_ext);
-
- uint32_t* _hd_ext = _retu->_hd_ext;
- size_t i;
- for ( i = 0; i < _ext_len; i++ ) {
- _it += 4;
- _hd_ext[i] = ( ( uint32_t ) * _it << 24 ) |
- ( ( uint32_t ) * ( _it + 1 ) << 16 ) |
- ( ( uint32_t ) * ( _it + 2 ) << 8 ) |
- ( ( uint32_t ) * ( _it + 3 ) ) ;
- }
-
- return _retu;
-}
-
-uint8_t* rtp_add_header ( rtp_header_t* _header, uint8_t* _payload )
-{
- uint8_t cc = rtp_header_get_flag_CSRC_count ( _header );
-
- uint8_t* _it = _payload;
-
- *_it = _header->_flags; ++_it;
- *_it = _header->_marker_payload_t; ++_it;
-
- *_it = ( _header->_sequence_number >> 8 ); ++_it;
- *_it = ( _header->_sequence_number ); ++_it;
-
- uint32_t _timestamp = _header->_timestamp;
- *_it = ( _timestamp >> 24 ); ++_it;
- *_it = ( _timestamp >> 16 ); ++_it;
- *_it = ( _timestamp >> 8 ); ++_it;
- *_it = ( _timestamp ); ++_it;
-
- uint32_t _ssrc = _header->_ssrc;
- *_it = ( _ssrc >> 24 ); ++_it;
- *_it = ( _ssrc >> 16 ); ++_it;
- *_it = ( _ssrc >> 8 ); ++_it;
- *_it = ( _ssrc );
-
- uint32_t *_csrc = _header->_csrc;
- size_t x;
- for ( x = 0; x < cc; x++ ) {
- ++_it;
- *_it = ( _csrc[x] >> 24 ); ++_it;
- *_it = ( _csrc[x] >> 16 ); ++_it;
- *_it = ( _csrc[x] >> 8 ); ++_it;
- *_it = ( _csrc[x] );
- }
-
- return _it;
-}
-
-uint8_t* rtp_add_extention_header ( rtp_ext_header_t* _header, uint8_t* _payload )
-{
- uint8_t* _it = _payload;
-
- *_it = ( _header->_ext_len >> 8 ); _it++;
- *_it = ( _header->_ext_len ); _it++;
-
- *_it = ( _header->_ext_type >> 8 ); ++_it;
- *_it = ( _header->_ext_type );
-
- size_t x;
-
- uint32_t* _hd_ext = _header->_hd_ext;
- for ( x = 0; x < _header->_ext_len; x++ ) {
- ++_it;
- *_it = ( _hd_ext[x] >> 24 ); ++_it;
- *_it = ( _hd_ext[x] >> 16 ); ++_it;
- *_it = ( _hd_ext[x] >> 8 ); ++_it;
- *_it = ( _hd_ext[x] );
- }
-
- return _it;
-}
-
-size_t rtp_header_get_size ( const rtp_header_t* _header )
-{
- return ( 8 + ( rtp_header_get_flag_CSRC_count ( _header ) * 4 ) );
-}
-/* Setting flags */
-
-void rtp_header_add_flag_version ( rtp_header_t* _header, uint32_t value )
-{
- ( _header->_flags ) &= 0x3F;
- ( _header->_flags ) |= ( ( ( value ) << 6 ) & 0xC0 );
-}
-
-void rtp_header_add_flag_padding ( rtp_header_t* _header, uint32_t value )
-{
- if ( value > 0 ) {
- value = 1; /* It can only be 1 */
- }
-
- ( _header->_flags ) &= 0xDF;
- ( _header->_flags ) |= ( ( ( value ) << 5 ) & 0x20 );
-}
-
-void rtp_header_add_flag_extension ( rtp_header_t* _header, uint32_t value )
-{
- if ( value > 0 ) {
- value = 1; /* It can only be 1 */
- }
-
- ( _header->_flags ) &= 0xEF;
- ( _header->_flags ) |= ( ( ( value ) << 4 ) & 0x10 );
-}
-
-void rtp_header_add_flag_CSRC_count ( rtp_header_t* _header, uint32_t value )
-{
- ( _header->_flags ) &= 0xF0;
- ( _header->_flags ) |= ( ( value ) & 0x0F );
-}
-
-void rtp_header_add_setting_marker ( rtp_header_t* _header, uint32_t value )
-{
- if ( value > 1 )
- value = 1;
-
- ( _header->_marker_payload_t ) &= 0x7F;
- ( _header->_marker_payload_t ) |= ( ( ( value ) << 7 ) /*& 0x80 */ );
-}
-
-void rtp_header_add_setting_payload ( rtp_header_t* _header, uint32_t value )
-{
- if ( value > 127 )
- value = 127; /* Well set to maximum */
-
- ( _header->_marker_payload_t ) &= 0x80;
- ( _header->_marker_payload_t ) |= ( ( value ) /* & 0x7F */ );
-}
-
-/* Getting values from flags */
-uint8_t rtp_header_get_flag_version ( const rtp_header_t* _header )
-{
- return ( _header->_flags & 0xd0 ) >> 6;
-}
-
-uint8_t rtp_header_get_flag_padding ( const rtp_header_t* _header )
-{
- return ( _header->_flags & 0x20 ) >> 5;
-}
-
-uint8_t rtp_header_get_flag_extension ( const rtp_header_t* _header )
-{
- return ( _header->_flags & 0x10 ) >> 4;
-}
-
-uint8_t rtp_header_get_flag_CSRC_count ( const rtp_header_t* _header )
-{
- return ( _header->_flags & 0x0f );
-}
-uint8_t rtp_header_get_setting_marker ( const rtp_header_t* _header )
-{
- return ( _header->_marker_payload_t ) >> 7;
-}
-uint8_t rtp_header_get_setting_payload_type ( const rtp_header_t* _header )
-{
- /*
- uint8_t _retu;
-
- if ( _header->_marker_payload_t >> 7 == 1 ) {
- _header->_marker_payload_t ^= 0x80;
- _retu = _header->_marker_payload_t;
- _header->_marker_payload_t ^= 0x80;
- } else {
- _retu = _header->_marker_payload_t;
- }
- */
- /* return to start value
- return _retu; */
- return _header->_marker_payload_t & 0x7f;
-}
-
-/* */
-
-
diff --git a/toxrtp/toxrtp_message.h b/toxrtp/toxrtp_message.h
deleted file mode 100644
index 8feea5d9..00000000
--- a/toxrtp/toxrtp_message.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* rtp_message.h
- *
- * Rtp Message handler. It handles message/header parsing.
- * Refer to RTP: A Transport Protocol for Real-Time Applications ( RFC 3550 ) for more info. !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 _RTP__MESSAGE_H_
-#define _RTP__MESSAGE_H_
-
-#include "../toxcore/network.h"
-#include "toxrtp_helper.h"
-#include "../toxcore/tox.h"
-/* Defines */
-
-#define _MAX_SEQU_NUM 65535
-
-/* Minimum size */
-#define _MIN_HEADER_LENGTH 12
-#define _MIN_EXT_HEADER_LENGTH 4
-
-/* End of defines */
-
-
-typedef struct rtp_dest_list_s {
- tox_IP_Port _dest;
- struct rtp_dest_list_s* next;
-
-} rtp_dest_list_t;
-
-typedef struct rtp_header_s {
- uint8_t _flags; /* Version(2),Padding(1), Ext(1), Cc(4) */
- uint8_t _marker_payload_t; /* Marker(1), PlayLoad Type(7) */
- uint16_t _sequence_number; /* Sequence Number */
- uint32_t _timestamp; /* Timestamp */
- uint32_t _ssrc; /* SSRC */
- uint32_t* _csrc; /* CSRC's table */
-
- uint32_t _length; /* A little something for allocation */
-
-} rtp_header_t;
-
-typedef struct rtp_ext_header_s {
- uint16_t _ext_type; /* Extension profile */
- uint16_t _ext_len; /* Number of extensions */
- uint32_t* _hd_ext; /* Extension's table */
-
-
-} rtp_ext_header_t;
-
-typedef struct rtp_msg_s {
- struct rtp_header_s* _header;
- struct rtp_ext_header_s* _ext_header;
- uint32_t _header_lenght;
-
- uint8_t* _data;
- uint32_t _length;
- tox_IP_Port _from;
-
- struct rtp_msg_s* _next;
-} rtp_msg_t;
-
-/* Extracts the header from the payload starting at _from */
-rtp_header_t* rtp_extract_header ( const uint8_t* _payload, size_t _bytes );
-rtp_ext_header_t* rtp_extract_ext_header ( const uint8_t* _payload, size_t _bytes );
-
-
-uint8_t* rtp_add_header ( rtp_header_t* _header, uint8_t* _payload );
-uint8_t* rtp_add_extention_header ( rtp_ext_header_t* _header, uint8_t* _payload );
-
-/* Gets the size of the header _header in bytes */
-size_t rtp_header_get_size ( const rtp_header_t* _header );
-
-void rtp_header_print (const rtp_header_t* _header);
-
-/* Adding flags and settings */
-void rtp_header_add_flag_version ( rtp_header_t* _header, uint32_t value );
-void rtp_header_add_flag_padding ( rtp_header_t* _header, uint32_t value );
-void rtp_header_add_flag_extension ( rtp_header_t* _header, uint32_t value );
-void rtp_header_add_flag_CSRC_count ( rtp_header_t* _header, uint32_t value );
-void rtp_header_add_setting_marker ( rtp_header_t* _header, uint32_t value );
-void rtp_header_add_setting_payload ( rtp_header_t* _header, uint32_t value );
-
-
-/* Getting values from flags and settings */
-uint8_t rtp_header_get_flag_version ( const rtp_header_t* _header );
-uint8_t rtp_header_get_flag_padding ( const rtp_header_t* _header );
-uint8_t rtp_header_get_flag_extension ( const rtp_header_t* _header );
-uint8_t rtp_header_get_flag_CSRC_count ( const rtp_header_t* _header );
-uint8_t rtp_header_get_setting_marker ( const rtp_header_t* _header );
-uint8_t rtp_header_get_setting_payload_type ( const rtp_header_t* _header );
-
-#endif /* _RTP__MESSAGE_H_ */