diff --git a/src/Makefile.am b/src/Makefile.am
index 5fb445d..d71d4f7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,9 +3,10 @@ bin_PROGRAMS = osmo-sip-connector
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(SOFIASIP_CFLAGS)
noinst_HEADERS = \
- evpoll.h vty.h mncc_protocol.h app.h mncc.h sip.h call.h
+ evpoll.h vty.h mncc_protocol.h app.h mncc.h sip.h call.h sdp.h
osmo_sip_connector_SOURCES = \
+ sdp.c \
app.c \
call.c \
sip.c \
diff --git a/src/sdp.c b/src/sdp.c
new file mode 100644
index 0000000..78c314f
--- /dev/null
+++ b/src/sdp.c
@@ -0,0 +1,161 @@
+/*
+ * (C) 2016 by Holger Hans Peter Freyther
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "sdp.h"
+#include "call.h"
+#include "logging.h"
+
+#include
+
+#include
+#include
+
+#include
+
+/*
+ * We want to decide on the audio codec later but we need to see
+ * if it is even including some of the supported ones.
+ */
+bool sdp_screen_sdp(const sip_t *sip)
+{
+ const char *sdp_data;
+ sdp_parser_t *parser;
+ sdp_session_t *sdp;
+ sdp_media_t *media;
+
+ if (!sip->sip_payload || !sip->sip_payload->pl_data) {
+ LOGP(DSIP, LOGL_ERROR, "No SDP file\n");
+ return false;
+ }
+
+ sdp_data = sip->sip_payload->pl_data;
+ parser = sdp_parse(NULL, sdp_data, strlen(sdp_data), 0);
+ if (!parser) {
+ LOGP(DSIP, LOGL_ERROR, "Failed to parse SDP\n");
+ return false;
+ }
+
+ sdp = sdp_session(parser);
+ if (!sdp) {
+ LOGP(DSIP, LOGL_ERROR, "No sdp session\n");
+ sdp_parser_free(parser);
+ return false;
+ }
+
+ for (media = sdp->sdp_media; media; media = media->m_next) {
+ sdp_rtpmap_t *map;
+
+ if (media->m_proto != sdp_proto_rtp)
+ continue;
+ if (media->m_type != sdp_media_audio)
+ continue;
+
+ for (map = media->m_rtpmaps; map; map = map->rm_next) {
+ if (strcasecmp(map->rm_encoding, "GSM") == 0)
+ goto success;
+ if (strcasecmp(map->rm_encoding, "GSM-EFR") == 0)
+ goto success;
+ if (strcasecmp(map->rm_encoding, "GSM-HR-08") == 0)
+ goto success;
+ if (strcasecmp(map->rm_encoding, "AMR") == 0)
+ goto success;
+ }
+ }
+
+ sdp_parser_free(parser);
+ return false;
+
+success:
+ sdp_parser_free(parser);
+ return true;
+}
+
+bool sdp_extract_sdp(struct sip_call_leg *leg, const sip_t *sip)
+{
+ sdp_connection_t *conn;
+ sdp_session_t *sdp;
+ sdp_parser_t *parser;
+ sdp_media_t *media;
+ const char *sdp_data;
+ bool found_conn = false, found_map = false;
+
+ if (!sip->sip_payload || !sip->sip_payload->pl_data) {
+ LOGP(DSIP, LOGL_ERROR, "leg(%p) but no SDP file\n", leg);
+ return false;
+ }
+
+ sdp_data = sip->sip_payload->pl_data;
+ parser = sdp_parse(NULL, sdp_data, strlen(sdp_data), 0);
+ if (!parser) {
+ LOGP(DSIP, LOGL_ERROR, "leg(%p) failed to parse SDP\n",
+ leg);
+ return false;
+ }
+
+ sdp = sdp_session(parser);
+ if (!sdp) {
+ LOGP(DSIP, LOGL_ERROR, "leg(%p) no sdp session\n", leg);
+ sdp_parser_free(parser);
+ return false;
+ }
+
+ for (conn = sdp->sdp_connection; conn; conn = conn->c_next) {
+ struct in_addr addr;
+
+ if (conn->c_addrtype != sdp_addr_ip4)
+ continue;
+ inet_aton(conn->c_address, &addr);
+ leg->base.ip = addr.s_addr;
+ found_conn = true;
+ break;
+ }
+
+ for (media = sdp->sdp_media; media; media = media->m_next) {
+ sdp_rtpmap_t *map;
+
+ if (media->m_proto != sdp_proto_rtp)
+ continue;
+ if (media->m_type != sdp_media_audio)
+ continue;
+
+ for (map = media->m_rtpmaps; map; map = map->rm_next) {
+ if (strcasecmp(map->rm_encoding, leg->wanted_codec) != 0)
+ continue;
+
+ leg->base.port = media->m_port;
+ leg->base.payload_type = map->rm_pt;
+ found_map = true;
+ break;
+ }
+
+ if (found_map)
+ break;
+ }
+
+ if (!found_conn || !found_map) {
+ LOGP(DSIP, LOGL_ERROR, "leg(%p) did not find %d/%d\n",
+ leg, found_conn, found_map);
+ sdp_parser_free(parser);
+ return false;
+ }
+
+ sdp_parser_free(parser);
+ return true;
+}
diff --git a/src/sdp.h b/src/sdp.h
new file mode 100644
index 0000000..d19d7b5
--- /dev/null
+++ b/src/sdp.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include
+
+#include
+
+struct sip_call_leg;
+
+bool sdp_screen_sdp(const sip_t *sip);
+bool sdp_extract_sdp(struct sip_call_leg *leg, const sip_t *sip);
diff --git a/src/sip.c b/src/sip.c
index 78a3d0c..32a9264 100644
--- a/src/sip.c
+++ b/src/sip.c
@@ -22,10 +22,10 @@
#include "app.h"
#include "call.h"
#include "logging.h"
+#include "sdp.h"
#include
-#include
#include
#include
@@ -34,137 +34,6 @@
extern void *tall_mncc_ctx;
-/*
- * We want to decide on the audio codec later but we need to see
- * if it is even including some of the supported ones.
- */
-static bool screen_sdp(const sip_t *sip)
-{
- const char *sdp_data;
- sdp_parser_t *parser;
- sdp_session_t *sdp;
- sdp_media_t *media;
-
- if (!sip->sip_payload || !sip->sip_payload->pl_data) {
- LOGP(DSIP, LOGL_ERROR, "No SDP file\n");
- return false;
- }
-
- sdp_data = sip->sip_payload->pl_data;
- parser = sdp_parse(NULL, sdp_data, strlen(sdp_data), 0);
- if (!parser) {
- LOGP(DSIP, LOGL_ERROR, "Failed to parse SDP\n");
- return false;
- }
-
- sdp = sdp_session(parser);
- if (!sdp) {
- LOGP(DSIP, LOGL_ERROR, "No sdp session\n");
- sdp_parser_free(parser);
- return false;
- }
-
- for (media = sdp->sdp_media; media; media = media->m_next) {
- sdp_rtpmap_t *map;
-
- if (media->m_proto != sdp_proto_rtp)
- continue;
- if (media->m_type != sdp_media_audio)
- continue;
-
- for (map = media->m_rtpmaps; map; map = map->rm_next) {
- if (strcasecmp(map->rm_encoding, "GSM") == 0)
- goto success;
- if (strcasecmp(map->rm_encoding, "GSM-EFR") == 0)
- goto success;
- if (strcasecmp(map->rm_encoding, "GSM-HR-08") == 0)
- goto success;
- if (strcasecmp(map->rm_encoding, "AMR") == 0)
- goto success;
- }
- }
-
- sdp_parser_free(parser);
- return false;
-
-success:
- sdp_parser_free(parser);
- return true;
-}
-
-static bool extract_sdp(struct sip_call_leg *leg, const sip_t *sip)
-{
- sdp_connection_t *conn;
- sdp_session_t *sdp;
- sdp_parser_t *parser;
- sdp_media_t *media;
- const char *sdp_data;
- bool found_conn = false, found_map = false;
-
- if (!sip->sip_payload || !sip->sip_payload->pl_data) {
- LOGP(DSIP, LOGL_ERROR, "leg(%p) but no SDP file\n", leg);
- return false;
- }
-
- sdp_data = sip->sip_payload->pl_data;
- parser = sdp_parse(NULL, sdp_data, strlen(sdp_data), 0);
- if (!parser) {
- LOGP(DSIP, LOGL_ERROR, "leg(%p) failed to parse SDP\n",
- leg);
- return false;
- }
-
- sdp = sdp_session(parser);
- if (!sdp) {
- LOGP(DSIP, LOGL_ERROR, "leg(%p) no sdp session\n", leg);
- sdp_parser_free(parser);
- return false;
- }
-
- for (conn = sdp->sdp_connection; conn; conn = conn->c_next) {
- struct in_addr addr;
-
- if (conn->c_addrtype != sdp_addr_ip4)
- continue;
- inet_aton(conn->c_address, &addr);
- leg->base.ip = addr.s_addr;
- found_conn = true;
- break;
- }
-
- for (media = sdp->sdp_media; media; media = media->m_next) {
- sdp_rtpmap_t *map;
-
- if (media->m_proto != sdp_proto_rtp)
- continue;
- if (media->m_type != sdp_media_audio)
- continue;
-
- for (map = media->m_rtpmaps; map; map = map->rm_next) {
- if (strcasecmp(map->rm_encoding, leg->wanted_codec) != 0)
- continue;
-
- leg->base.port = media->m_port;
- leg->base.payload_type = map->rm_pt;
- found_map = true;
- break;
- }
-
- if (found_map)
- break;
- }
-
- if (!found_conn || !found_map) {
- LOGP(DSIP, LOGL_ERROR, "leg(%p) did not find %d/%d\n",
- leg, found_conn, found_map);
- sdp_parser_free(parser);
- return false;
- }
-
- sdp_parser_free(parser);
- return true;
-}
-
static void call_progress(struct sip_call_leg *leg, const sip_t *sip)
{
struct call_leg *other = call_leg_other(&leg->base);
@@ -187,7 +56,7 @@ static void call_connect(struct sip_call_leg *leg, const sip_t *sip)
return;
}
- if (!extract_sdp(leg, sip)) {
+ if (!sdp_extract_sdp(leg, sip)) {
LOGP(DSIP, LOGL_ERROR, "leg(%p) incompatible audio, releasing\n", leg);
nua_cancel(leg->nua_handle, TAG_END());
other->release_call(other);
@@ -205,7 +74,7 @@ static void new_call(struct sip_agent *agent, nua_handle_t *nh,
{
LOGP(DSIP, LOGL_DEBUG, "Incoming call handle(%p)\n", nh);
- if (!screen_sdp(sip)) {
+ if (!sdp_screen_sdp(sip)) {
LOGP(DSIP, LOGL_ERROR, "No supported codec.\n");
nua_respond(nh, SIP_406_NOT_ACCEPTABLE, TAG_END());
nua_handle_destroy(nh);