Basic SDP parser for app_python

Python script to be used from kamailio.cfg via app_python module (cached here from mailing list).

# -*- coding: utf-8 -*-
 
import Router
 
class OriginType:
    username = None
    sess_id = None
    sess_ver = None
    nettype = None
    addrtype = None
    unicast_addr = None
    RAW_STRING = None
 
# WARNING:
# Maybe in the format: <base multicast address>[/<ttl>]/<number of addresses>
# Examples:
#	c=IN IP4 224.2.36.41/127
#	c=IN IP4 224.2.36.42/127
#	c=IN IP4 224.2.36.43/127
#	c=IN IP4 224.2.1.1/127/3
#	c=IN IP6 FF15::101/3
class ConnectionType:
    nettype = None
    addrtype = None
    connection_addr = None
    RAW_STRING = None
 
# Formats:
#	<media> <port> <proto> <fmt> ...
#	<media> <port>/<number of ports> <proto> <fmt> ...
class MediaType:
    media = None
    port = None
    proto = None
    fmt = None
    args = ""
    RAW_STRING = None
 
class SDPBodyMessage:
    origin = OriginType()			# o=root 2135137275 2135137277 IN IP4 192.168.254.54
    session_name = None				# s=Asterisk PBX 1.8.7.1
    conn_data = [] # of ConnectionType()	# c=IN IP4 192.168.254.54
    media = [] # of MediaType()			# m=audio 17406 RTP/AVP 0 101
 
 
class SdpParser:
 
    def __init__(self):
	pass
 
    def __del__(self):
	pass
 
    def child_init(self, y):
	return 0
 
 
    def ParseSDP(self, msg, args):
 
 
	sdpBody = SDPBodyMessage()
	sdpBody.origin = OriginType()
	sdpBody.session_name = None
	sdpBody.conn_data = []
	sdpBody.media = []
 
	if args.lower().find("application/sdp") >= 0:
 
	    SIPMSGLines = []
	    SDPBodyLines = []
 
	    emptyLineCounter = 0
	    for line in args.splitlines():
		if line.strip() == "":
		    emptyLineCounter += 1
		    continue
 
		if emptyLineCounter == 0:
		    SIPMSGLines.append(line)
		else:
		    SDPBodyLines.append(line)
 
	    for sdpLine in SDPBodyLines:
		sdpType = sdpLine.split("=")[0].lower().strip()
		sdpPartLine = sdpLine[2:]
		sdpParts = sdpPartLine.split()
 
		if sdpType == "o":
		    oType = OriginType()
		    try:
			oType.username, oType.sess_id, oType.sess_ver, oType.nettype, oType.addrtype, oType.unicast_addr = sdpParts
			oType.RAW_STRING = sdpPartLine.strip()
			sdpBody.origin = oType
		    except:
			pass
		    continue
 
		if sdpType == "s":
		    sdpBody.session_name = sdpPartLine
		    continue
 
		if sdpType == "c":
		    cType = ConnectionType()
		    cType.nettype, cType.addrtype, cType.connection_addr = sdpParts
		    cType.RAW_STRING = sdpPartLine.strip()
		    sdpBody.conn_data.append(cType)
		    continue
 
		if sdpType == "m":
		    mType = MediaType()
		    mType.media = sdpParts[0]
		    mType.port = sdpParts[1]
		    mType.proto = sdpParts[2]
		    mType.fmt = sdpParts[3]
		    mType.args = " ".join(sdpParts[4:]).strip()
		    mType.RAW_STRING = sdpPartLine.strip()
		    sdpBody.media.append(mType)
		    continue
 
 
 
	    msg.call_function("append_hf", "X-Mangled--Connection-From: %s:%d\r\n" % (msg.src_address[0], msg.src_address[1]))
	    msg.call_function("append_hf", "X-Mangled--Contact: %s\r\n" % msg.getHeader("Contact"))
	    if sdpBody.origin.RAW_STRING is not None:
	        msg.call_function("append_hf", "X-Mangled--Origin: o=%s\r\n" % sdpBody.origin.RAW_STRING)
	    if sdpBody.session_name is not None:
	        msg.call_function("append_hf", "X-Mangled--Session-Name: s=%s\r\n" % sdpBody.session_name)
	    CLcount=0
	    for CLine in sdpBody.conn_data:
		if CLine.RAW_STRING is not None:
		    msg.call_function("append_hf", "X-Mangled--Connection-Data-%d: c=%s\r\n" % (CLcount, CLine.RAW_STRING))
		CLcount += 1
 
	    CMcount=0
	    for CMline in sdpBody.media:
		if CMline.RAW_STRING is not None:
		    msg.call_function("append_hf", "X-Mangled--Media-Data-%d: m=%s\r\n" % (CMcount, CMline.RAW_STRING))
		CMcount += 1
 
        return 1
 
def mod_init():
    return SdpParser()

In kamailio.cfg:

loadmodule "app_python.so"
modparam("app_python", "script_name", "/opt/kamailio/python/sdp.py")
modparam("app_python", "mod_init_function", "mod_init")
modparam("app_python", "child_init_method", "child_init") 

and put in a routing block:

python_exec("ParseSDP", $mb);