[mgcp] Add a simple mgcp gateway used for the BSC
The python script is a simple call-agent driving the
client. Currently it is sending a AuditEndpoint message
and is printing the result.
The bsc_mgcp.c is a standalone process that will implement
a MGCP Gateway for the MSC. On call handling the Call-Agent
will ask the Gateway to "CreateConnection" and then this
gateway needs to communicate with OpenBSC.
Currently CreateConnection,ModifiyConnection,DeleteConnection
and Endpoint auditing is implemented.
[mgcp] Send RSIP on start and on first receive of any message
Ignore the first request and send a RSIP. We do that because
we might tunnel UDP through some other things and have no direct
way to connect to the call-agent.
Also the transaction is not checked and we ignore the response
from the call-agent, actually we print the '200 ' or any other
value as unhandled...
[mgcp] Print the MGCP command next to the response code
This allows to see which commands were sent by the server
mgcp: Terminate it with a new line
[mgcp] Make number of endpoints static...
For now this is fixed to the number of endpoints as of the GSM
specification...
[mgcp] The endpoint names seem to be base 16... use strtoul to parse
Use strtoul to parse the base 16 number from the mgw string.
[mgcp] Log the endpoints as hex numbers...
[mgcp] Only send the RSIP on the first incoming message..
Remove call_agent option (also remove the number from the getopt
call).
[mgcp] Start couting at 1 for the mgcp
[mgcp] Slight attempt to improve the grammar of the strings
[mgcp] Share validation routines between DLCX and MDCX
[mgcp] Remove help for dead config options
[mgcp] Specify a different IN addr in the SDP records
In case of NAT traversal be able to listen on a given
interface (like 127.0.0.1) but claim to receive data
at the beginning of the tunnel.
[mgcp] Fix the static copy of the SDP file
WIP verify out factoring broken..
[mgcp] Introduce VTY to the mgcp for config file parsing...
Parse the MGCP config file via the VTY framework.
[mgcp] Handle SDP parameters through VTY..
Currently the payload type, name and rate can be specified
in the config file.
[mgcp] Add an option to bind all rtp ports early
This can be useful for testing and in deployment to make sure
no runtime resource limit can be hit.
[mgcp] Add some API doc comment
[mgcp] Convert the packets of the example server to ascii
This will allow to easily patch the call id... to run the
server in a loop and make it work with the mediagateway
[mgcp] Assign CI_UNUSED... to be more obvious...
[mgcp] Use DEBUG and not DEBUGPC and specially not printf
Improve the logging a bit in the mgcp
[mgcp] Change the fake server to change the call id
This assume the call-agent will just increment the id
as well.... this is true for our implementation
[mgcp] Generate the transaction id dynamically..
This way wireshark will be more happy about it...
[mgcp] Recognize responses from the network..
This is just recognizing the response code and
then is doing nothing with it. Also change the
script to generate response messages...
[mgcp] Improve debug messages for CRCX/MDCX..
Log on which ports the media gateway is listening
and where the other (server) gateway is located
diff --git a/openbsc/contrib/mgcp_server.py b/openbsc/contrib/mgcp_server.py
new file mode 100755
index 0000000..cf3ef38
--- /dev/null
+++ b/openbsc/contrib/mgcp_server.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# Simple server for mgcp... send audit, receive response..
+
+import socket, time
+
+MGCP_GATEWAY_PORT = 2427
+MGCP_CALLAGENT_PORT = 2727
+
+rsip_resp = """200 321321332\r\n"""
+audit_packet = """AUEP %d 13@mgw MGCP 1.0\r\n"""
+crcx_packet = """CRCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n"""
+dlcx_packet = """DLCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\n"""
+mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 4400 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
+
+def hexdump(src, length=8):
+ """Recipe is from http://code.activestate.com/recipes/142812/"""
+ result = []
+ digits = 4 if isinstance(src, unicode) else 2
+ for i in xrange(0, len(src), length):
+ s = src[i:i+length]
+ hexa = b' '.join(["%0*X" % (digits, ord(x)) for x in s])
+ text = b''.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s])
+ result.append( b"%04X %-*s %s" % (i, length*(digits + 1), hexa, text) )
+ return b'\n'.join(result)
+
+server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT))
+server_socket.setblocking(0)
+
+
+def send_receive(packet):
+ server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT))
+ try:
+ data, addr = server_socket.recvfrom(4096)
+ print hexdump(data), addr
+ except socket.error:
+ pass
+
+def generate_tid():
+ import random
+ return random.randint(0, 65123)
+
+
+
+i = 1
+while True:
+ send_receive(rsip_resp)
+ send_receive(audit_packet)
+ send_receive(crcx_packet % generate_tid() )
+ send_receive(mdcx_packet % (generate_tid(), i))
+ send_receive(dlcx_packet % (generate_tid(), i))
+ i = i + 1
+
+ time.sleep(3)