| module MGCP_Templates { |
| |
| import from MGCP_Types all; |
| import from SDP_Types all; |
| |
| function f_mgcp_par_append(inout template MgcpParameterList list, template MgcpParameter par) { |
| var integer len := lengthof(list); |
| list[len] := par; |
| } |
| |
| /* 3.2.2.6 Connection Mode (sendonly, recvonly, sendrecv, confrnce, inactive, loopback, |
| * conttest, netwloop, netwtest) */ |
| template MgcpParameter t_MgcpParConnMode(template MgcpConnectionMode mode) := { "M", mode }; |
| |
| /* 3.2.2.2 CallId: maximum 32 hex chars */ |
| template MgcpParameter ts_MgcpParCallId(MgcpCallId cid) := { |
| code := "C", |
| val := hex2str(cid) |
| }; |
| |
| /* 3.2.2.18 RequestIdentifier: Maximum 32 hex chars */ |
| template MgcpParameter ts_MgcpParReqId(MgcpRequestId rid) := { |
| code := "X", |
| val := hex2str(rid) |
| }; |
| |
| /* 3.2.2.10: LocalConnectionOptions (codec, packetization, bandwidth, ToS, eco, gain, silence, ...) */ |
| template MgcpParameter t_MgcpParLocConnOpt(template charstring lco) := { "L", lco }; |
| |
| /* 3.2.2.5: ConnectionId: maximum 32 hex chars */ |
| template MgcpParameter ts_MgcpParConnectionId(MgcpConnectionId cid) := { |
| code := "I", |
| val := hex2str(cid) |
| }; |
| |
| /* osmo-bsc_mgcp implements L/C/M/X only, osmo-mgw adds 'I' */ |
| /* SDP: osmo-bsc_mgcp implements Tx of v,o,s,c,t,m,a */ |
| |
| template MgcpResponse tr_MgcpResp_Err(template MgcpResponseCode code) := { |
| line := { |
| code := code, |
| trans_id := ?, |
| string := ? |
| }, |
| params := {}, |
| sdp := omit |
| } |
| |
| template MgcpCommandLine t_MgcpCmdLine(template charstring verb, template MgcpTransId trans_id, template charstring ep) := { |
| verb := verb, |
| trans_id := trans_id, |
| ep := ep, |
| ver := "1.0" |
| }; |
| |
| template MgcpCommand ts_CRCX(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, template SDP_Message sdp := omit) := { |
| line := t_MgcpCmdLine("CRCX", trans_id, ep), |
| params := { |
| t_MgcpParConnMode(mode), |
| ts_MgcpParCallId(call_id), |
| //t_MgcpParReqId(omit), |
| t_MgcpParLocConnOpt("p:20, a:PCMU") |
| }, |
| sdp := sdp |
| } |
| |
| template MgcpResponse tr_CRCX_ACK := { |
| line := { |
| code := "200", |
| trans_id := ?, |
| string := "OK" |
| }, |
| params:= { { "I", ? }, *}, |
| sdp := ? |
| } |
| |
| template MgcpCommand ts_MDCX(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := { |
| line := t_MgcpCmdLine("MDCX", trans_id, ep), |
| params := { |
| t_MgcpParConnMode(mode), |
| ts_MgcpParCallId(call_id), |
| ts_MgcpParConnectionId(conn_id), |
| //t_MgcpParReqId(omit), |
| t_MgcpParLocConnOpt("p:20, a:PCMU") |
| }, |
| sdp := sdp |
| } |
| |
| /* have a function that generates a template, rather than a template in order to handle |
| * optional parameters */ |
| function ts_DLCX(MgcpTransId trans_id, charstring ep, template MgcpCallId call_id := omit, |
| template MgcpConnectionId conn_id := omit) return template MgcpCommand { |
| var template MgcpCommand cmd; |
| cmd.line := t_MgcpCmdLine("DLCX", trans_id, ep); |
| cmd.params := {}; |
| cmd.sdp := omit; |
| if (isvalue(call_id)) { |
| f_mgcp_par_append(cmd.params, ts_MgcpParCallId(valueof(call_id))); |
| if (isvalue(conn_id)) { |
| f_mgcp_par_append(cmd.params, ts_MgcpParConnectionId(valueof(conn_id))); |
| } |
| } |
| return cmd; |
| } |
| |
| template MgcpResponse tr_DLCX_ACK := { |
| line := { |
| code := "200", |
| trans_id := ?, |
| string := "OK" |
| }, |
| params:= *, |
| sdp := * |
| } |
| |
| /* SDP Templates */ |
| template SDP_Origin ts_SDP_origin(charstring addr, charstring session_id, |
| charstring session_version := "1", |
| charstring addr_type := "IP4", |
| charstring user_name := "-") := { |
| user_name := user_name, |
| session_id := session_id, |
| session_version := session_version, |
| net_type := "IN", |
| addr_type := addr_type, |
| addr := addr |
| } |
| |
| template SDP_connection ts_SDP_connection_IP(charstring addr, charstring addr_type := "IP4", |
| template integer ttl := omit, |
| template integer num_of_addr := omit) :={ |
| net_type := "IN", |
| addr_type := addr_type, |
| conn_addr := { |
| addr := addr, |
| ttl := ttl, |
| num_of_addr := num_of_addr |
| } |
| } |
| |
| template SDP_time ts_SDP_time(charstring beg, charstring end) := { |
| time_field := { |
| start_time := beg, |
| stop_time := end |
| }, |
| time_repeat := omit |
| } |
| |
| template SDP_media_desc ts_SDP_media_desc(integer port_number, SDP_fmt_list fmts, |
| SDP_attribute_list attributes) := { |
| media_field := { |
| media := "audio", |
| ports := { |
| port_number := port_number, |
| num_of_ports := omit |
| }, |
| transport := "RTP/AVP", |
| fmts := fmts |
| }, |
| information := omit, |
| connections := omit, |
| bandwidth := omit, |
| key := omit, |
| attributes := attributes |
| } |
| |
| /* master template for generating SDP based in template arguments */ |
| template SDP_Message ts_SDP(charstring local_addr, charstring remote_addr, |
| charstring session_id, charstring session_version, |
| integer rtp_port, SDP_fmt_list fmts, |
| SDP_attribute_list attributes) := { |
| protocol_version := 0, |
| origin := ts_SDP_origin(local_addr, session_id, session_version), |
| session_name := "-", |
| information := omit, |
| uri := omit, |
| emails := omit, |
| phone_numbers := omit, |
| connection := ts_SDP_connection_IP(remote_addr), |
| bandwidth := omit, |
| times := { ts_SDP_time("0","0") }, |
| timezone_adjustments := omit, |
| key := omit, |
| attributes := omit, |
| media_list := { ts_SDP_media_desc(rtp_port, fmts, attributes) } |
| } |
| |
| template SDP_attribute ts_SDP_rtpmap(integer fmt, charstring val) := { |
| rtpmap := { |
| attr_value := int2str(fmt) & " " & val |
| } |
| } |
| template SDP_attribute ts_SDP_ptime(integer p) := { |
| ptime := { |
| attr_value := int2str(p) |
| } |
| } |
| |
| function f_MgcpResp_extract_conn_id(MgcpResponse resp) return MgcpConnectionId { |
| var integer i; |
| for (i := 0; i < lengthof(resp.params); i := i + 1) { |
| var MgcpParameter par := resp.params[i]; |
| if (par.code == "I") { |
| return str2hex(par.val); |
| } |
| } |
| setverdict(fail); |
| return '00000000'H; |
| } |
| |
| function f_mgcp_alloc_tid() return MgcpTransId { |
| return int2str(float2int(rnd()*2147483647.0)); |
| } |
| |
| function f_mgcp_alloc_call_id() return MgcpCallId { |
| return int2hex(float2int(rnd()*2147483647.0), 8); |
| } |
| |
| function f_mgcp_alloc_conn_id() return MgcpConnectionId { |
| return int2hex(float2int(rnd()*2147483647.0), 8); |
| } |
| |
| } |