From da727875ac954b13ecb16521d255499511bb7424 Mon Sep 17 00:00:00 2001 From: mannol Date: Sun, 13 Oct 2013 16:16:47 +0200 Subject: tox A/V: RTP/MSI implementation --- toxrtp/tests/Makefile.inc | 1 + toxrtp/tests/test_bidirect.c | 109 +++++++++++++++ toxrtp/tests/test_headers.c | 316 +++++++++++++++++++++++++++++++++++++++++++ toxrtp/tests/test_helper.c | 83 ++++++++++++ toxrtp/tests/test_helper.h | 61 +++++++++ 5 files changed, 570 insertions(+) create mode 100644 toxrtp/tests/Makefile.inc create mode 100644 toxrtp/tests/test_bidirect.c create mode 100644 toxrtp/tests/test_headers.c create mode 100644 toxrtp/tests/test_helper.c create mode 100644 toxrtp/tests/test_helper.h (limited to 'toxrtp/tests') diff --git a/toxrtp/tests/Makefile.inc b/toxrtp/tests/Makefile.inc new file mode 100644 index 00000000..8d1c8b69 --- /dev/null +++ b/toxrtp/tests/Makefile.inc @@ -0,0 +1 @@ + diff --git a/toxrtp/tests/test_bidirect.c b/toxrtp/tests/test_bidirect.c new file mode 100644 index 00000000..b5a0899e --- /dev/null +++ b/toxrtp/tests/test_bidirect.c @@ -0,0 +1,109 @@ +#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 new file mode 100644 index 00000000..be3f1375 --- /dev/null +++ b/toxrtp/tests/test_headers.c @@ -0,0 +1,316 @@ +/* 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 new file mode 100644 index 00000000..526b6b38 --- /dev/null +++ b/toxrtp/tests/test_helper.c @@ -0,0 +1,83 @@ +/* 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 new file mode 100644 index 00000000..de654743 --- /dev/null +++ b/toxrtp/tests/test_helper.h @@ -0,0 +1,61 @@ +/* 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_ */ + + -- cgit v1.2.3