iu_helpers: make new_transp_info_(rtp|gtp) public
The functions new_transp_info_rtp and new_transp_info_gtp are needed to generate the transport layer information struct. The functions are currently not public since they are only used in ranap_msg_factory.c but to reqwrite the RANAP RAB AssignmentReqtest / AssignmentResponse messages we can reuse this code, so lets make them public. Change-Id: I1e369718de8c4c7db1f1af1e6864562164ada6cf Related: OS#5152
This commit is contained in:
parent
48b8af2bde
commit
ed1537e9cb
|
@ -1,13 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocom/ranap/RANAP_IuTransportAssociation.h>
|
||||
#include <osmocom/ranap/RANAP_TransportLayerAddress.h>
|
||||
#include <osmocom/ranap/RANAP_TransportLayerInformation.h>
|
||||
|
||||
struct osmo_sockaddr;
|
||||
|
||||
int ranap_bcd_decode(char *out, size_t out_len, const uint8_t *in, size_t in_len);
|
||||
int ranap_imsi_encode(uint8_t *out, size_t out_len, const char *in);
|
||||
int ranap_transp_assoc_decode(uint16_t *port, const RANAP_IuTransportAssociation_t *transp_assoc);
|
||||
int ranap_transp_layer_addr_decode(char *addr, unsigned int addr_len,
|
||||
const RANAP_TransportLayerAddress_t *trasp_layer_addr);
|
||||
RANAP_TransportLayerInformation_t *ranap_new_transp_info_rtp(struct osmo_sockaddr *addr, bool use_x213_nsap);
|
||||
RANAP_TransportLayerInformation_t *ranap_new_transp_info_gtp(struct osmo_sockaddr *addr, uint32_t tei,
|
||||
bool use_x213_nsap);
|
||||
|
|
103
src/iu_helpers.c
103
src/iu_helpers.c
|
@ -24,8 +24,12 @@
|
|||
#include <arpa/inet.h>
|
||||
#include "asn1helpers.h"
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/bit16gen.h>
|
||||
|
||||
#include <osmocom/ranap/RANAP_IuTransportAssociation.h>
|
||||
#include <osmocom/ranap/RANAP_TransportLayerAddress.h>
|
||||
#include <osmocom/ranap/RANAP_TransportLayerInformation.h>
|
||||
|
||||
/* decode a BCD-string as used inside ASN.1 encoded Iu interface protocols */
|
||||
int ranap_bcd_decode(char *out, size_t out_len, const uint8_t *in, size_t in_len)
|
||||
|
@ -121,3 +125,102 @@ int ranap_transp_layer_addr_decode(char *addr, unsigned int addr_len,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int new_transp_layer_addr(BIT_STRING_t *out, struct osmo_sockaddr *addr, bool use_x213_nsap)
|
||||
{
|
||||
uint8_t *buf;
|
||||
unsigned int len;
|
||||
size_t ip_len;
|
||||
uint8_t *ip_addr;
|
||||
uint16_t icp;
|
||||
|
||||
switch (addr->u.sa.sa_family) {
|
||||
case AF_INET:
|
||||
ip_len = sizeof(addr->u.sin.sin_addr.s_addr);
|
||||
ip_addr = (uint8_t *) &addr->u.sin.sin_addr.s_addr;
|
||||
icp = 0x0001; /* See X.213, section A.5.2.1.2.7 */
|
||||
break;
|
||||
case AF_INET6:
|
||||
ip_len = sizeof(addr->u.sin6.sin6_addr.s6_addr);
|
||||
ip_addr = addr->u.sin6.sin6_addr.s6_addr;
|
||||
icp = 0x0000; /* See X.213, section A.5.2.1.2.7 */
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (use_x213_nsap) {
|
||||
/* 3 bytes IDP (AFI+ICP) + 17 bytes DSP */
|
||||
len = 3 + 17;
|
||||
buf = CALLOC(len, sizeof(uint8_t));
|
||||
|
||||
/* 1 byte AFI to announce IANA ICP, see also X.213, table A.4 */
|
||||
buf[0] = 0x35;
|
||||
|
||||
/* 2 byte IANA ICP IDI, see also X.213, A.5.2.1.2.7 */
|
||||
osmo_store16be(icp, &buf[1]);
|
||||
|
||||
/* 17 byte DSP, see also X.213, table A.5 and A.5.2.1.2.7 */
|
||||
memcpy(&buf[3], ip_addr, ip_len);
|
||||
} else {
|
||||
len = ip_len;
|
||||
buf = CALLOC(len, sizeof(uint8_t));
|
||||
memcpy(buf, ip_addr, ip_len);
|
||||
}
|
||||
out->buf = buf;
|
||||
out->size = len;
|
||||
out->bits_unused = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
RANAP_TransportLayerInformation_t *ranap_new_transp_info_rtp(struct osmo_sockaddr *addr, bool use_x213_nsap)
|
||||
{
|
||||
RANAP_TransportLayerInformation_t *tli;
|
||||
uint8_t binding_id[4] = { 0 };
|
||||
int rc;
|
||||
|
||||
switch (addr->u.sin.sin_family) {
|
||||
case AF_INET:
|
||||
osmo_store16be(ntohs(addr->u.sin.sin_port), binding_id);
|
||||
break;
|
||||
case AF_INET6:
|
||||
osmo_store16be(ntohs(addr->u.sin6.sin6_port), binding_id);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tli = CALLOC(1, sizeof(*tli));
|
||||
rc = new_transp_layer_addr(&tli->transportLayerAddress, addr, use_x213_nsap);
|
||||
if (rc < 0) {
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID;
|
||||
OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
|
||||
(const char *)binding_id, sizeof(binding_id));
|
||||
|
||||
return tli;
|
||||
}
|
||||
|
||||
RANAP_TransportLayerInformation_t *ranap_new_transp_info_gtp(struct osmo_sockaddr *addr, uint32_t tei,
|
||||
bool use_x213_nsap)
|
||||
{
|
||||
RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
|
||||
uint32_t binding_buf = htonl(tei);
|
||||
int rc;
|
||||
|
||||
rc = new_transp_layer_addr(&tli->transportLayerAddress, addr, use_x213_nsap);
|
||||
if (rc < 0) {
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_gTP_TEI;
|
||||
OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.gTP_TEI,
|
||||
(const char *)&binding_buf, sizeof(binding_buf));
|
||||
|
||||
return tli;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
|
||||
#include "asn1helpers.h"
|
||||
#include <osmocom/ranap/iu_helpers.h>
|
||||
|
@ -691,61 +692,6 @@ static RANAP_RAB_Parameters_t *new_rab_par_data(uint32_t dl_max_bitrate, uint32_
|
|||
return rab;
|
||||
}
|
||||
|
||||
static void new_transp_layer_addr(BIT_STRING_t *out, uint32_t ip, bool use_x213_nsap)
|
||||
{
|
||||
uint8_t *buf;
|
||||
unsigned int len;
|
||||
uint32_t ip_h = ntohl(ip);
|
||||
|
||||
if (use_x213_nsap) {
|
||||
len = 160/8;
|
||||
buf = CALLOC(len, sizeof(uint8_t));
|
||||
buf[0] = 0x35; /* AFI For IANA ICP */
|
||||
buf[1] = 0x00; /* See A.5.2.1.2.7 of X.213 */
|
||||
buf[2] = 0x01;
|
||||
memcpy(&buf[3], &ip_h, sizeof(ip_h));
|
||||
} else {
|
||||
len = sizeof(ip_h);
|
||||
buf = CALLOC(len, sizeof(uint8_t));
|
||||
memcpy(buf, &ip_h, sizeof(ip_h));
|
||||
}
|
||||
out->buf = buf;
|
||||
out->size = len;
|
||||
out->bits_unused = 0;
|
||||
}
|
||||
|
||||
static RANAP_TransportLayerInformation_t *new_transp_info_rtp(uint32_t ip, uint16_t port,
|
||||
bool use_x213_nsap)
|
||||
{
|
||||
RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
|
||||
uint8_t binding_id[4];
|
||||
|
||||
binding_id[0] = port >> 8;
|
||||
binding_id[1] = port & 0xff;
|
||||
binding_id[2] = binding_id[3] = 0;
|
||||
|
||||
new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap);
|
||||
tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_bindingID;
|
||||
OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.bindingID,
|
||||
(const char *) binding_id, sizeof(binding_id));
|
||||
|
||||
return tli;
|
||||
}
|
||||
|
||||
static RANAP_TransportLayerInformation_t *new_transp_info_gtp(uint32_t ip, uint32_t tei,
|
||||
bool use_x213_nsap)
|
||||
{
|
||||
RANAP_TransportLayerInformation_t *tli = CALLOC(1, sizeof(*tli));
|
||||
uint32_t binding_buf = htonl(tei);
|
||||
|
||||
new_transp_layer_addr(&tli->transportLayerAddress, ip, use_x213_nsap);
|
||||
tli->iuTransportAssociation.present = RANAP_IuTransportAssociation_PR_gTP_TEI;
|
||||
OCTET_STRING_fromBuf(&tli->iuTransportAssociation.choice.gTP_TEI,
|
||||
(const char *) &binding_buf, sizeof(binding_buf));
|
||||
|
||||
return tli;
|
||||
}
|
||||
|
||||
static RANAP_UserPlaneInformation_t *new_upi(long mode, uint8_t mode_versions)
|
||||
{
|
||||
RANAP_UserPlaneInformation_t *upi = CALLOC(1, sizeof(*upi));
|
||||
|
@ -786,6 +732,7 @@ struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip,
|
|||
RANAP_RAB_AssignmentRequest_t out;
|
||||
struct msgb *msg;
|
||||
int rc;
|
||||
struct osmo_sockaddr rtp_addr;
|
||||
|
||||
memset(&ies, 0, sizeof(ies));
|
||||
memset(&out, 0, sizeof(out));
|
||||
|
@ -800,8 +747,11 @@ struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip,
|
|||
first.nAS_SynchronisationIndicator = new_rab_nas_sync_ind(60);
|
||||
first.rAB_Parameters = new_rab_par_voice(6700, 12200);
|
||||
first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_support_mode_for_predefined_SDU_sizes, 1); /* 2? */
|
||||
first.transportLayerInformation = new_transp_info_rtp(rtp_ip, rtp_port,
|
||||
use_x213_nsap);
|
||||
|
||||
rtp_addr.u.sin.sin_family = AF_INET;
|
||||
rtp_addr.u.sin.sin_port = htons(rtp_port);
|
||||
rtp_addr.u.sin.sin_addr.s_addr = htonl(rtp_ip);
|
||||
first.transportLayerInformation = ranap_new_transp_info_rtp(&rtp_addr, use_x213_nsap);
|
||||
|
||||
/* put together the 'Second' part */
|
||||
RANAP_RAB_SetupOrModifyItemSecond_t second;
|
||||
|
@ -855,6 +805,7 @@ struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip,
|
|||
RANAP_DataVolumeReportingIndication_t *dat_vol_ind;
|
||||
struct msgb *msg;
|
||||
int rc;
|
||||
struct osmo_sockaddr gtp_addr;
|
||||
|
||||
memset(&ies, 0, sizeof(ies));
|
||||
memset(&out, 0, sizeof(out));
|
||||
|
@ -870,8 +821,10 @@ struct msgb *ranap_new_msg_rab_assign_data(uint8_t rab_id, uint32_t gtp_ip,
|
|||
|
||||
first.rAB_Parameters = new_rab_par_data(1600000, 800000);
|
||||
first.userPlaneInformation = new_upi(RANAP_UserPlaneMode_transparent_mode, 1);
|
||||
first.transportLayerInformation = new_transp_info_gtp(gtp_ip, gtp_tei,
|
||||
use_x213_nsap);
|
||||
|
||||
gtp_addr.u.sin.sin_family = AF_INET;
|
||||
gtp_addr.u.sin.sin_addr.s_addr = htonl(gtp_ip);
|
||||
first.transportLayerInformation = ranap_new_transp_info_gtp(>p_addr, gtp_tei, use_x213_nsap);
|
||||
|
||||
/* put together the 'Second' part */
|
||||
RANAP_RAB_SetupOrModifyItemSecond_t second;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#define ASSERT(x) assert(x)
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
|
||||
#include <osmocom/ranap/RANAP_LAI.h>
|
||||
|
@ -204,6 +205,120 @@ void test_ranap_common(void)
|
|||
OSMO_ASSERT(rc == -1);
|
||||
}
|
||||
|
||||
void test_ranap_new_transp_info_rtp(void)
|
||||
{
|
||||
RANAP_TransportLayerInformation_t *tli;
|
||||
|
||||
printf("Testing function ranap_new_transp_info_rtp()\n");
|
||||
|
||||
struct osmo_sockaddr addr;
|
||||
|
||||
addr.u.sin.sin_family = AF_INET;
|
||||
addr.u.sin.sin_port = htons(0x1122);
|
||||
inet_pton(AF_INET, "1.2.3.4", &addr.u.sin.sin_addr);
|
||||
|
||||
printf(" ipv4, x213_nsap\n");
|
||||
tli = ranap_new_transp_info_rtp(&addr, true);
|
||||
printf(" transportLayerAddress = %s\n",
|
||||
osmo_hexdump_nospc(tli->transportLayerAddress.buf, tli->transportLayerAddress.size));
|
||||
printf(" bindingID = %s\n",
|
||||
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.bindingID.buf,
|
||||
tli->iuTransportAssociation.choice.bindingID.size));
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
|
||||
printf(" ipv4\n");
|
||||
tli = ranap_new_transp_info_rtp(&addr, false);
|
||||
printf(" transportLayerAddress = %s\n",
|
||||
osmo_hexdump_nospc(tli->transportLayerAddress.buf, tli->transportLayerAddress.size));
|
||||
printf(" bindingID = %s\n",
|
||||
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.bindingID.buf,
|
||||
tli->iuTransportAssociation.choice.bindingID.size));
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
|
||||
addr.u.sin.sin_family = AF_INET6;
|
||||
addr.u.sin.sin_port = htons(0x1122);
|
||||
inet_pton(AF_INET6, "f11f:f22f:f33f:f44f:f55f:f66f:f77f:f88f", &addr.u.sin6.sin6_addr);
|
||||
|
||||
printf(" ipv6, x213_nsap\n");
|
||||
tli = ranap_new_transp_info_rtp(&addr, true);
|
||||
printf(" transportLayerAddress = %s\n",
|
||||
osmo_hexdump_nospc(tli->transportLayerAddress.buf, tli->transportLayerAddress.size));
|
||||
printf(" bindingID = %s\n",
|
||||
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.bindingID.buf,
|
||||
tli->iuTransportAssociation.choice.bindingID.size));
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
|
||||
printf(" ipv6\n");
|
||||
tli = ranap_new_transp_info_rtp(&addr, false);
|
||||
printf(" transportLayerAddress = %s\n",
|
||||
osmo_hexdump_nospc(tli->transportLayerAddress.buf, tli->transportLayerAddress.size));
|
||||
printf(" bindingID = %s\n",
|
||||
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.bindingID.buf,
|
||||
tli->iuTransportAssociation.choice.bindingID.size));
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
|
||||
addr.u.sin.sin_family = AF_X25;
|
||||
printf(" unsupported address family\n");
|
||||
tli = ranap_new_transp_info_rtp(&addr, false);
|
||||
OSMO_ASSERT(tli == NULL);
|
||||
}
|
||||
|
||||
void test_ranap_new_transp_info_gtp(void)
|
||||
{
|
||||
RANAP_TransportLayerInformation_t *tli;
|
||||
|
||||
printf("Testing function ranap_new_transp_info_gtp()\n");
|
||||
|
||||
struct osmo_sockaddr addr;
|
||||
|
||||
addr.u.sin.sin_family = AF_INET;
|
||||
inet_pton(AF_INET, "1.2.3.4", &addr.u.sin.sin_addr);
|
||||
|
||||
printf(" ipv4, x213_nsap\n");
|
||||
tli = ranap_new_transp_info_gtp(&addr, 0x11223344, true);
|
||||
printf(" transportLayerAddress = %s\n",
|
||||
osmo_hexdump_nospc(tli->transportLayerAddress.buf, tli->transportLayerAddress.size));
|
||||
printf(" gTP_TEI = %s\n",
|
||||
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.gTP_TEI.buf,
|
||||
tli->iuTransportAssociation.choice.gTP_TEI.size));
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
|
||||
printf(" ipv4\n");
|
||||
tli = ranap_new_transp_info_gtp(&addr, 0x11223344, false);
|
||||
printf(" transportLayerAddress = %s\n",
|
||||
osmo_hexdump_nospc(tli->transportLayerAddress.buf, tli->transportLayerAddress.size));
|
||||
printf(" gTP_TEI = %s\n",
|
||||
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.gTP_TEI.buf,
|
||||
tli->iuTransportAssociation.choice.gTP_TEI.size));
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
|
||||
addr.u.sin.sin_family = AF_INET6;
|
||||
inet_pton(AF_INET6, "f11f:f22f:f33f:f44f:f55f:f66f:f77f:f88f", &addr.u.sin6.sin6_addr);
|
||||
|
||||
printf(" ipv6, x213_nsap\n");
|
||||
tli = ranap_new_transp_info_gtp(&addr, 0x11223344, true);
|
||||
printf(" transportLayerAddress = %s\n",
|
||||
osmo_hexdump_nospc(tli->transportLayerAddress.buf, tli->transportLayerAddress.size));
|
||||
printf(" gTP_TEI = %s\n",
|
||||
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.gTP_TEI.buf,
|
||||
tli->iuTransportAssociation.choice.gTP_TEI.size));
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
|
||||
printf(" ipv6\n");
|
||||
tli = ranap_new_transp_info_gtp(&addr, 0x11223344, false);
|
||||
printf(" transportLayerAddress = %s\n",
|
||||
osmo_hexdump_nospc(tli->transportLayerAddress.buf, tli->transportLayerAddress.size));
|
||||
printf(" gTP_TEI = %s\n",
|
||||
osmo_hexdump_nospc(tli->iuTransportAssociation.choice.gTP_TEI.buf,
|
||||
tli->iuTransportAssociation.choice.gTP_TEI.size));
|
||||
ASN_STRUCT_FREE(asn_DEF_RANAP_TransportLayerInformation, tli);
|
||||
|
||||
addr.u.sin.sin_family = AF_X25;
|
||||
printf(" unsupported address family\n");
|
||||
tli = ranap_new_transp_info_gtp(&addr, 0x11223344, false);
|
||||
OSMO_ASSERT(tli == NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
asn1_xer_print = 0;
|
||||
|
@ -214,6 +329,8 @@ int main(int argc, char **argv)
|
|||
test_iu_helpers();
|
||||
test_asn1_helpers();
|
||||
test_ranap_common();
|
||||
test_ranap_new_transp_info_gtp();
|
||||
test_ranap_new_transp_info_rtp();
|
||||
|
||||
test_common_cleanup();
|
||||
return 0;
|
||||
|
|
|
@ -23,3 +23,31 @@ PLMN-Id [ 21 43 ], LAC [ ab cd ]
|
|||
rc == -1
|
||||
PLMN-Id [ 21 43 65 ], LAC [ ab ]
|
||||
rc == -1
|
||||
Testing function ranap_new_transp_info_gtp()
|
||||
ipv4, x213_nsap
|
||||
transportLayerAddress = 3500010102030400000000000000000000000000
|
||||
gTP_TEI = 11223344
|
||||
ipv4
|
||||
transportLayerAddress = 01020304
|
||||
gTP_TEI = 11223344
|
||||
ipv6, x213_nsap
|
||||
transportLayerAddress = 350000f11ff22ff33ff44ff55ff66ff77ff88f00
|
||||
gTP_TEI = 11223344
|
||||
ipv6
|
||||
transportLayerAddress = f11ff22ff33ff44ff55ff66ff77ff88f
|
||||
gTP_TEI = 11223344
|
||||
unsupported address family
|
||||
Testing function ranap_new_transp_info_rtp()
|
||||
ipv4, x213_nsap
|
||||
transportLayerAddress = 3500010102030400000000000000000000000000
|
||||
bindingID = 11220000
|
||||
ipv4
|
||||
transportLayerAddress = 01020304
|
||||
bindingID = 11220000
|
||||
ipv6, x213_nsap
|
||||
transportLayerAddress = 350000f11ff22ff33ff44ff55ff66ff77ff88f00
|
||||
bindingID = 11220000
|
||||
ipv6
|
||||
transportLayerAddress = f11ff22ff33ff44ff55ff66ff77ff88f
|
||||
bindingID = 11220000
|
||||
unsupported address family
|
||||
|
|
Loading…
Reference in New Issue