diff libsip/sdp_parse.c @ 53:2423f3aac4ce

libsip: SDP parsing implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 08 Sep 2022 10:45:50 -0800
parents
children bea761629c5b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libsip/sdp_parse.c	Thu Sep 08 10:45:50 2022 -0800
@@ -0,0 +1,104 @@
+/*
+ * Here we implement the function that parses received SDP descriptions.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "../include/tmgw_const.h"
+#include "sdp.h"
+
+parse_incoming_sdp(body, bodylen, dist)
+	char *body;
+	unsigned bodylen;
+	struct sdp_parse *dist;
+{
+	char *cp, *endp;
+	int got_c = 0, got_m = 0, prefer_pcma = 0;
+	unsigned codec;
+
+	cp = body;
+	endp = body + bodylen;
+	while (cp < endp) {
+		if (!islower(cp[0]) || cp[1] != '=')
+			return(-1);
+		switch (cp[0]) {
+		case 'c':
+			if (got_c)
+				return(-1);
+			got_c = 1;
+			if (strncmp(cp + 2, "IN IP4 ", 7))
+				return(-1);
+			cp += 9;
+			dist->ip_addr.s_addr = inet_addr(cp);
+			if (dist->ip_addr.s_addr == INADDR_NONE)
+				return(-1);
+			break;
+		case 'm':
+			if (got_m)
+				return(-1);
+			got_m = 1;
+			if (strncmp(cp + 2, "audio ", 6))
+				return(-1);
+			cp += 8;
+			if (!isdigit(*cp))
+				return(-1);
+			dist->audio_port = strtoul(cp, &cp, 10);
+			if (!strncmp(cp, " RTP/AVP", 8))
+				return(-1);
+			cp += 8;
+			dist->codec_mask = 0;
+			for (;;) {
+				if (*cp == '\r' || *cp == '\n')
+					break;
+				if (*cp++ != ' ')
+					return(-1);
+				codec = strtoul(cp, &cp, 10);
+				switch (codec) {
+				case PSTN_CODEC_PCMU:
+					dist->codec_mask |= SDP_CODEC_MASK_PCMU;
+					break;
+				case PSTN_CODEC_PCMA:
+					if (!dist->codec_mask)
+						prefer_pcma = 1;
+					dist->codec_mask |= SDP_CODEC_MASK_PCMA;
+					break;
+				}
+			}
+			if (dist->codec_mask == SDP_CODEC_MASK_BOTH &&
+			    prefer_pcma)
+				dist->codec_mask |= SDP_CODEC_MASK_PCMA_PREF;
+			break;
+		default:
+			cp += 2;
+		}
+		for (;;) {
+			if (cp >= endp)
+				return(-1);
+			if (!*cp)
+				return(-1);
+			if (*cp == '\n') {
+				cp++;
+				break;
+			}
+			if (*cp == '\r') {
+				cp++;
+				if (cp >= endp)
+					return(-1);
+				if (*cp++ != '\n')
+					return(-1);
+				break;
+			}
+			cp++;
+		}
+	}
+	if (got_c && got_m)
+		return(0);
+	else
+		return(-1);
+}