diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 33 | ||||
-rw-r--r-- | include/baresip.h | 125 | ||||
-rw-r--r-- | modules/ice/ice.c | 7 | ||||
-rw-r--r-- | test/cplusplus.cpp | 16 | ||||
-rw-r--r-- | test/main.c | 6 | ||||
-rw-r--r-- | test/mock/cert.c | 82 | ||||
-rw-r--r-- | test/mock/sipsrv.c | 145 | ||||
-rw-r--r-- | test/sip_server.c | 113 | ||||
-rw-r--r-- | test/srcs.mk | 16 | ||||
-rw-r--r-- | test/test.h | 43 | ||||
-rw-r--r-- | test/ua.c | 27 |
12 files changed, 430 insertions, 184 deletions
@@ -22,3 +22,4 @@ selftest # Generated files src/static.c build* +*.pc @@ -14,6 +14,7 @@ USE_VIDEO := 1 PROJECT := baresip VERSION := 0.4.15 +DESCR := "Baresip is a modular SIP User-Agent with audio and video support" ifndef LIBRE_MK LIBRE_MK := $(shell [ -f ../re/mk/re.mk ] && \ @@ -49,6 +50,9 @@ CXXFLAGS += -I$(LIBREM_PATH)/include CXXFLAGS += -I$(SYSROOT)/local/include/rem -I$(SYSROOT)/include/rem CXXFLAGS += $(EXTRA_CXXFLAGS) +# XXX: common for C/C++ +CPPFLAGS += -DHAVE_INTTYPES_H + ifneq ($(LIBREM_PATH),) SPLINT_OPTIONS += -I$(LIBREM_PATH)/include CLANG_OPTIONS += -I$(LIBREM_PATH)/include @@ -118,6 +122,7 @@ APP_OBJS := $(OBJS) $(patsubst %.c,$(BUILD)/src/%.o,$(APP_SRCS)) $(MOD_OBJS) LIB_OBJS := $(OBJS) $(MOD_OBJS) TEST_OBJS := $(patsubst %.c,$(BUILD)/test/%.o,$(filter %.c,$(TEST_SRCS))) +TEST_OBJS += $(patsubst %.cpp,$(BUILD)/test/%.o,$(filter %.cpp,$(TEST_SRCS))) ifneq ($(LIBREM_PATH),) LIBS += -L$(LIBREM_PATH) @@ -168,6 +173,19 @@ ifneq ($(RANLIB),) @$(RANLIB) $@ endif +libbaresip.pc: + @echo 'prefix='$(PREFIX) > libbaresip.pc + @echo 'exec_prefix=$${prefix}' >> libbaresip.pc + @echo 'libdir=$${prefix}/lib' >> libbaresip.pc + @echo 'includedir=$${prefix}/include' >> libbaresip.pc + @echo '' >> libbaresip.pc + @echo 'Name: libbaresip' >> libbaresip.pc + @echo 'Description: $(DESCR)' >> libbaresip.pc + @echo 'Version: '$(VERSION) >> libbaresip.pc + @echo 'URL: http://www.creytiv.com/baresip.html' >> libbaresip.pc + @echo 'Libs: -L$${libdir} -lbaresip' >> libbaresip.pc + @echo 'Cflags: -I$${includedir}' >> libbaresip.pc + # GPROF requires static linking $(BIN): $(APP_OBJS) @echo " LD $@" @@ -192,6 +210,10 @@ $(BUILD)/%.o: %.c $(BUILD) Makefile $(APP_MK) @echo " CC $@" @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) +$(BUILD)/%.o: %.cpp $(BUILD) Makefile $(APP_MK) + @echo " CXX $@" + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ $(DFLAGS) + $(BUILD)/%.o: %.m $(BUILD) Makefile $(APP_MK) @echo " OC $@" @$(CC) $(CFLAGS) $(OBJCFLAGS) -c $< -o $@ $(DFLAGS) @@ -201,7 +223,7 @@ $(BUILD)/%.o: %.S $(BUILD) Makefile $(APP_MK) @$(CC) $(CFLAGS) -c $< -o $@ $(DFLAGS) $(BUILD): Makefile - @mkdir -p $(BUILD)/src $(MOD_BLD) $(BUILD)/test + @mkdir -p $(BUILD)/src $(MOD_BLD) $(BUILD)/test/mock @touch $@ install: $(BIN) $(MOD_BINS) @@ -214,11 +236,12 @@ install: $(BIN) $(MOD_BINS) install-dev: install-shared install-static -install-shared: $(SHARED) +install-shared: $(SHARED) libbaresip.pc @mkdir -p $(DESTDIR)$(INCDIR) $(INSTALL) -Cm 0644 include/baresip.h $(DESTDIR)$(INCDIR) - @mkdir -p $(DESTDIR)$(LIBDIR) + @mkdir -p $(DESTDIR)$(LIBDIR) $(DESTDIR)$(LIBDIR)/pkgconfig $(INSTALL) -m 0644 $(SHARED) $(DESTDIR)$(LIBDIR) + $(INSTALL) -m 0644 libbaresip.pc $(DESTDIR)$(LIBDIR)/pkgconfig install-static: $(STATICLIB) @mkdir -p $(DESTDIR)$(INCDIR) @@ -231,10 +254,12 @@ uninstall: @rm -rf $(DESTDIR)$(MOD_PATH) @rm -f $(DESTDIR)$(PREFIX)/lib/$(SHARED) @rm -f $(DESTDIR)$(PREFIX)/lib/$(STATICLIB) + @rm -f $(DESTDIR)$(PREFIX)/lib/pkgconfig/libbaresip.pc .PHONY: clean clean: - @rm -rf $(BIN) $(MOD_BINS) $(SHARED) $(BUILD) $(TEST_BIN) + @rm -rf $(BIN) $(MOD_BINS) $(SHARED) $(BUILD) $(TEST_BIN) \ + $(STATICLIB) libbaresip.pc @rm -f *stamp \ `find . -name "*.[od]"` \ `find . -name "*~"` \ diff --git a/include/baresip.h b/include/baresip.h index 2d9c598..3ac753e 100644 --- a/include/baresip.h +++ b/include/baresip.h @@ -130,69 +130,86 @@ enum audio_mode { AUDIO_MODE_TMR /**< Use timer */ }; + +/** SIP User-Agent */ +struct config_sip { + uint32_t trans_bsize; /**< SIP Transaction bucket size */ + char uuid[64]; /**< Universally Unique Identifier */ + char local[64]; /**< Local SIP Address */ + char cert[256]; /**< SIP Certificate */ +}; + +/** Audio */ +struct config_audio { + char src_mod[16]; /**< Audio source module */ + char src_dev[128]; /**< Audio source device */ + char play_mod[16]; /**< Audio playback module */ + char play_dev[128]; /**< Audio playback device */ + char alert_mod[16]; /**< Audio alert module */ + char alert_dev[128]; /**< Audio alert device */ + struct range srate; /**< Audio sampling rate in [Hz] */ + struct range channels; /**< Nr. of audio channels (1=mono) */ + uint32_t srate_play; /**< Opt. sampling rate for player */ + uint32_t srate_src; /**< Opt. sampling rate for source */ + uint32_t channels_play; /**< Opt. channels for player */ + uint32_t channels_src; /**< Opt. channels for source */ + bool src_first; /**< Audio source opened first */ + enum audio_mode txmode; /**< Audio transmit mode */ +}; + +#ifdef USE_VIDEO +/** Video */ +struct config_video { + char src_mod[16]; /**< Video source module */ + char src_dev[128]; /**< Video source device */ + char disp_mod[16]; /**< Video display module */ + char disp_dev[128]; /**< Video display device */ + unsigned width, height; /**< Video resolution */ + uint32_t bitrate; /**< Encoder bitrate in [bit/s] */ + uint32_t fps; /**< Video framerate */ +}; +#endif + +/** Audio/Video Transport */ +struct config_avt { + uint8_t rtp_tos; /**< Type-of-Service for outg. RTP */ + struct range rtp_ports; /**< RTP port range */ + struct range rtp_bw; /**< RTP Bandwidth range [bit/s] */ + bool rtcp_enable; /**< RTCP is enabled */ + bool rtcp_mux; /**< RTP/RTCP multiplexing */ + struct range jbuf_del; /**< Delay, number of frames */ + bool rtp_stats; /**< Enable RTP statistics */ +}; + +/* Network */ +struct config_net { + char ifname[16]; /**< Bind to interface (optional) */ +}; + +#ifdef USE_VIDEO +/* BFCP */ +struct config_bfcp { + char proto[16]; /**< BFCP Transport (optional) */ +}; +#endif + + /** Core configuration */ struct config { - /** SIP User-Agent */ - struct config_sip { - uint32_t trans_bsize; /**< SIP Transaction bucket size */ - char uuid[64]; /**< Universally Unique Identifier */ - char local[64]; /**< Local SIP Address */ - char cert[256]; /**< SIP Certificate */ - } sip; - - /** Audio */ - struct config_audio { - char src_mod[16]; /**< Audio source module */ - char src_dev[128]; /**< Audio source device */ - char play_mod[16]; /**< Audio playback module */ - char play_dev[128]; /**< Audio playback device */ - char alert_mod[16]; /**< Audio alert module */ - char alert_dev[128]; /**< Audio alert device */ - struct range srate; /**< Audio sampling rate in [Hz] */ - struct range channels; /**< Nr. of audio channels (1=mono) */ - uint32_t srate_play; /**< Opt. sampling rate for player */ - uint32_t srate_src; /**< Opt. sampling rate for source */ - uint32_t channels_play; /**< Opt. channels for player */ - uint32_t channels_src; /**< Opt. channels for source */ - bool src_first; /**< Audio source opened first */ - enum audio_mode txmode; /**< Audio transmit mode */ - } audio; + struct config_sip sip; + + struct config_audio audio; #ifdef USE_VIDEO - /** Video */ - struct config_video { - char src_mod[16]; /**< Video source module */ - char src_dev[128]; /**< Video source device */ - char disp_mod[16]; /**< Video display module */ - char disp_dev[128]; /**< Video display device */ - unsigned width, height; /**< Video resolution */ - uint32_t bitrate; /**< Encoder bitrate in [bit/s] */ - uint32_t fps; /**< Video framerate */ - } video; + struct config_video video; #endif + struct config_avt avt; - /** Audio/Video Transport */ - struct config_avt { - uint8_t rtp_tos; /**< Type-of-Service for outg. RTP */ - struct range rtp_ports; /**< RTP port range */ - struct range rtp_bw; /**< RTP Bandwidth range [bit/s] */ - bool rtcp_enable; /**< RTCP is enabled */ - bool rtcp_mux; /**< RTP/RTCP multiplexing */ - struct range jbuf_del; /**< Delay, number of frames */ - bool rtp_stats; /**< Enable RTP statistics */ - } avt; - - /* Network */ - struct config_net { - char ifname[16]; /**< Bind to interface (optional) */ - } net; + struct config_net net; #ifdef USE_VIDEO - /* BFCP */ - struct config_bfcp { - char proto[16]; /**< BFCP Transport (optional) */ - } bfcp; + struct config_bfcp bfcp; #endif }; diff --git a/modules/ice/ice.c b/modules/ice/ice.c index ac2c4d9..2782069 100644 --- a/modules/ice/ice.c +++ b/modules/ice/ice.c @@ -250,6 +250,9 @@ static void dns_handler(int err, const struct sa *srv, void *arg) if (err) goto out; + debug("ice: resolved %s-server to address %J\n", + ice.turn ? "TURN" : "STUN", srv); + sess->srv = *srv; for (le=sess->medial.head; le; le=le->next) { @@ -281,6 +284,10 @@ static int session_alloc(struct mnat_sess **sessp, struct dnsc *dnsc, if (!sessp || !dnsc || !srv || !user || !pass || !ss || !estabh) return EINVAL; + info("ice: new session with %s-server at %s (username=%s)\n", + ice.turn ? "TURN" : "STUN", + srv, user); + sess = mem_zalloc(sizeof(*sess), session_destructor); if (!sess) return ENOMEM; diff --git a/test/cplusplus.cpp b/test/cplusplus.cpp new file mode 100644 index 0000000..b6ddaa9 --- /dev/null +++ b/test/cplusplus.cpp @@ -0,0 +1,16 @@ +/** + * @file test/cplusplus.cpp Baresip selftest -- C++ compatibility + * + * Copyright (C) 2010 - 2015 Creytiv.com + */ +#include <re.h> +#include <rem.h> +#include <baresip.h> +#include "test.h" + + +int test_cplusplus(void) +{ + re_printf("c++ ok\n"); + return 0; +} diff --git a/test/main.c b/test/main.c index c32cd4b..d39adfe 100644 --- a/test/main.c +++ b/test/main.c @@ -28,6 +28,10 @@ static int run_tests(void) if (err) return err; + err = test_cplusplus(); + if (err) + return err; + return 0; } @@ -41,7 +45,7 @@ int main(void) if (err) return err; - re_printf("running test..\n"); + re_printf("running test version %s\n", BARESIP_VERSION); /* note: run SIP-traffic on localhost */ config = conf_config(); diff --git a/test/mock/cert.c b/test/mock/cert.c new file mode 100644 index 0000000..a711082 --- /dev/null +++ b/test/mock/cert.c @@ -0,0 +1,82 @@ +/** + * @file cert.c TLS Certificate + * + * Copyright (C) 2010 Creytiv.com + */ +#include <re.h> +#include "../test.h" + + +/** + * Dummy certificate for testing. + * + * + * It was generated like this: + * + * $ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \ + * -days 36500 -nodes + * + * + * Dumping information: + * + * $ openssl x509 -subject -dates -fingerprint -in cert.pem + * subject= /C=NO/ST=Retest/O=Retest AS/CN=Mr Retest/emailAddress=re@test.org + * notBefore=Nov 23 18:40:38 2014 GMT + * notAfter=Oct 30 18:40:38 2114 GMT + * Fingerprint=49:A4:E9:F4:80:3A:D4:38:84:F1:64:C3:B9:4B:F9:BB:80:F7:07:76 + */ + +const char test_certificate[] = + +"-----BEGIN CERTIFICATE-----\r\n" +"MIIDmTCCAoGgAwIBAgIJAIt1/MAlTpB7MA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV\r\n" +"BAYTAk5PMQ8wDQYDVQQIDAZSZXRlc3QxEjAQBgNVBAoMCVJldGVzdCBBUzESMBAG\r\n" +"A1UEAwwJTXIgUmV0ZXN0MRowGAYJKoZIhvcNAQkBFgtyZUB0ZXN0Lm9yZzAgFw0x\r\n" +"NDExMjMxODQwMzhaGA8yMTE0MTAzMDE4NDAzOFowYjELMAkGA1UEBhMCTk8xDzAN\r\n" +"BgNVBAgMBlJldGVzdDESMBAGA1UECgwJUmV0ZXN0IEFTMRIwEAYDVQQDDAlNciBS\r\n" +"ZXRlc3QxGjAYBgkqhkiG9w0BCQEWC3JlQHRlc3Qub3JnMIIBIjANBgkqhkiG9w0B\r\n" +"AQEFAAOCAQ8AMIIBCgKCAQEAqnX4j6WK6tcN/X+C8C9ZSSlhVT2OdPB/lAPa3T3w\r\n" +"eB3wu2C9gnZcCSvekBhyFKSi4w0Az5HNjJWWQqpSeYW2MCEKI97DIu0hg/5qn2le\r\n" +"2sDjo4u/SNdH0CQHaLD2Xu0hhvZ/dTIulxpy5hLVmxs8/UZ8QKZ3vxDFE92p4LBL\r\n" +"tLYz6+TvWovmUqYL97J+2muXUMcZCCTbk8DQSGLBbsawXejVF8RgPiFHCvefybUQ\r\n" +"JCbtTDTfMykVnMEv3yMmfcXG/mwG8CLDRv7y8wh632aDdWfKN+g70gH0CFdjn070\r\n" +"eIZyJ3TyRi4b55RSC4FAdP2YKToOUH55N86wrbprnHb8swIDAQABo1AwTjAdBgNV\r\n" +"HQ4EFgQUcaZeVPUmMPFvKwYzn27b8BUJV3AwHwYDVR0jBBgwFoAUcaZeVPUmMPFv\r\n" +"KwYzn27b8BUJV3AwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAbsMt\r\n" +"zruNpBUZv08vdoWN9QWaJrmv8fvcx/RcuVLRuAaLYExEUJnoz3+dNFbR38BvncVC\r\n" +"LlDcSIK06JIHX6E7gJegWQdECoO/YgQGCwoIoQJtNCybxtZccb5uAGY/+qO3uOx0\r\n" +"Vx1NxrAMh5cpOIhZ8XiSYA2+JB71prW97diSQS+cU9xWCJxPU7UqQ10nV7PbfSmp\r\n" +"XTnj+togZPXYzJmSQR4RoM4Vqu27syo7xYQ90twoRKpRYTPdDTArpkTn6KuUuCJ1\r\n" +"t2v9LOkkxOvF11rLY6rLf0BG4XYkhnz4CLLt428wvAPykPcs95Q9TwpF/nKEwyfh\r\n" +"J+cC3FZTiBf/YmPPaA==\r\n" +"-----END CERTIFICATE-----\r\n" + +"-----BEGIN PRIVATE KEY-----\r\n" +"MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCqdfiPpYrq1w39\r\n" +"f4LwL1lJKWFVPY508H+UA9rdPfB4HfC7YL2CdlwJK96QGHIUpKLjDQDPkc2MlZZC\r\n" +"qlJ5hbYwIQoj3sMi7SGD/mqfaV7awOOji79I10fQJAdosPZe7SGG9n91Mi6XGnLm\r\n" +"EtWbGzz9RnxApne/EMUT3angsEu0tjPr5O9ai+ZSpgv3sn7aa5dQxxkIJNuTwNBI\r\n" +"YsFuxrBd6NUXxGA+IUcK95/JtRAkJu1MNN8zKRWcwS/fIyZ9xcb+bAbwIsNG/vLz\r\n" +"CHrfZoN1Z8o36DvSAfQIV2OfTvR4hnIndPJGLhvnlFILgUB0/ZgpOg5Qfnk3zrCt\r\n" +"umucdvyzAgMBAAECggEAC1xxhKFz8NMEi7DD+V4uhUHMyvGfXQvqdOMM41INhPP5\r\n" +"54M7HkblO3dBDjmS4O1YLenf8/WzzXrq2OahOJhA3FRXaKygNOO5KCL82EMdn1bb\r\n" +"1TqrNR+kGatNEx04TntfkK89L4J4uHl6zvrSYdQe7IKWJXjy4jkr6XcMq30Ujqa6\r\n" +"Val03Cr40VL0ZSYXnwTf/P65GtQTdyTOemYkUbMH9qRoxHmE7ZsPRpbXU4k30JWh\r\n" +"6VYy+7h5XmjrX+VdIiia6sMjy0mbtsxJb6DOo19ro4DfF5JmFZpXnBhsJGhMxiEM\r\n" +"94QEC5Tv6b0hWomFpOm3I5jOnktavCFQ1NsNHUspgQKBgQDUQm2+F06YdC6Pgt+9\r\n" +"COnd9rz2lB2TjGRIJvis6MW7EfQ7XHkH9y/sDGLzINBVn6DkaHmQZDrIg77Mey+H\r\n" +"LG0QL6+7WK7c1X/Zga6LKvkLlmcMWq6i1uu+Q3UODu7XcFh6f8kDThP+BubfUWpw\r\n" +"rCRq74gF1JzQISoKqmyW/AXMZQKBgQDNln0jzgh/ySWRjJbuh6GqPQunDQsh3K3I\r\n" +"4WDHK40NHFgIzPomKO+pqsOu3V/X81NARqfUyoIp/455YRheLHBUJg7maLfxrBq/\r\n" +"qQPEUwSAI6lheMz1WNWri65GvwBlVENajVuMh/xfmKVL1KVV+LXGO5L1UClWITCM\r\n" +"VSC0QT8XNwKBgQC7bYUWS+JdAIp0su36MDrCgzPM0HFlbpzGkZMYq9qeG3Z8TGWb\r\n" +"QQyR9UYSxjDwyqn5xr9BXyABG0SJr2UCiZosps8YMXEHE4d3eumzfdi4ALEx2YlH\r\n" +"xVwZf9uG9Gy21D9svBW102YX8+Q94diJcZgezTBhZaKqrf4/uMl2cUh1eQKBgQDB\r\n" +"heZYXOqdN0A5CUlOUbg5YutkHaAcCPpBvP33niRRchvgdOsIHsKzSL6ZDWPaCP+V\r\n" +"4qy7XsE2PYzk7yQcCeLXI1glRe/Y+3PWdIfKN4dmA6u+yBLO5QeFSqALkmISAEbC\r\n" +"p4vE9oD3j94RSqM0EUEy0ANfDk1K+UUU5FE7vKth8wKBgQCoKvPNfC3FmyhLK7EK\r\n" +"zgfIYAcoi52EFu6xQ9PvZHg60ptYvq1L+H6LR8cxYfcrPTt3aDbFf41RahPkokNh\r\n" +"2HDxiHd4HwWkAGiqZXCTA2znb+rnJ9fheI6g/Wb3p+oGeCFHMcdUcsl1qWBFDtax\r\n" +"ygS/tEFgy1z2dVMLbLKqEUscsA==\r\n" +"-----END PRIVATE KEY-----\r\n" +; diff --git a/test/mock/sipsrv.c b/test/mock/sipsrv.c new file mode 100644 index 0000000..0707962 --- /dev/null +++ b/test/mock/sipsrv.c @@ -0,0 +1,145 @@ +/** + * @file mock/sipsrv.c Mock SIP server + * + * Copyright (C) 2010 - 2015 Creytiv.com + */ +#include <string.h> +#include <re.h> +#include "../test.h" + + +#define DEBUG_MODULE "mock/sipsrv" +#define DEBUG_LEVEL 5 +#include <re_dbg.h> + + +#define LOCAL_PORT 0 +#define LOCAL_SECURE_PORT 0 + + +static bool sip_msg_handler(const struct sip_msg *msg, void *arg) +{ + struct sip_server *srv = arg; + int err; + +#if 0 + DEBUG_NOTICE("recv %r via %s\n", &msg->met, sip_transp_name(msg->tp)); +#endif + + if (0 == pl_strcmp(&msg->met, "REGISTER")) { + ++srv->n_register_req; + } + else { + DEBUG_NOTICE("method not handled (%r)\n", &msg->met); + return false; + } + + srv->tp_last = msg->tp; + + if (srv->terminate) + err = sip_reply(srv->sip, msg, 503, "Server Error"); + else + err = sip_reply(srv->sip, msg, 200, "OK"); + + if (err) { + DEBUG_WARNING("could not reply: %m\n", err); + } + +#if 1 + if (srv->terminate) + re_cancel(); +#endif + + return true; +} + + +static void destructor(void *arg) +{ + struct sip_server *srv = arg; + + srv->terminate = true; + + sip_close(srv->sip, false); + mem_deref(srv->sip); +} + + +int sip_server_alloc(struct sip_server **srvp) +{ + struct sip_server *srv; + struct sa laddr, laddrs; + struct tls *tls = NULL; + int err; + + if (!srvp) + return EINVAL; + + srv = mem_zalloc(sizeof *srv, destructor); + if (!srv) + return ENOMEM; + + err = sa_set_str(&laddr, "127.0.0.1", LOCAL_PORT); + err |= sa_set_str(&laddrs, "127.0.0.1", LOCAL_SECURE_PORT); + if (err) + goto out; + + err = sip_alloc(&srv->sip, NULL, 16, 16, 16, + "mock SIP server", NULL, NULL); + if (err) + goto out; + + err |= sip_transp_add(srv->sip, SIP_TRANSP_UDP, &laddr); + err |= sip_transp_add(srv->sip, SIP_TRANSP_TCP, &laddr); + if (err) + goto out; + +#ifdef USE_TLS + err = tls_alloc(&tls, TLS_METHOD_SSLV23, NULL, NULL); + if (err) + goto out; + + err = tls_set_certificate(tls, test_certificate, + strlen(test_certificate)); + if (err) + goto out; + + err |= sip_transp_add(srv->sip, SIP_TRANSP_TLS, &laddrs, tls); +#endif + if (err) + goto out; + + err = sip_listen(&srv->lsnr, srv->sip, true, sip_msg_handler, srv); + if (err) + goto out; + + out: + mem_deref(tls); + if (err) + mem_deref(srv); + else + *srvp = srv; + + return err; +} + + +int sip_server_uri(struct sip_server *srv, char *uri, size_t sz, + enum sip_transp tp) +{ + struct sa laddr; + int err; + + if (!srv || !uri || !sz) + return EINVAL; + + err = sip_transp_laddr(srv->sip, &laddr, tp, NULL); + if (err) + return err; + + if (re_snprintf(uri, sz, "sip:x:x@%J%s", + &laddr, sip_transp_param(tp)) < 0) + return ENOMEM; + + return 0; +} diff --git a/test/sip_server.c b/test/sip_server.c deleted file mode 100644 index 0e637de..0000000 --- a/test/sip_server.c +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file sip_server.c Selftest for Baresip core -- SIP Server - * - * Copyright (C) 2010 Creytiv.com - */ -#include <string.h> -#include <re.h> -#include <baresip.h> -#include "test.h" - - -static void udp_recv(const struct sa *src, struct mbuf *mb, void *arg) -{ - struct sip_server *srv = arg; - struct sip_msg *msg; - int err; - -#if 0 - re_printf("sip: %zu bytes from %J\n", mbuf_get_left(mb), src); - re_printf("%b\n", mb->buf, mb->end); -#endif - - err = sip_msg_decode(&msg, mb); - if (err) { - warning("selftest: sip_msg_decode: %m\n", err); - return; - } - - if (0 == pl_strcmp(&msg->met, "REGISTER")) - srv->got_register_req = true; - - msg->sock = mem_ref(srv->us); - msg->src = *src; - msg->dst = srv->laddr; - msg->tp = SIP_TRANSP_UDP; - - if (srv->terminate) - err = sip_reply(srv->sip, msg, 503, "Server Error"); - else - err = sip_reply(srv->sip, msg, 200, "OK"); - if (err) { - warning("selftest: could not reply: %m\n", err); - } - - mem_deref(msg); - - if (srv->terminate) - re_cancel(); -} - - -static void destructor(void *arg) -{ - struct sip_server *srv = arg; - - sip_close(srv->sip, false); - mem_deref(srv->sip); - - mem_deref(srv->us); -} - - -int sip_server_create(struct sip_server **srvp) -{ - struct sip_server *srv; - struct sa laddr_tp; - int err; - - srv = mem_zalloc(sizeof *srv, destructor); - if (!srv) - return ENOMEM; - - err = sa_set_str(&laddr_tp, "127.0.0.1", 0); - err |= sa_set_str(&srv->laddr, "127.0.0.1", 0); - if (err) - goto out; - - err = sip_alloc(&srv->sip, NULL, 16, 16, 16, - "dummy SIP registrar", NULL, NULL); - if (err) - goto out; - - err = sip_transp_add(srv->sip, SIP_TRANSP_UDP, &laddr_tp); - if (err) { - warning("failed to add sip transport (%m)\n", err); - goto out; - } - - err = udp_listen(&srv->us, &srv->laddr, udp_recv, srv); - if (err) { - warning("sip: udp_listen on '%J' failed (%d/%m)\n", - &srv->laddr, err, err); - goto out; - } - - err = udp_local_get(srv->us, &srv->laddr); - if (err) { - warning("sip: udp_local_get\n"); - goto out; - } - -#if 0 - re_printf("sip: listen on %J\n", &srv->laddr); -#endif - - out: - if (err) - mem_deref(srv); - else - *srvp = srv; - - return err; -} diff --git a/test/srcs.mk b/test/srcs.mk index df16f8b..1caafbb 100644 --- a/test/srcs.mk +++ b/test/srcs.mk @@ -4,10 +4,24 @@ # Copyright (C) 2010 Creytiv.com # + +# +# Test-cases: +# TEST_SRCS += cmd.c TEST_SRCS += ua.c +TEST_SRCS += cplusplus.c + + +# +# Mocks +# +TEST_SRCS += mock/sipsrv.c +ifneq ($(USE_TLS),) +TEST_SRCS += mock/cert.c +endif + -TEST_SRCS += sip_server.c TEST_SRCS += test.c TEST_SRCS += main.c diff --git a/test/test.h b/test/test.h index 20807b6..61ddd27 100644 --- a/test/test.h +++ b/test/test.h @@ -33,21 +33,43 @@ goto out; \ } +#define TEST_ERR(err) \ + if ((err)) { \ + (void)re_fprintf(stderr, "\n"); \ + warning("TEST_ERR: %s:%u:" \ + " (%m)\n", \ + __FILE__, __LINE__, \ + (err)); \ + goto out; \ + } + /* helpers */ int re_main_timeout(uint32_t timeout); + +#ifdef USE_TLS +extern const char test_certificate[]; +#endif + + +/* + * SIP Server + */ + struct sip_server { - struct sa laddr; - struct udp_sock *us; struct sip *sip; - - bool got_register_req; + struct sip_lsnr *lsnr; bool terminate; + + unsigned n_register_req; + enum sip_transp tp_last; }; -int sip_server_create(struct sip_server **srvp); +int sip_server_alloc(struct sip_server **srvp); +int sip_server_uri(struct sip_server *srv, char *uri, size_t sz, + enum sip_transp tp); /* test cases */ @@ -56,3 +78,14 @@ int test_cmd(void); int test_ua_alloc(void); int test_uag_find_param(void); int test_ua_register(void); + + +#ifdef __cplusplus +extern "C" { +#endif + +int test_cplusplus(void); + +#ifdef __cplusplus +} +#endif @@ -50,7 +50,7 @@ static void ua_event_handler(struct ua *ua, enum ua_event ev, } -int test_ua_register(void) +static int reg(enum sip_transp tp) { struct test t; char aor[256]; @@ -58,17 +58,17 @@ int test_ua_register(void) memset(&t, 0, sizeof t); - err = sip_server_create(&t.srv); + err = sip_server_alloc(&t.srv); if (err) { warning("failed to create sip server (%d/%m)\n", err, err); goto out; } - re_snprintf(aor, sizeof(aor), "sip:x:x@%J", &t.srv->laddr); + err = sip_server_uri(t.srv, aor, sizeof(aor), tp); + TEST_ERR(err); err = ua_alloc(&t.ua, aor); - if (err) - goto out; + TEST_ERR(err); err = uag_event_register(ua_event_handler, &t); if (err) @@ -82,7 +82,8 @@ int test_ua_register(void) if (t.err) err = t.err; - ASSERT_TRUE(t.srv->got_register_req); + ASSERT_TRUE(t.srv->n_register_req > 0); + ASSERT_EQ(tp, t.srv->tp_last); ASSERT_TRUE(t.got_register_ok); out: @@ -97,6 +98,20 @@ int test_ua_register(void) } +int test_ua_register(void) +{ + int err = 0; + + err = reg(SIP_TRANSP_UDP); +#if 0 + err |= reg(SIP_TRANSP_TCP); + err |= reg(SIP_TRANSP_TLS); +#endif + + return err; +} + + int test_ua_alloc(void) { struct ua *ua; |