diff --git a/Makefile.am b/Makefile.am
index d8952086b8ccc47e0e8ef87013cb4395fee69b17..9185c6936712106a77cc9699d54360e1f829ce73 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,7 +6,7 @@ SOURCES=
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = src ringtones man $(TESTS_DIR) doc bin
+SUBDIRS = src ringtones man $(TESTS_DIR) doc bin test
EXTRA_DIST = m4/libtool.m4 \
m4/lt~obsolete.m4 \
diff --git a/configure.ac b/configure.ac
index 70e6de1e4c44b78da973344891cffec46391d36b..582b4e339112eb5b4947bf5ac0634b9755199ef9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -699,6 +699,7 @@ AS_IF([test "x$enable_debug" = "xyes"],
dnl What Makefiles to generate
+
#TODO: split this list across where the relevant check is performed
AC_CONFIG_FILES([Makefile \
bin/Makefile \
@@ -725,10 +726,11 @@ AC_CONFIG_FILES([Makefile \
src/media/video/androidvideo/Makefile \
src/media/video/osxvideo/Makefile \
src/media/video/winvideo/Makefile \
- src/media/video/test/Makefile \
src/security/Makefile \
src/upnp/Makefile \
ringtones/Makefile \
+ test/Makefile\
+ test/sip/Makefile \
man/Makefile \
doc/Makefile \
doc/doxygen/Makefile])
diff --git a/src/media/video/Makefile.am b/src/media/video/Makefile.am
index 5aa6de09319c72ff2bf78f245a79dbd65a4f5820..9d5afe657adcf4ee9de640599066a46ca48b7977 100644
--- a/src/media/video/Makefile.am
+++ b/src/media/video/Makefile.am
@@ -1,24 +1,22 @@
include $(top_srcdir)/globals.mk
-SUBDIRS= test
-
if HAVE_LINUX
if HAVE_ANDROID
-SUBDIRS+= \
+SUBDIRS= \
androidvideo
else
-SUBDIRS+= \
+SUBDIRS= \
v4l2
endif
endif
if HAVE_OSX
-SUBDIRS+= \
+SUBDIRS= \
osxvideo
endif
if HAVE_WIN32
-SUBDIRS+= \
+SUBDIRS= \
winvideo
endif
diff --git a/src/media/video/test/.gitignore b/src/media/video/test/.gitignore
deleted file mode 100644
index 90574ca50ae0adbb1fdc438057fe25f295ab909c..0000000000000000000000000000000000000000
--- a/src/media/video/test/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-test_thread
-test_v4l2
-test_video_endpoint
-test_video_rtp
-test_video_preview
diff --git a/src/media/video/test/Makefile.am b/src/media/video/test/Makefile.am
deleted file mode 100644
index f4f44aa903a207c9f9d17845d05f195ee7ff065f..0000000000000000000000000000000000000000
--- a/src/media/video/test/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-include $(top_srcdir)/globals.mk
-
-TESTS=test_shm test_video_input test_video_rtp
-check_PROGRAMS=test_video_rtp test_video_input test_shm
-
-test_video_rtp_SOURCES=test_video_rtp.cpp
-test_video_rtp_LDADD=$(top_builddir)/src/libring.la $(top_builddir)/src/media/video/libvideo.la $(YAML_LIBS)
-
-test_video_input_SOURCES=test_video_input.cpp test_video_input.h
-test_video_input_LDADD=$(top_builddir)/src/libring.la $(top_builddir)/src/media/video/libvideo.la $(YAML_LIBS)
-
-if HAVE_LINUX
-test_shm_SOURCES=test_shm.cpp shm_src.cpp shm_src.h
-test_shm_LDADD=$(top_builddir)/src/libring.la $(top_builddir)/src/media/video/libvideo.la $(YAML_LIBS) -lrt
-test_shm_CXXFLAGS=$(AM_CXXFLAGS)
-endif
-
-AM_CXXFLAGS=-I$(top_srcdir)/src/media/video -I$(top_srcdir)/src
diff --git a/src/media/video/test/README b/src/media/video/test/README
deleted file mode 100644
index 9ef0c4f1e81db2960330be48b5138435024a50d5..0000000000000000000000000000000000000000
--- a/src/media/video/test/README
+++ /dev/null
@@ -1 +0,0 @@
-c++ shm_src.cpp shmclient.cpp -o shmclient `pkg-config --cflags --libs clutter-1.0` -lrt -pthread -O2
diff --git a/src/media/video/test/make_rtp_stream.sh b/src/media/video/test/make_rtp_stream.sh
deleted file mode 100755
index dfb4759b5bde85a8fce02915beb7642754a51eb8..0000000000000000000000000000000000000000
--- a/src/media/video/test/make_rtp_stream.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-# disables audio
-ffmpeg -f video4linux2 -i /dev/video0 -srcw 320 -srch 240 -an -r 30 -vprofile baseline -level 13 -vb 400000 -vcodec libx264 -payload_type 109 -preset veryfast -tune zerolatency -f rtp rtp://192.168.50.116:2228
diff --git a/src/media/video/test/shm_src.cpp b/src/media/video/test/shm_src.cpp
deleted file mode 100644
index 0a55efef78cd8f7cccff59acf44d1847924de25f..0000000000000000000000000000000000000000
--- a/src/media/video/test/shm_src.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2012-2017 Savoir-faire Linux Inc.
- *
- * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
- *
- * Portions derived from GStreamer:
- * Copyright (C) <2009> Collabora Ltd
- * @author: Olivier Crete <olivier.crete@collabora.co.uk
- * Copyright (C) <2009> Nokia Inc
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "shm_src.h"
-#include "../shm_header.h"
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <cstdio>
-#include <iostream>
-#include <unistd.h>
-#include <cerrno>
-#include <cstring>
-#include <cassert>
-
-SHMSrc::SHMSrc(const std::string &shm_name) :
- shm_name_(shm_name),
- fd_(-1),
- shm_area_(static_cast<SHMHeader*>(MAP_FAILED)),
- shm_area_len_(0),
- buffer_gen_(0)
- {}
-
-bool
-SHMSrc::start()
-{
- if (fd_ != -1) {
- std::cerr << "fd must be -1" << std::endl;
- return false;
- }
-
- fd_ = shm_open(shm_name_.c_str(), O_RDWR, 0);
- if (fd_ < 0) {
- std::cerr << "could not open shm area \"" << shm_name_ << "\", shm_open failed" << std::endl;
- perror(strerror(errno));
- return false;
- }
- shm_area_len_ = sizeof(SHMHeader);
-
- shm_area_ = static_cast<SHMHeader*>(mmap(NULL, shm_area_len_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
-
- if (shm_area_ == MAP_FAILED) {
- std::cerr << "Could not map shm area, mmap failed" << std::endl;
- return false;
- }
-
- return true;
-}
-
-bool
-SHMSrc::stop()
-{
- if (fd_ >= 0)
- close(fd_);
- fd_ = -1;
-
- if (shm_area_ != MAP_FAILED)
- munmap(shm_area_, shm_area_len_);
- shm_area_len_ = 0;
- shm_area_ = static_cast<SHMHeader*>(MAP_FAILED);
-
- return true;
-}
-
-bool
-SHMSrc::resize_area()
-{
- while ((sizeof(SHMHeader) + shm_area_->buffer_size) > shm_area_len_) {
- size_t new_size = sizeof(SHMHeader) + shm_area_->buffer_size;
-
- shm_unlock();
- if (munmap(shm_area_, shm_area_len_)) {
- std::cerr << "Could not unmap shared area" << std::endl;
- perror(strerror(errno));
- return false;
- }
-
- shm_area_ = static_cast<SHMHeader*>(mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
- shm_area_len_ = new_size;
-
- if (!shm_area_) {
- shm_area_ = 0;
- std::cerr << "Could not remap shared area" << std::endl;
- return false;
- }
-
- shm_area_len_ = new_size;
- shm_lock();
- }
- return true;
-}
-
-void SHMSrc::render(char *dest, size_t len)
-{
- shm_lock();
-
- while (buffer_gen_ == shm_area_->buffer_gen) {
- shm_unlock();
- std::cerr << "Waiting for next buffer" << std::endl;;
- sem_wait(&shm_area_->notification);
-
- shm_lock();
- }
-
- if (!resize_area())
- return;
-
- std::cerr << "Reading from buffer!" << std::endl;
- memcpy(dest, shm_area_->data, len);
- buffer_gen_ = shm_area_->buffer_gen;
- shm_unlock();
-}
-
-void SHMSrc::shm_lock()
-{
- sem_wait(&shm_area_->mutex);
-}
-
-void SHMSrc::shm_unlock()
-{
- sem_post(&shm_area_->mutex);
-}
diff --git a/src/media/video/test/shm_src.h b/src/media/video/test/shm_src.h
deleted file mode 100644
index f66f04c6e6fae405f575e507cfb0ad27c36f2834..0000000000000000000000000000000000000000
--- a/src/media/video/test/shm_src.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012-2017 Savoir-faire Linux Inc.
- *
- * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
- *
- * Portions derived from GStreamer:
- * Copyright (C) <2009> Collabora Ltd
- * @author: Olivier Crete <olivier.crete@collabora.co.uk
- * Copyright (C) <2009> Nokia Inc
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef SHM_SRC_H_
-#define SHM_SRC_H_
-
-#include <string>
-#include "../../noncopyable.h"
-
-class SHMHeader;
-// Example Shared memory source, only useful for testing
-// as far as the daemon is concerned
-
-class SHMSrc {
- public:
- SHMSrc(const std::string &shm_name);
- virtual ~SHMSrc() {};
-
- bool start();
- bool stop();
-
- bool resize_area();
-
- void render(char *data, size_t len);
-
- protected:
- void shm_lock();
- void shm_unlock();
- std::string shm_name_;
- int fd_;
- SHMHeader *shm_area_;
- size_t shm_area_len_;
- unsigned buffer_gen_;
-
- private:
- NON_COPYABLE(SHMSrc);
-};
-
-#endif // SHM_SRC_H_
diff --git a/src/media/video/test/shmclient.cpp b/src/media/video/test/shmclient.cpp
deleted file mode 100644
index a5a77a7e76a48f789513df66c9899f62cb9dfedd..0000000000000000000000000000000000000000
--- a/src/media/video/test/shmclient.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2011-2017 Savoir-faire Linux Inc.
- *
- * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <cstdio>
-#include <cstdlib>
-#include "shm_src.h"
-#include "../shm_header.h"
-#include "../../noncopyable.h"
-#include <sys/mman.h>
-#include <iostream>
-#include <clutter/clutter.h>
-
-class ClutterSHMSrc : public SHMSrc {
- public:
- ClutterSHMSrc(const std::string &name,
- unsigned width,
- unsigned height,
- ClutterActor *texture) :
- SHMSrc(name),
- width_(width),
- height_(height),
- texture_(texture)
- {
- printf("Creating source with name:%s width:%d height:%d texture:%p\n", name.c_str(), width, height, texture);
- }
-
- void render_to_texture()
- {
- if (shm_area_ == MAP_FAILED) {
- g_print("shm_area is MAP FAILED!\n");
- return;
- }
-
- shm_lock();
-
- while (buffer_gen_ == shm_area_->buffer_gen) {
- shm_unlock();
- sem_wait(&shm_area_->notification);
-
- shm_lock();
- }
-
- if (!resize_area()) {
- g_print("could not resize area\n");
- return;
- }
-
- clutter_actor_set_size(texture_, width_, height_);
- const int BPP = 4;
- const int ROW_STRIDE = BPP * width_;
- /* update the clutter texture */
- clutter_texture_set_from_rgb_data(CLUTTER_TEXTURE(texture_),
- reinterpret_cast<const unsigned char *>(shm_area_->data),
- TRUE,
- width_,
- height_,
- ROW_STRIDE,
- BPP,
- CLUTTER_TEXTURE_RGB_FLAG_BGR,
- NULL);
- buffer_gen_ = shm_area_->buffer_gen;
- shm_unlock();
- }
-
- private:
- NON_COPYABLE(ClutterSHMSrc);
- unsigned width_;
- unsigned height_;
- ClutterActor *texture_;
-};
-
-gboolean updateTexture(gpointer data)
-{
- ClutterSHMSrc *src = static_cast<ClutterSHMSrc *>(data);
- src->render_to_texture();
- return TRUE;
-}
-
-int main(int argc, char *argv[])
-{
- if (argc < 4) {
- printf("Usage: ./shmclient <shm_filename> <width> <height>\n");
- return 1;
- }
-
- /* Initialize Clutter */
- if (clutter_init(NULL, NULL) != CLUTTER_INIT_SUCCESS)
- return 1;
-
- /* Get the default stage */
- ClutterActor *stage = clutter_stage_get_default();
-
- const int width = atoi(argv[2]);
- const int height = atoi(argv[3]);
-
- clutter_actor_set_size(stage, width, height);
-
- ClutterActor *texture = clutter_texture_new();
-
- clutter_stage_set_title(CLUTTER_STAGE(stage), "Client");
- /* Add ClutterTexture to the stage */
- clutter_container_add(CLUTTER_CONTAINER(stage), texture, NULL);
-
- ClutterSHMSrc src(argv[1], width, height, texture);
- if (not src.start()) {
- printf("Could not start SHM source\n");
- return 1;
- }
- /* frames are read and saved here */
- g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, 30, updateTexture, &src, NULL);
-
- clutter_actor_show_all(stage);
-
- /* main loop */
- clutter_main();
- src.stop();
-
- return 0;
-}
diff --git a/src/media/video/test/test_shm.cpp b/src/media/video/test/test_shm.cpp
deleted file mode 100644
index 02df602dca2dedfcad567f164ec36a0cc34b6355..0000000000000000000000000000000000000000
--- a/src/media/video/test/test_shm.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2012-2017 Savoir-faire Linux Inc.
- *
- * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "shm_sink.h"
-#include "shm_src.h"
-#include <thread>
-#include <signal.h>
-#include <iostream>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <atomic>
-#include <cstring>
-#include <cassert>
-
-static std::atomic<bool> done(false);
-
-static void
-signal_handler(int /*sig*/)
-{
- done = true;
-}
-
-static const char test_data[] = "abcdefghijklmnopqrstuvwxyz";
-
-static void
-sink_thread()
-{
- ring::video::SHMSink sink("bob");;
- if (!sink.start())
- return;
- std::vector<unsigned char> test_vec(test_data, test_data + sizeof(test_data) / sizeof(test_data[0]));
-
- while (!done) {
- sink.render(test_vec);
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- }
- sink.stop();
- std::cerr << std::endl;
- std::cerr << "Exitting sink thread" << std::endl;
-}
-
-static void
-run_client()
-{
- SHMSrc src("bob");;
- bool started = false;
- while (not done and not started) {
- sleep(1);
- if (src.start())
- started = true;
- }
- // we get here if the above loop was interupted by our signal handler
- if (!started)
- return;
-
- // initialize destination string to 0's
- std::vector<char> dest(sizeof(test_data), 0);
- const std::vector<char> test_data_str(test_data, test_data + sizeof(test_data));
- assert(test_data_str.size() == 27);
- assert(dest.size() == test_data_str.size());
- while (not done and dest != test_data_str) {
- src.render(dest.data(), dest.size());
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- }
- src.stop();
- std::cerr << "Got characters, exitting client process" << std::endl;
-}
-
-static void
-run_daemon()
-{
- std::thread bob(sink_thread);
- /* Wait for child process. */
- int status;
- int pid;
- if ((pid = wait(&status)) == -1) {
- perror("wait error");
- } else {
- // Check status.
- if (WIFSIGNALED(status) != 0)
- std::cout << "Child process ended because of signal " <<
- WTERMSIG(status) << std::endl;
- else if (WIFEXITED(status) != 0)
- std::cout << "Child process ended normally; status = " <<
- WEXITSTATUS(status) << std::endl;
- else
- std::cout << "Child process did not end normally" << std::endl;
- }
- std::cout << "Finished waiting for child" << std::endl;
- done = true;
- // wait for thread
- bob.join();
-}
-int main()
-{
- signal(SIGINT, signal_handler);
- pid_t pid = fork();
- if (pid < 0) {
- std::cerr << "Failed to fork" << std::endl;
- return 1;
- } else if (pid == 0) {
- // child code only
- run_client();
- } else {
- // parent code only
- run_daemon();
- }
- return 0;
-}
diff --git a/src/media/video/test/test_video_input.cpp b/src/media/video/test/test_video_input.cpp
deleted file mode 100644
index 8bceabba88de286bbf85cd9587feff987c4ce59a..0000000000000000000000000000000000000000
--- a/src/media/video/test/test_video_input.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011-2017 Savoir-faire Linux Inc.
- *
- * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "test_video_input.h"
-#include "video_input.h"
-#include "media_const.h"
-#include <map>
-#include <string>
-
-namespace ring { namespace video { namespace test {
-
-void VideoInputTest::testInput()
-{
- static const std::string sep = DRing::Media::VideoProtocolPrefix::SEPARATOR;
- std::string resource = DRing::Media::VideoProtocolPrefix::DISPLAY + sep + std::string(getenv("DISPLAY") ? : ":0.0");
- VideoInput video;
- video.switchInput(resource);
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
-}
-
-}}} // namespace ring::video::test
-
-int main ()
-{
- for (int i = 0; i < 20; ++i) {
- ring::video::test::VideoInputTest test;
- test.testInput();
- }
- return 0;
-}
diff --git a/src/media/video/test/test_video_input.h b/src/media/video/test/test_video_input.h
deleted file mode 100644
index aeeb2acd3cd4cf1e9ca9b4abcf993e85cad28d75..0000000000000000000000000000000000000000
--- a/src/media/video/test/test_video_input.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2011-2017 Savoir-faire Linux Inc.
- *
- * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef _VIDEO_INPUT_TEST_
-#define _VIDEO_INPUT_TEST_
-
-namespace ring { namespace video { namespace test {
-
-class VideoInputTest {
-public:
- void testInput();
-};
-
-}}} // namespace ring::video::test
-
-#endif // _VIDEO_INPUT_TEST_
diff --git a/src/media/video/test/test_video_rtp.cpp b/src/media/video/test/test_video_rtp.cpp
deleted file mode 100644
index 530aa5dbfc0ec282e4870eea9c8472c2d0fbbc18..0000000000000000000000000000000000000000
--- a/src/media/video/test/test_video_rtp.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2011-2017 Savoir-faire Linux Inc.
- *
- * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "video_rtp_session.h"
-#include "video_device_monitor.h"
-
-#include "ip_utils.h"
-
-#include <unistd.h> // for sleep
-
-int main ()
-{
- ring::video::VideoDeviceMonitor monitor;
- ring::video::VideoRtpSession session("test", monitor.getDeviceParams(monitor.getDefaultDevice()));
-
- ring::MediaDescription local {};
- local.addr = {AF_INET};
- local.addr.setPort(12345);
- session.updateMedia(local, ring::MediaDescription{});
-
- session.start();
- sleep(5);
- session.stop();
-
- return 0;
-}
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..7e563b8b3023b7b9cc879c0052dfcc26b9f82505
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,2 @@
+*.log
+*.trs
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..10991115e819f782edc973c3ebfd12e7ce5c71d9
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=sip
diff --git a/test/sip/.gitignore b/test/sip/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d0cf867da6b545ec0e6dcd9e9b781952efdb4c16
--- /dev/null
+++ b/test/sip/.gitignore
@@ -0,0 +1,8 @@
+*.o
+
+# test result files
+*.log
+*.trs
+
+#test binaries
+sip
diff --git a/test/sip/Makefile.am b/test/sip/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..01bc4887e0bf5bce6971530579035f1bbdacd263
--- /dev/null
+++ b/test/sip/Makefile.am
@@ -0,0 +1,8 @@
+# Rules for the test code (use `make check` to execute)
+include ../../globals.mk
+TESTS = sip
+check_PROGRAMS = $(TESTS)
+sip_LDADD = ./../../src/libring.la
+sip_SOURCES = sip.cpp test_SIP.h test_SIP.cpp ../../manager.h
+sip_CXXFLAGS = $(CPPUNIT_CFLAGS)
+sip_LDFLAGS = $(CPPUNIT_LIBS) -ldl
diff --git a/test/sip/sip.cpp b/test/sip/sip.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b89abb26163944c580a0b71370937cc8ee15ea9d
--- /dev/null
+++ b/test/sip/sip.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
+ * Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Additional permission under GNU GPL version 3 section 7:
+ *
+ * If you modify this program, or any covered work, by linking or
+ * combining it with the OpenSSL project's OpenSSL library (or a
+ * modified version of that library), containing parts covered by the
+ * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ * grants you additional permission to convey the resulting work.
+ * Corresponding Source for a non-source form of such a combination
+ * shall include the source code for the parts of OpenSSL used as well
+ * as that of the covered work.
+ */
+#include "test_SIP.h"
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/XmlOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TextTestRunner.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+int main(int argc, char* argv[])
+{
+
+ // Get the top level suite from the registry
+ CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+ // Adds the test to the list of test to run
+ CppUnit::TextUi::TestRunner runner;
+ runner.addTest( suite );
+
+ // Change the default outputter to a compiler error format outputter
+ runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
+ std::cerr ) );
+ // Run the tests.
+ bool wasSucessful = runner.run();
+
+ // Return error code 1 if the one of test failed.
+ return wasSucessful ? 0 : 1;
+}
diff --git a/test/sip/sippxml/test_1.xml b/test/sip/sippxml/test_1.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fae68d200d7625d1d2f20f26c441734a369d4f31
--- /dev/null
+++ b/test/sip/sippxml/test_1.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- This program 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 2 of the -->
+<!-- License, or (at your option) any later version. -->
+<!-- -->
+<!-- This program 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 this program; if not, write to the -->
+<!-- Free Software Foundation, Inc., -->
+<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
+<!-- -->
+<!-- Sipp default 'uas' scenario. -->
+<!-- -->
+
+<scenario name="UAS responder put on hold then hungup">
+
+ <!-- This scenario implies a second call made by the uac which implies -->
+ <!-- This call to be put on hold automatically -->
+
+ <recv request="INVITE" crlf="true">
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 180 Ringing
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[pid]SIPpTag01[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <send retrans="500">
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[pid]SIPpTag01[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ v=0
+ o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+ s=-
+ c=IN IP[media_ip_type] [media_ip]
+ t=0 0
+ m=audio [media_port] RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ ]]>
+ </send>
+
+ <recv request="ACK"
+ optional="true"
+ rtd="true"
+ crlf="true">
+ </recv>
+
+
+ <!-- Here process a second invite with updated sdp, this call is placed on HOLD -->
+ <!-- TODO: parse in sdp: Media Attribute (a): sendonly -->
+ <recv request="INVITE" crlf="true">
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 100 Trying
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[pid]SIPpTag01[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <send retrans="500">
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[pid]SIPpTag01[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ v=0
+ o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+ s=-
+ c=IN IP[media_ip_type] [media_ip]
+ t=0 0
+ m=audio [media_port] RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ ]]>
+ </send>
+
+ <recv request="ACK"
+ optional="true"
+ rtd="true"
+ crlf="true">
+ </recv>
+
+ <!-- expect to be hung up immediately -->
+ <recv request="BYE">
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <!-- Keep the call open for a while in case the 200 is lost to be -->
+ <!-- able to retransmit it if we receive the BYE again. -->
+ <timewait milliseconds="4000"/>
+
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
diff --git a/test/sip/sippxml/test_2.xml b/test/sip/sippxml/test_2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1856bf713f27cb57a6f7b5b5429a31fb2a0041cd
--- /dev/null
+++ b/test/sip/sippxml/test_2.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- This program 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 2 of the -->
+<!-- License, or (at your option) any later version. -->
+<!-- -->
+<!-- This program 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 this program; if not, write to the -->
+<!-- Free Software Foundation, Inc., -->
+<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
+<!-- -->
+<!-- Sipp default 'uac' scenario. -->
+<!-- -->
+
+<scenario name="Two simultaneous outgoing call Sipstone UAC">
+ <!-- In client mode (sipp placing calls), the Call-ID MUST be -->
+ <!-- generated by sipp. To do so, use [call_id] keyword. -->
+ <send retrans="500">
+ <![CDATA[
+
+ INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
+ To: sut <sip:[service]@[remote_ip]:[remote_port]>
+ Call-ID: [call_id]
+ CSeq: 1 INVITE
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Subject: Performance Test
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ v=0
+ o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+ s=-
+ c=IN IP[media_ip_type] [media_ip]
+ t=0 0
+ m=audio [media_port] RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ ]]>
+ </send>
+
+ <recv response="100" optional="true">
+ </recv>
+
+ <recv response="180" optional="true">
+ </recv>
+
+ <recv response="183" optional="true">
+ </recv>
+
+ <!-- By adding rrs="true" (Record Route Sets), the route sets -->
+ <!-- are saved and used for following messages sent. Useful to test -->
+ <!-- against stateful SIP proxies/B2BUAs. -->
+ <recv response="200" rtd="true">
+ </recv>
+
+ <!-- Packet lost can be simulated in any send/recv message by -->
+ <!-- by adding the 'lost = "10"'. Value can be [1-100] percent. -->
+ <send>
+ <![CDATA[
+
+ ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
+ To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
+ Call-ID: [call_id]
+ CSeq: 1 ACK
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Subject: Performance Test
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <!-- Here is where the call is put on hold -->
+ <recv request="INVITE" crlf="true">
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 100 Trying
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[pid]SIPpTag01[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <send retrans="500">
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[pid]SIPpTag01[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ v=0
+ o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+ s=-
+ c=IN IP[media_ip_type] [media_ip]
+ t=0 0
+ m=audio [media_port] RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ ]]>
+ </send>
+
+ <recv request="ACK"
+ rtd="true"
+ crlf="true">
+ </recv>
+
+ <!-- The 'crlf' option inserts a blank line in the statistics report. -->
+ <send retrans="500">
+ <![CDATA[
+
+ BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
+ To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
+ Call-ID: [call_id]
+ CSeq: 2 BYE
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Subject: Performance Test
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <recv response="200" crlf="true">
+ </recv>
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
diff --git a/test/sip/sippxml/test_3.xml b/test/sip/sippxml/test_3.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bae7eaa2bc795eafd357f3ca30e18433c1220a2e
--- /dev/null
+++ b/test/sip/sippxml/test_3.xml
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+
+<scenario name="UAS HOLD/OFFHOLD">
+
+ <!-- Receive a new call -->
+
+ <recv request="INVITE" crlf="true">
+ <action>
+ <ereg regexp="sendrecv" search_in="body" check_it="true" assign_to="1"/>
+ <log message="Media is [$1]"/>
+ </action>
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 180 Ringing
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <send retrans="500">
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ v=0
+ o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+ s=-
+ c=IN IP[media_ip_type] [media_ip]
+ t=0 0
+ m=audio [media_port] RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ ]]>
+</send>
+
+ <recv request="ACK" optional="true" rtd="true" crlf="true">
+ </recv>
+
+ <!-- This call is now on HOLD: sendonly tell to PBX to send music on hold-->
+
+ <recv request="INVITE" crlf="true">
+ <action>
+ <ereg regexp="sendonly" search_in="body" check_it="true" assign_to="2"/>
+ <log message="Media is [$2]"/>
+ </action>
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 180 Ringing
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <send retrans="500">
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ v=0
+ o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+ s=-
+ c=IN IP[media_ip_type] [media_ip]
+ t=0 0
+ m=audio [media_port] RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ ]]>
+ </send>
+
+ <recv request="ACK" optional="true" rtd="true" crlf="true">
+ </recv>
+
+ <!-- OFFHOLD this call -->
+
+ <recv request="INVITE" crlf="true">
+ <action>
+ <ereg regexp="sendrecv" search_in="body" check_it="true" assign_to="3"/>
+ <log message="Media is [$3]"/>
+ </action>
+ </recv>
+
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 180 Ringing
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <send retrans="500">
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:];tag=[call_number]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ v=0
+ o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+ s=-
+ c=IN IP[media_ip_type] [media_ip]
+ t=0 0
+ m=audio [media_port] RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ ]]>
+ </send>
+
+ <recv request="ACK" optional="true" rtd="true" crlf="true">
+ </recv>
+
+ <!-- Hangup this call -->
+
+ <recv request="BYE">
+ </recv>
+
+ <send>
+ <![CDATA[
+
+ SIP/2.0 200 OK
+ [last_Via:]
+ [last_From:]
+ [last_To:]
+ [last_Call-ID:]
+ [last_CSeq:]
+ Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <pause milliseconds="4000"/>
+
+
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
diff --git a/test/sip/sippxml/test_4.xml b/test/sip/sippxml/test_4.xml
new file mode 100644
index 0000000000000000000000000000000000000000..038aea81001ce7bd3524846065b43646d9995429
--- /dev/null
+++ b/test/sip/sippxml/test_4.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- This program 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 2 of the -->
+<!-- License, or (at your option) any later version. -->
+<!-- -->
+<!-- This program 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 this program; if not, write to the -->
+<!-- Free Software Foundation, Inc., -->
+<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
+<!-- -->
+<!-- Sipp default 'uac' scenario. -->
+<!-- -->
+
+<scenario name="Basic Sipstone UAC">
+ <!-- In client mode (sipp placing calls), the Call-ID MUST be -->
+ <!-- generated by sipp. To do so, use [call_id] keyword. --
+ <send retrans="500">
+ <![CDATA[
+
+ INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
+ To: sut <sip:[service]@[remote_ip]:[remote_port]>
+ Call-ID: [call_id]
+ CSeq: 1 INVITE
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Subject: Performance Test
+ Content-Type: application/sdp
+ Content-Length: [len]
+
+ v=0
+ o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+ s=-
+ c=IN IP[media_ip_type] [media_ip]
+ t=0 0
+ m=audio [media_port] RTP/AVP 0
+ a=rtpmap:0 PCMU/8000
+
+ ]]>
+ </send>
+
+ <recv response="100"
+ optional="true">
+ </recv>
+
+ <recv response="180" optional="true">
+ </recv>
+
+ <recv response="183" optional="true">
+ </recv>
+
+ <!-- By adding rrs="true" (Record Route Sets), the route sets -->
+ <!-- are saved and used for following messages sent. Useful to test -->
+ <!-- against stateful SIP proxies/B2BUAs. -->
+ <recv response="200" rtd="true">
+ <action>
+ <ereg regexp="a=rtpmap:0 PCMU/8000" search_in="body" check_it="true" assign_to="1" />
+ <log message="Custom header is [$1]"/>
+ </action>
+ </recv>
+
+ <!-- Packet lost can be simulated in any send/recv message by -->
+ <!-- by adding the 'lost = "10"'. Value can be [1-100] percent. -->
+ <send>
+ <![CDATA[
+
+ ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
+ To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
+ Call-ID: [call_id]
+ CSeq: 1 ACK
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Subject: Performance Test
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <!-- This delay can be customized by the -d command-line option -->
+ <!-- or by adding a 'milliseconds = "value"' option here. -->
+ <pause/>
+
+ <!-- The 'crlf' option inserts a blank line in the statistics report. -->
+ <send retrans="500">
+ <![CDATA[
+
+ BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+ Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+ From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]
+ To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
+ Call-ID: [call_id]
+ CSeq: 2 BYE
+ Contact: sip:sipp@[local_ip]:[local_port]
+ Max-Forwards: 70
+ Subject: Performance Test
+ Content-Length: 0
+
+ ]]>
+ </send>
+
+ <recv response="200" crlf="true">
+ </recv>
+
+ <!-- definition of the response time repartition table (unit is ms) -->
+ <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+ <!-- definition of the call length repartition table (unit is ms) -->
+ <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
diff --git a/test/sip/test_SIP.cpp b/test/sip/test_SIP.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ebf16b0c2fafc5358e285693e56fd645659804f7
--- /dev/null
+++ b/test/sip/test_SIP.cpp
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
+ * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Additional permission under GNU GPL version 3 section 7:
+ *
+ * If you modify this program, or any covered work, by linking or
+ * combining it with the OpenSSL project's OpenSSL library (or a
+ * modified version of that library), containing parts covered by the
+ * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ * grants you additional permission to convey the resulting work.
+ * Corresponding Source for a non-source form of such a combination
+ * shall include the source code for the parts of OpenSSL used as well
+ * as that of the covered work.
+ */
+
+#include <unistd.h>
+#include <cstdlib>
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+
+#include <pthread.h>
+#include <string>
+
+#include "test_SIP.h"
+
+
+// anonymous namespace
+namespace {
+pthread_mutex_t count_mutex;
+pthread_cond_t count_nb_thread;
+int counter = 0;
+}
+namespace ring {
+ CPPUNIT_TEST_SUITE_REGISTRATION( test_SIP );
+/*
+return an error if all call are not successful
+*/
+void *sippThreadWithCount(void *str)
+{
+ // number of time we use the mutex. Lock the utilisation of counter
+ pthread_mutex_lock(&count_mutex);
+ counter++;
+ pthread_mutex_unlock(&count_mutex);
+
+ // display what is send on the parameter of the method
+ std::string *command = (std::string *)(str);
+
+ std::cout << "test_SIP: " << command << std::endl;
+
+ // Set up the sipp instance in this thread in order to catch return value
+ // 0: All calls were successful
+ // 1: At least one call failed
+ // 97: exit on internal command. Calls may have been processed
+ // 99: Normal exit without calls processed
+ // -1: Fatal error
+ // -2: Fatal error binding a socket
+ int i = system(command->c_str()); //c_str() retrieve the *char of the string
+
+ CPPUNIT_ASSERT(i);
+
+ pthread_mutex_lock(&count_mutex);
+ counter--;
+ // ???
+ if (counter == 0)
+ pthread_cond_signal(&count_nb_thread);
+
+ pthread_mutex_unlock(&count_mutex);
+
+ pthread_exit(NULL);
+}
+
+
+void *sippThread(void *str)
+{
+ std::string *command = static_cast<std::string *>(str);
+ std::cout << "test_SIP: " << command << std::endl;
+
+ // Set up the sipp instance in this thread in order to catch return value
+ // 0: All calls were successful
+ // 1: At least one call failed
+ // 97: exit on internal command. Calls may have been processed
+ // 99: Normal exit without calls processed
+ // -1: Fatal error
+ // -2: Fatal error binding a socket
+ int i = system(command->c_str());
+
+ std::stringstream output;
+ output << i;
+
+ std::cout << "test_SIP: Command executed by system returned: " << output.str() << std::endl;
+ pthread_exit(NULL);
+}
+
+
+void test_SIP::setUp()
+{
+ std::cout << "setup test SIP" << std::endl;
+ pthread_mutex_lock(&count_mutex);
+ counter = 0;
+ pthread_mutex_unlock(&count_mutex);
+}
+
+void test_SIP::tearDown()
+{
+ // in order to stop any currently running threads
+ std::cout << "test_SIP: Clean all remaining sipp instances" << std::endl;
+ int ret = system("killall sipp");
+
+ if (!ret)
+ std::cout << "test_SIP: Error from system call, killall sipp" << std::endl;
+}
+
+
+void test_SIP::testSimpleOutgoingIpCall()
+{
+ pthread_t thethread;
+
+ // command to be executed by the thread, user agent server waiting for a call
+ std::string command("sipp -sn uas -i 127.0.0.1 -p 5068 -m 1 -bg");
+
+ int rc = pthread_create(&thethread, NULL, sippThread, &command);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_create()" << std::endl;
+
+ std::string testaccount("IP2IP");
+ std::string testcallid("callid1234");
+ std::string testcallnumber("sip:test@127.0.0.1:5068");
+
+ CPPUNIT_ASSERT(!Manager::instance().hasCurrentCall());
+
+ // start a new call sending INVITE message to sipp instance
+ Manager::instance().outgoingCall(testaccount, testcallid, testcallnumber);
+
+ // must sleep here until receiving 180 and 200 message from peer
+ sleep(2);
+
+ CPPUNIT_ASSERT(Manager::instance().hasCurrentCall());
+ //CPPUNIT_ASSERT(Manager::instance().getCurrentCallId() == testcallid);
+
+ Manager::instance().hangupCall(testcallid);
+
+ rc = pthread_join(thethread, NULL);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_join(): " << rc << std::endl;
+ else
+ std::cout << "test_SIP: completed join with thread" << std::endl;
+}
+
+
+/*void test_SIP::testSimpleIncomingIpCall()
+{
+ pthread_t thethread;
+
+ // command to be executed by the thread, user agent client which initiate a call and hangup
+ std::string command("sipp -sn uac 127.0.0.1 -i 127.0.0.1 -p 5062 -m 1i -bg");
+
+ int rc = pthread_create(&thethread, NULL, sippThread, &command);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_create()" << std::endl;
+
+ // sleep a while to make sure that sipp insdtance is initialized and sflphoned received
+ // the incoming invite.
+ sleep(2);
+
+ // gtrab call id from sipvoiplink
+ SIPVoIPLink& siplink = SIPVoIPLink::instance();
+
+ CPPUNIT_ASSERT(siplink.sipCallMap_.size() == 1);
+ SipCallMap::iterator iterCallId = siplink.sipCallMap_.begin();
+ std::string testcallid = iterCallId->first;
+
+ // Answer this call
+ CPPUNIT_ASSERT(Manager::instance().answerCall(testcallid));
+
+ sleep(1);
+
+ rc = pthread_join(thethread, NULL);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_join(): " << rc << std::endl;
+ else
+ std::cout << "test_SIP: completed join with thread" << std::endl;
+}*/
+
+
+void test_SIP::testTwoOutgoingIpCall()
+{
+ // This scenario expect to be put on hold before hangup
+ std::string firstCallCommand("sipp -sf tools/sippxml/test_1.xml -i 127.0.0.1 -p 5062 -m 1");
+
+ // The second call uses the default user agent scenario
+ std::string secondCallCommand("sipp -sn uas -i 127.0.0.1 -p 5064 -m 1");
+
+ pthread_t firstCallThread;
+ int rc = pthread_create(&firstCallThread, NULL, sippThread, &firstCallCommand);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_create()" << std::endl;
+
+ pthread_t secondCallThread;
+ rc = pthread_create(&secondCallThread, NULL, sippThread, &secondCallCommand);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_create()" << std::endl;
+
+ sleep(1);
+
+ std::string testAccount("IP2IP");
+
+ std::string firstCallID("callid1234");
+ std::string firstCallNumber("sip:test@127.0.0.1:5062");
+
+ std::string secondCallID("callid2345");
+ std::string secondCallNumber("sip:test@127.0.0.1:5064");
+
+ CPPUNIT_ASSERT(!Manager::instance().hasCurrentCall());
+
+ // start a new call sending INVITE message to sipp instance
+ // this call should be put on hold when making the second call
+ Manager::instance().outgoingCall(testAccount, firstCallID, firstCallNumber);
+
+ // must sleep here until receiving 180 and 200 message from peer
+ sleep(1);
+
+ Manager::instance().outgoingCall(testAccount, secondCallID, secondCallNumber);
+
+ sleep(1);
+
+ Manager::instance().hangupCall(firstCallID);
+
+ rc = pthread_join(firstCallThread, NULL);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_join(): " << rc << std::endl;
+
+ std::cout << "test_SIP: completed join with thread" << std::endl;
+
+ Manager::instance().hangupCall(secondCallID);
+
+ rc = pthread_join(secondCallThread, NULL);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_join(): " << rc << std::endl;
+ else
+ std::cout << "test_SIP: completed join with thread" << std::endl;
+}
+
+/*void test_SIP::testTwoIncomingIpCall()
+{
+ pthread_mutex_init(&count_mutex, NULL);
+ pthread_cond_init(&count_nb_thread, NULL);
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+ // the first call is supposed to be put on hold when answering teh second incoming call
+ std::string firstCallCommand("sipp -sf tools/sippxml/test_2.xml 127.0.0.1 -i 127.0.0.1 -p 5064 -m 1 > testfile1.txt -bg");
+
+ // command to be executed by the thread, user agent client which initiate a call and hangup
+ std::string secondCallCommand("sipp -sn uac 127.0.0.1 -i 127.0.0.1 -p 5062 -m 1 -d 250 > testfile2.txt -bg");
+
+ pthread_t firstCallThread;
+ int rc = pthread_create(&firstCallThread, &attr, sippThreadWithCount, &firstCallCommand);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_create()" << std::endl;
+
+ // sleep a while to make sure that sipp insdtance is initialized and sflphoned received
+ // the incoming invite.
+ sleep(1);
+
+ // gtrab call id from sipvoiplink
+ SIPVoIPLink& sipLink = SIPVoIPLink::instance();
+
+ CPPUNIT_ASSERT(sipLink.sipCallMap_.size() == 1);
+ SipCallMap::iterator iterCallId = sipLink.sipCallMap_.begin();
+ std::string firstCallID = iterCallId->first;
+
+ // Answer this call
+ CPPUNIT_ASSERT(Manager::instance().answerCall(firstCallID));
+
+ sleep(1);
+ pthread_t secondCallThread;
+ rc = pthread_create(&secondCallThread, &attr, sippThread, &secondCallCommand);
+
+ if (rc)
+ std::cout << "test_SIP: Error; return code from pthread_create()" << std::endl;
+
+ sleep(1);
+
+ CPPUNIT_ASSERT(sipLink.sipCallMap_.size() == 2);
+ iterCallId = sipLink.sipCallMap_.begin();
+
+ if (iterCallId->first == firstCallID)
+ ++iterCallId;
+
+ std::string secondCallID(iterCallId->first);
+
+ CPPUNIT_ASSERT(Manager::instance().answerCall(secondCallID));
+
+ sleep(2);
+
+ pthread_mutex_lock(&count_mutex);
+
+ while (counter > 0)
+ pthread_cond_wait(&count_nb_thread, &count_mutex);
+
+ pthread_mutex_unlock(&count_mutex);
+
+ pthread_mutex_destroy(&count_mutex);
+ pthread_cond_destroy(&count_nb_thread);
+}*/
+
+
+void test_SIP::testHoldIpCall()
+{
+ std::string callCommand("sipp -sf tools/sippxml/test_3.xml -i 127.0.0.1 -p 5062 -m 1 -bg");
+
+ pthread_t callThread;
+ int rc = pthread_create(&callThread, NULL, sippThread, (void *)(&callCommand));
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_create(): " << rc << std::endl;
+ else
+ std::cout << "test_SIP: completed thread creation" << std::endl;
+
+
+ std::string testAccount("IP2IP");
+
+ std::string testCallID("callid1234");
+ std::string testCallNumber("sip:test@127.0.0.1:5062");
+
+ Manager::instance().outgoingCall(testAccount, testCallID, testCallNumber);
+
+ sleep(1);
+
+ Manager::instance().onHoldCall(testCallID);
+
+ sleep(1);
+
+ Manager::instance().offHoldCall(testCallID);
+
+ sleep(1);
+
+ Manager::instance().hangupCall(testCallID);
+}
+
+/*void test_SIP::testSIPURI()
+{
+ std::string foo("<sip:17771234567@callcentric.com>");
+ sip_utils::stripSipUriPrefix(foo);
+ CPPUNIT_ASSERT(foo == "17771234567");
+}*/
+
+/*void test_SIP::testParseDisplayName()
+{
+ // 1st element is input, 2nd is expected output
+ const char *test_set[][2] = {
+ {"\nFrom: \"A. G. Bell\" <sip:agb@bell-telephone.com> ;tag=a48s", "A. G. Bell"},
+ {"\nFrom: \"A. G. Bell2\" <sip:agb@bell-telephone.com> ;tag=a48s\r\nOtherLine: \"bla\"\r\n", "A. G. Bell2"},
+ {"\nf: Anonymous <sip:c8oqz84zk7z@privacy.org>;tag=hyh8", "Anonymous"},
+ {"\nFrom: \"Alejandro Perez\" <sip:1111@10.0.0.1>;tag=3a7516a63bdbo0", "Alejandro Perez"},
+ {"\nFrom: \"Malformed <sip:1111@10.0.0.1>;tag=3a6a63bdbo0", ""},
+ {"\nTo: <sip:1955@10.0.0.1>;tag=as6fbade41", ""},
+ {"\nFrom: \"1000\" <sip:1000@sip.example.es>;tag=as775338f3", "1000"},
+ {"\nFrom: 1111_9532323 <sip:1111_9532323@sip.example.es>;tag=caa3a61", "1111_9532323"},
+ {"\nFrom: \"4444_953111111\" <sip:4444_111111@sip.example.es>;tag=2b00632co0", "4444_953111111"},
+ {"\nFrom: <sip:6926666@4.4.4.4>;tag=4421-D9700", ""},
+ {"\nFrom: <sip:pinger@sipwise.local>;tag=01f516a4", ""},
+ {"\nFrom: sip:pinger@sipwise.local;tag=01f516a4", ""},
+ {"\nFrom: ", ""},
+ {"\nFrom: \"\xb1""Alejandro P\xc3\xa9rez\" <sip:1111@10.0.0.1>;tag=3a7516a63bdbo0", "\xef\xbf\xbd""Alejandro P\xc3\xa9rez"},
+ {"\nFrom: \"Alejandro P\xc3\xa9rez\" <sip:1111@10.0.0.1>;tag=3a7516a63bdbo0", "Alejandro P\xc3\xa9rez"},
+ {"\nFrom: sip:+1212555@server.example.com;tag=887s", ""}};
+
+ for (const auto &t : test_set) {
+ const std::string str(sip_utils::parseDisplayName(t[0]));
+ CPPUNIT_ASSERT_MESSAGE(std::string("\"") + str + "\" should be \"" +
+ t[1] + "\", input on next line: " + t[0],
+ str == t[1]);
+ }
+}*/
+
+/*void test_SIP::testIncomingIpCallSdp()
+{
+ // command to be executed by the thread, user agent client which initiate a call and hangup
+ std::string command("sipp -sf tools/sippxml/test_4.xml 127.0.0.1 -i 127.0.0.1 -p 5062 -m 1i -bg");
+
+ pthread_t thethread;
+ int rc = pthread_create(&thethread, NULL, sippThread, (void *)(&command));
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_create()" << std::endl;
+
+ // sleep a while to make sure that sipp insdtance is initialized and sflphoned received
+ // the incoming invite.
+ sleep(2);
+
+ // gtrab call id from sipvoiplink
+ SIPVoIPLink& siplink = SIPVoIPLink::instance();
+
+ CPPUNIT_ASSERT(siplink.sipCallMap_.size() == 1);
+ SipCallMap::iterator iterCallId = siplink.sipCallMap_.begin();
+ std::string testcallid = iterCallId->first;
+
+ // TODO: hmmm, should IP2IP call be stored in call list....
+ CPPUNIT_ASSERT(Manager::instance().getCallList().empty());
+
+ // Answer this call
+ CPPUNIT_ASSERT(Manager::instance().answerCall(testcallid));
+
+
+ sleep(1);
+
+ rc = pthread_join(thethread, NULL);
+
+ if (rc)
+ std::cout << "test_SIP: ERROR; return code from pthread_join(): " << rc << std::endl;
+ else
+ std::cout << "test_SIP: completed join with thread" << std::endl;
+}*/
+}
diff --git a/test/sip/test_SIP.h b/test/sip/test_SIP.h
new file mode 100644
index 0000000000000000000000000000000000000000..d522c6453f03020b3db22fde9f2b0cfc7865c8da
--- /dev/null
+++ b/test/sip/test_SIP.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
+ * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Additional permission under GNU GPL version 3 section 7:
+ *
+ * If you modify this program, or any covered work, by linking or
+ * combining it with the OpenSSL project's OpenSSL library (or a
+ * modified version of that library), containing parts covered by the
+ * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
+ * grants you additional permission to convey the resulting work.
+ * Corresponding Source for a non-source form of such a combination
+ * shall include the source code for the parts of OpenSSL used as well
+ * as that of the covered work.
+ */
+#pragma once
+//#include "../../src/manager.h"
+
+// Cppunit import
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCaller.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/TestSuite.h>
+
+// Application import
+#include "manager.h"
+#include "../../src/sip/sipvoiplink.h"
+#include "../../src/sip/sip_utils.h"
+/*
+ * @file Test-sip.h
+ * @brief Regroups unitary tests related to the SIP module
+ */
+
+namespace ring {
+class test_SIP : public CppUnit::TestFixture {
+
+ /**
+ * Use cppunit library macros to add unit test the factory
+ */
+ CPPUNIT_TEST_SUITE(test_SIP);
+ CPPUNIT_TEST ( testSimpleOutgoingIpCall );
+ //CPPUNIT_TEST ( testParseDisplayName );
+ //CPPUNIT_TEST ( testSimpleIncomingIpCall );
+ //CPPUNIT_TEST ( testTwoOutgoingIpCall );
+ //CPPUNIT_TEST ( testTwoIncomingIpCall );
+ //CPPUNIT_TEST ( testHoldIpCall );
+ //CPPUNIT_TEST ( testIncomingIpCallSdp );
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ //test_SIP() : CppUnit::TestCase("SIP module Tests") {}
+
+ /*
+ * Code factoring - Common resources can be initialized here.
+ * This method is called by unitcpp before each test
+ */
+ void setUp();
+
+ /*
+ * Code factoring - Common resources can be released here.
+ * This method is called by unitcpp after each test
+ */
+ void tearDown();
+
+
+ void testSimpleOutgoingIpCall(void);
+
+ //void testSimpleIncomingIpCall(void);
+
+ void testTwoOutgoingIpCall(void);
+
+ //void testTwoIncomingIpCall(void);
+
+ void testHoldIpCall(void);
+
+ //void testIncomingIpCallSdp(void);
+
+ //void testSIPURI();
+
+ //void testParseDisplayName();
+};
+} //end ring namespace