mncc: Support IPv6 addresses (new version mncc 7)
Apparently commit 06b859ca31
forgot to
bump the MNCC_SOCK_VERSION field from 5 to 6.
Change-Id: I5448ff931ec33f24f4837a51376f1703fe97683b
This commit is contained in:
parent
28aa466dd9
commit
563b3d013b
|
@ -38,7 +38,7 @@ import from MNCC_Types all;
|
|||
import from UD_Types all;
|
||||
|
||||
modulepar {
|
||||
int mp_mncc_version := 6;
|
||||
int mp_mncc_version := 7;
|
||||
}
|
||||
|
||||
/* General "base class" component definition, of which specific implementations
|
||||
|
@ -266,6 +266,11 @@ type record MnccOps {
|
|||
function main(MnccOps ops, charstring id, charstring sock, boolean role_server := false)
|
||||
runs on MNCC_Emulation_CT {
|
||||
|
||||
if (not set_MNCC_version(mp_mncc_version)) {
|
||||
setverdict(fail, "Failed configuring MNCC enc/dec to version ", mp_mncc_version);
|
||||
return;
|
||||
}
|
||||
|
||||
if (role_server) {
|
||||
f_listen(sock);
|
||||
MNCC.send(t_SD_MNCC(g_mncc_ud_id, ts_MNCC_HELLO(version := mp_mncc_version)));
|
||||
|
|
|
@ -5,6 +5,16 @@
|
|||
|
||||
namespace MNCC__Types {
|
||||
|
||||
static int mncc_sock_version = MNCC_SOCK_VERSION;
|
||||
|
||||
BOOLEAN set__MNCC__version(INTEGER const& version)
|
||||
{
|
||||
if (version != 6 && version != 7)
|
||||
return false;
|
||||
mncc_sock_version = version;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void enc_bcap(struct gsm_mncc_bearer_cap *out, const MNCC__bearer__cap& in)
|
||||
{
|
||||
out->transfer = in.transfer();
|
||||
|
@ -76,6 +86,7 @@ OCTETSTRING enc__MNCC__PDU(const MNCC__PDU& in)
|
|||
{
|
||||
struct gsm_mncc mncc;
|
||||
OCTETSTRING ret_val;
|
||||
TTCN_Buffer ttcn_buffer;
|
||||
|
||||
memset(&mncc, 0, sizeof(mncc));
|
||||
mncc.msg_type = in.msg__type();
|
||||
|
@ -184,16 +195,47 @@ OCTETSTRING enc__MNCC__PDU(const MNCC__PDU& in)
|
|||
ret_val = ret_val & in.u().data().data();
|
||||
break;
|
||||
case MNCC__MsgUnion::ALT_rtp:
|
||||
switch (mncc_sock_version) {
|
||||
case 6:
|
||||
struct gsm_mncc_rtp_mncc6 rtp_old;
|
||||
memset(&rtp_old, 0, sizeof(rtp_old));
|
||||
rtp_old.msg_type = in.msg__type();
|
||||
rtp_old.callref = in.u().rtp().callref();
|
||||
ttcn_buffer.put_string(in.u().rtp().ip());
|
||||
if (!in.u().rtp().is__ipv6()) {
|
||||
memcpy(&rtp_old.ip, ttcn_buffer.get_data(), sizeof(struct in_addr));
|
||||
rtp_old.ip = ntohl(rtp_old.ip);
|
||||
} /* else: ipv6 not supported in MNCCv6 */
|
||||
rtp_old.port = in.u().rtp().rtp__port();
|
||||
rtp_old.payload_type = in.u().rtp().payload__type();
|
||||
rtp_old.payload_msg_type = in.u().rtp().payload__msg__type();
|
||||
ret_val = OCTETSTRING(sizeof(rtp_old), (uint8_t *) &rtp_old);
|
||||
break;
|
||||
case 7:
|
||||
struct gsm_mncc_rtp rtp;
|
||||
memset(&rtp, 0, sizeof(rtp));
|
||||
rtp.msg_type = in.msg__type();
|
||||
rtp.callref = in.u().rtp().callref();
|
||||
rtp.ip = in.u().rtp().ip();
|
||||
rtp.port = in.u().rtp().rtp__port();
|
||||
ttcn_buffer.put_string(in.u().rtp().ip());
|
||||
if (in.u().rtp().is__ipv6()) {
|
||||
// if(in.u().rtp().ip().lengthof() != 16) print error
|
||||
rtp.addr.ss_family = AF_INET6;
|
||||
memcpy(&((struct sockaddr_in6*)&rtp.addr)->sin6_addr, ttcn_buffer.get_data(),
|
||||
sizeof(struct in6_addr));
|
||||
((struct sockaddr_in6*)&rtp.addr)->sin6_port = htons(in.u().rtp().rtp__port());
|
||||
} else {
|
||||
// if(in.u().rtp().ip().lengthof() != 4) print error
|
||||
rtp.addr.ss_family = AF_INET;
|
||||
memcpy(&((struct sockaddr_in*)&rtp.addr)->sin_addr, ttcn_buffer.get_data(),
|
||||
sizeof(struct in_addr));
|
||||
((struct sockaddr_in*)&rtp.addr)->sin_port = htons(in.u().rtp().rtp__port());
|
||||
}
|
||||
rtp.payload_type = in.u().rtp().payload__type();
|
||||
rtp.payload_msg_type = in.u().rtp().payload__msg__type();
|
||||
ret_val = OCTETSTRING(sizeof(rtp), (uint8_t *) &rtp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MNCC__MsgUnion::ALT_hello:
|
||||
struct gsm_mncc_hello hello;
|
||||
memset(&hello, 0, sizeof(hello));
|
||||
|
@ -222,8 +264,12 @@ MNCC__PDU dec__MNCC__PDU(const OCTETSTRING& in)
|
|||
const struct gsm_data_frame *in_data;
|
||||
MNCC__PDU__Data data;
|
||||
const struct gsm_mncc_rtp *in_rtp;
|
||||
const struct gsm_mncc_rtp_mncc6 *in_rtp_old;
|
||||
MNCC__PDU__Rtp rtp;
|
||||
MNCC__MsgUnion u;
|
||||
bool is_ipv6;
|
||||
OCTETSTRING ip;
|
||||
uint16_t port;
|
||||
|
||||
in_mncc = (struct gsm_mncc *) ttcn_buffer.get_read_data();
|
||||
|
||||
|
@ -257,11 +303,41 @@ MNCC__PDU dec__MNCC__PDU(const OCTETSTRING& in)
|
|||
case MNCC_RTP_CREATE:
|
||||
case MNCC_RTP_CONNECT:
|
||||
case MNCC_RTP_FREE:
|
||||
switch (mncc_sock_version) {
|
||||
case 6:
|
||||
struct in_addr inaddr;
|
||||
in_rtp_old = (const struct gsm_mncc_rtp_mncc6 *) in_mncc;
|
||||
inaddr.s_addr = htonl(in_rtp_old->ip);
|
||||
ip = OCTETSTRING(sizeof(struct in_addr),
|
||||
(const unsigned char*)&inaddr);
|
||||
rtp = MNCC__PDU__Rtp(in_rtp_old->callref, false, ip, in_rtp_old->port, in_rtp_old->payload_type,
|
||||
in_rtp_old->payload_msg_type, in_rtp_old->sdp);
|
||||
u.rtp() = rtp;
|
||||
break;
|
||||
case 7:
|
||||
in_rtp = (const struct gsm_mncc_rtp *) in_mncc;
|
||||
rtp = MNCC__PDU__Rtp(in_rtp->callref, in_rtp->ip, in_rtp->port, in_rtp->payload_type,
|
||||
switch (in_rtp->addr.ss_family) {
|
||||
case AF_INET6:
|
||||
is_ipv6 = true;
|
||||
port = ntohs(((struct sockaddr_in6*)&in_rtp->addr)->sin6_port);
|
||||
ip = OCTETSTRING(sizeof(struct in6_addr),
|
||||
(const unsigned char*)&((struct sockaddr_in6*)&in_rtp->addr)->sin6_addr);
|
||||
|
||||
break;
|
||||
case AF_UNSPEC: //RTP_CREATE and RTP_FREE can contain fully zeroed addr
|
||||
case AF_INET:
|
||||
is_ipv6 = false;
|
||||
port = ntohs(((struct sockaddr_in*)&in_rtp->addr)->sin_port);
|
||||
ip = OCTETSTRING(sizeof(struct in_addr),
|
||||
(const unsigned char*)&((struct sockaddr_in*)&in_rtp->addr)->sin_addr);
|
||||
break;
|
||||
}
|
||||
rtp = MNCC__PDU__Rtp(in_rtp->callref, is_ipv6, ip, port, in_rtp->payload_type,
|
||||
in_rtp->payload_msg_type, in_rtp->sdp);
|
||||
u.rtp() = rtp;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sign.callref() = in_mncc->callref;
|
||||
if (in_mncc->fields & MNCC_F_BEARER_CAP) {
|
||||
|
|
|
@ -373,7 +373,8 @@ type record MNCC_PDU_Data {
|
|||
|
||||
type record MNCC_PDU_Rtp {
|
||||
uint32_t callref,
|
||||
uint32_t ip,
|
||||
boolean is_ipv6,
|
||||
octetstring ip,
|
||||
uint16_t rtp_port,
|
||||
uint32_t payload_type,
|
||||
uint32_t payload_msg_type,
|
||||
|
@ -421,6 +422,8 @@ external function enc_MNCC_PDU(in MNCC_PDU pdu) return octetstring;
|
|||
|
||||
external function dec_MNCC_PDU(in octetstring stream) return MNCC_PDU;
|
||||
|
||||
external function set_MNCC_version(in integer version) return boolean;
|
||||
|
||||
template (value) MNCC_PDU ts_MNCC_HELLO(uint32_t version := 5) := {
|
||||
msg_type := MNCC_SOCKET_HELLO,
|
||||
u := {
|
||||
|
@ -1921,7 +1924,8 @@ template MNCC_PDU ts_MNCC_SIMPLE_RTP(MNCC_MsgType msg_type, uint32_t call_id) :=
|
|||
u := {
|
||||
rtp := {
|
||||
callref := call_id,
|
||||
ip := 0,
|
||||
is_ipv6 := false,
|
||||
ip := '00000000'O,
|
||||
rtp_port := 0,
|
||||
payload_type := 0,
|
||||
payload_msg_type := 0,
|
||||
|
@ -1935,13 +1939,14 @@ template MNCC_PDU ts_MNCC_RTP_CREATE(uint32_t call_id) := ts_MNCC_SIMPLE_RTP(MNC
|
|||
|
||||
/* MSC -> MNCC: RTP_CREATE.rsp; acknowledge creation of RTP (stating MSC side IP/Port) */
|
||||
template MNCC_PDU tr_MNCC_RTP_CREATE(template uint32_t call_id := ?,
|
||||
template uint32_t ip := ?,
|
||||
template uint32_t rtp_port := ?,
|
||||
template octetstring ip := ?,
|
||||
template uint16_t rtp_port := ?,
|
||||
template uint32_t payload_type := ?) := {
|
||||
msg_type := MNCC_RTP_CREATE,
|
||||
u := {
|
||||
rtp := {
|
||||
callref := call_id,
|
||||
is_ipv6 := ?,
|
||||
ip := ip,
|
||||
rtp_port := rtp_port,
|
||||
payload_type := payload_type,
|
||||
|
@ -1952,11 +1957,12 @@ template MNCC_PDU tr_MNCC_RTP_CREATE(template uint32_t call_id := ?,
|
|||
}
|
||||
|
||||
/* MSC <- MNCC: RTP_CONNECT.req; request connect of RTP */
|
||||
template MNCC_PDU ts_MNCC_RTP_CONNECT(uint32_t call_id, uint32_t ip, uint32_t rtp_port, uint32_t pt) := {
|
||||
template MNCC_PDU ts_MNCC_RTP_CONNECT(uint32_t call_id, boolean is_ipv6, octetstring ip, uint16_t rtp_port, uint32_t pt) := {
|
||||
msg_type := MNCC_RTP_CONNECT,
|
||||
u := {
|
||||
rtp := {
|
||||
callref := call_id,
|
||||
is_ipv6 := is_ipv6,
|
||||
ip := ip,
|
||||
rtp_port := rtp_port,
|
||||
payload_type := pt,
|
||||
|
@ -1966,13 +1972,14 @@ template MNCC_PDU ts_MNCC_RTP_CONNECT(uint32_t call_id, uint32_t ip, uint32_t rt
|
|||
}
|
||||
}
|
||||
template MNCC_PDU tr_MNCC_RTP_CONNECT(template uint32_t call_id,
|
||||
template uint32_t ip := ?,
|
||||
template uint32_t rtp_port := ?,
|
||||
template octetstring ip := ?,
|
||||
template uint16_t rtp_port := ?,
|
||||
template uint32_t pt := ?) := {
|
||||
msg_type := MNCC_RTP_CONNECT,
|
||||
u := {
|
||||
rtp := {
|
||||
callref := call_id,
|
||||
is_ipv6 := ?,
|
||||
ip := ip,
|
||||
rtp_port := rtp_port,
|
||||
payload_type := pt,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Rate Adaption */
|
||||
enum gsm48_bcap_ra {
|
||||
|
@ -275,7 +276,7 @@ struct gsm_data_frame {
|
|||
unsigned char data[0];
|
||||
};
|
||||
|
||||
#define MNCC_SOCK_VERSION 5
|
||||
#define MNCC_SOCK_VERSION 7
|
||||
struct gsm_mncc_hello {
|
||||
uint32_t msg_type;
|
||||
uint32_t version;
|
||||
|
@ -291,7 +292,8 @@ struct gsm_mncc_hello {
|
|||
uint32_t lchan_type_offset;
|
||||
};
|
||||
|
||||
struct gsm_mncc_rtp {
|
||||
/* Use this one in MNCCv6 */
|
||||
struct gsm_mncc_rtp_mncc6 {
|
||||
uint32_t msg_type;
|
||||
uint32_t callref;
|
||||
uint32_t ip;
|
||||
|
@ -302,6 +304,16 @@ struct gsm_mncc_rtp {
|
|||
char sdp[1024];
|
||||
};
|
||||
|
||||
struct gsm_mncc_rtp {
|
||||
uint32_t msg_type;
|
||||
uint32_t callref;
|
||||
struct sockaddr_storage addr;
|
||||
uint32_t payload_type;
|
||||
uint32_t payload_msg_type;
|
||||
|
||||
char sdp[1024];
|
||||
};
|
||||
|
||||
struct gsm_mncc_bridge {
|
||||
uint32_t msg_type;
|
||||
uint32_t callref[2];
|
||||
|
|
|
@ -15,6 +15,7 @@ module BSC_ConnectionHandler {
|
|||
import from General_Types all;
|
||||
import from Osmocom_Types all;
|
||||
import from Native_Functions all;
|
||||
import from Misc_Helpers all;
|
||||
import from GSM_Types all;
|
||||
import from IPL4asp_Types all;
|
||||
import from SCCPasp_Types all;
|
||||
|
@ -813,6 +814,8 @@ type record CallParameters {
|
|||
/* MNCC related parameters */
|
||||
uint32_t mncc_callref optional, /* call reference on the MNCC side */
|
||||
MNCC_bearer_cap mncc_bearer_cap optional, /* MNCC-side bearer capabilities */
|
||||
HostName mncc_rtp_ip optional, /* MNCC Side RTP IP */
|
||||
PortNumber mncc_rtp_port optional, /* MNCC Side RTP port */
|
||||
|
||||
/* RTP related parameters */
|
||||
HostName bss_rtp_ip optional, /* BSS Side RTP IP */
|
||||
|
@ -845,6 +848,8 @@ template (value) CallParameters t_CallParams(hexstring called := '12345'H, integ
|
|||
emergency := false,
|
||||
mncc_callref := omit,
|
||||
mncc_bearer_cap := valueof(ts_MNCC_bcap_voice),
|
||||
mncc_rtp_ip := "42.23.11.5",
|
||||
mncc_rtp_port := 423,
|
||||
bss_rtp_ip := "9.8.7.6",
|
||||
bss_rtp_port := 9000,
|
||||
mss_rtp_ip := omit,
|
||||
|
@ -979,9 +984,16 @@ runs on BSC_ConnHdlr {
|
|||
|
||||
[] MNCC.receive(tr_MNCC_SETUP_cnf(cpars.mncc_callref)) {
|
||||
log("f_mt_call_complete 7");
|
||||
var octetstring ip;
|
||||
var boolean is_ipv6 := f_addr_is_ipv6(cpars.mncc_rtp_ip);
|
||||
if (is_ipv6) {
|
||||
ip := f_inet6_addr(cpars.mncc_rtp_ip);
|
||||
} else {
|
||||
ip := f_inet_addr(cpars.mncc_rtp_ip);
|
||||
}
|
||||
MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
|
||||
/* ip 42.23.11.5 */ hex2int('42231105'H),
|
||||
/* port 423 */ 423,
|
||||
is_ipv6, ip,
|
||||
cpars.mncc_rtp_port,
|
||||
/* payload type 3 = GSM FR */ 3));
|
||||
}
|
||||
|
||||
|
@ -1064,9 +1076,16 @@ runs on BSC_ConnHdlr {
|
|||
|
||||
[] MNCC.receive(tr_MNCC_SETUP_cnf(cpars.mncc_callref)) {
|
||||
log("f_mt_call_complete 7.iu");
|
||||
var octetstring ip;
|
||||
var boolean is_ipv6 := f_addr_is_ipv6(cpars.mncc_rtp_ip);
|
||||
if (is_ipv6) {
|
||||
ip := f_inet6_addr(cpars.mncc_rtp_ip);
|
||||
} else {
|
||||
ip := f_inet_addr(cpars.mncc_rtp_ip);
|
||||
}
|
||||
MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
|
||||
/* ip 42.23.11.5 */ hex2int('42231105'H),
|
||||
/* port 423 */ 423,
|
||||
is_ipv6, ip,
|
||||
cpars.mncc_rtp_port,
|
||||
/* payload type 3 = GSM FR */ 3));
|
||||
}
|
||||
|
||||
|
@ -1458,9 +1477,16 @@ runs on BSC_ConnHdlr {
|
|||
|
||||
cpars.mncc_callref := mncc.u.signal.callref;
|
||||
/* Call Proceeding */
|
||||
var octetstring ip;
|
||||
var boolean is_ipv6 := f_addr_is_ipv6(cpars.mncc_rtp_ip);
|
||||
if (is_ipv6) {
|
||||
ip := f_inet6_addr(cpars.mncc_rtp_ip);
|
||||
} else {
|
||||
ip := f_inet_addr(cpars.mncc_rtp_ip);
|
||||
}
|
||||
MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
|
||||
/* ip 42.23.11.5 */ hex2int('42231105'H),
|
||||
/* port 423 */ 423,
|
||||
is_ipv6, ip,
|
||||
cpars.mncc_rtp_port,
|
||||
/* payload type 3 = GSM FR */ 3));
|
||||
MNCC.send(ts_MNCC_SETUP_rsp(cpars.mncc_callref));
|
||||
}
|
||||
|
|
|
@ -1979,6 +1979,7 @@ friend function f_tc_lu_and_mt_call_ipv6(charstring id, BSC_ConnHdlrPars pars) r
|
|||
cpars.mgw_conn_1.mgw_rtp_ip := "::1";
|
||||
cpars.mgw_conn_2.mgw_rtp_ip := "::2";
|
||||
cpars.bss_rtp_ip := "::3";
|
||||
cpars.mncc_rtp_ip := "::9";
|
||||
f_perform_lu();
|
||||
f_mt_call(cpars);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ mtc.FileMask := ERROR | WARNING | PARALLEL | VERDICTOP;
|
|||
|
||||
[MODULE_PARAMETERS]
|
||||
Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoSIPcon";
|
||||
MNCC_Emulation.mp_mncc_version := 6;
|
||||
MNCC_Emulation.mp_mncc_version := 7;
|
||||
|
||||
[MAIN_CONTROLLER]
|
||||
|
||||
|
|
Loading…
Reference in New Issue