open5gs/lib/gtp/gtp_types.c

245 lines
8.3 KiB
C
Raw Normal View History

2017-03-24 16:07:59 +00:00
/*
2017-07-10 05:33:46 +00:00
* Copyright (c) 2017, NextEPC Group
2017-03-24 16:07:59 +00:00
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define TRACE_MODULE _gtptypes
#include "core_debug.h"
2017-03-25 16:19:44 +00:00
#include "core_lib.h"
2017-03-24 16:07:59 +00:00
#include "gtp_types.h"
2017-03-25 16:19:44 +00:00
/* 8.13 Protocol Configuration Options (PCO)
* 10.5.6.3 Protocol configuration options in 3GPP TS 24.008 */
/* 8.15 Bearer Quality of Service (Bearer QoS) */
c_int16_t gtp_parse_bearer_qos(
gtp_bearer_qos_t *bearer_qos, tlv_octet_t *octet)
{
gtp_bearer_qos_t *source = (gtp_bearer_qos_t *)octet->data;
c_int16_t size = 0;
d_assert(bearer_qos, return -1, "Null param");
d_assert(octet, return -1, "Null param");
d_assert(octet->len == GTP_BEARER_QOS_LEN, return -1, "Null param");
memset(bearer_qos, 0, sizeof(gtp_bearer_qos_t));
2017-04-11 14:25:33 +00:00
bearer_qos->pre_emption_capability = source->pre_emption_capability;
bearer_qos->priority_level = source->priority_level;
bearer_qos->pre_emption_vulnerability = source->pre_emption_vulnerability;
2017-03-25 16:19:44 +00:00
size++;
bearer_qos->qci = source->qci;
size++;
2017-03-25 16:29:41 +00:00
bearer_qos->ul_mbr = core_buffer_to_uint64(octet->data + size, 5);
2017-03-25 16:19:44 +00:00
size += 5;
2017-03-25 16:29:41 +00:00
bearer_qos->dl_mbr = core_buffer_to_uint64(octet->data + size, 5);
2017-03-25 16:19:44 +00:00
size += 5;
2017-03-25 16:29:41 +00:00
bearer_qos->ul_gbr = core_buffer_to_uint64(octet->data + size, 5);
2017-03-25 16:19:44 +00:00
size += 5;
2017-03-25 16:29:41 +00:00
bearer_qos->dl_gbr = core_buffer_to_uint64(octet->data + size, 5);
2017-03-25 16:19:44 +00:00
size += 5;
d_assert(size == octet->len, return -1, "decode error");
return size;
}
c_int16_t gtp_build_bearer_qos(
tlv_octet_t *octet, gtp_bearer_qos_t *bearer_qos, void *data, int data_len)
{
gtp_bearer_qos_t target;
c_int16_t size = 0;
d_assert(bearer_qos, return -1, "Null param");
d_assert(octet, return -1, "Null param");
d_assert(data, return -1, "Null param");
d_assert(data_len >= GTP_BEARER_QOS_LEN, return -1, "Null param");
octet->data = data;
memcpy(&target, bearer_qos, sizeof(gtp_bearer_qos_t));
2017-03-25 16:29:41 +00:00
memcpy(octet->data + size, &target, 2);
2017-03-25 16:19:44 +00:00
size += 2;
2017-03-25 16:29:41 +00:00
core_uint64_to_buffer(target.ul_mbr, 5, octet->data + size);
2017-03-25 16:19:44 +00:00
size += 5;
2017-03-25 16:29:41 +00:00
core_uint64_to_buffer(target.dl_mbr, 5, octet->data + size);
2017-03-25 16:19:44 +00:00
size += 5;
2017-03-25 16:29:41 +00:00
core_uint64_to_buffer(target.ul_gbr, 5, octet->data + size);
2017-03-25 16:19:44 +00:00
size += 5;
2017-03-25 16:29:41 +00:00
core_uint64_to_buffer(target.dl_gbr, 5, octet->data + size);
2017-03-25 16:19:44 +00:00
size += 5;
octet->len = size;
return octet->len;
}
/* 8.21 User Location Information (ULI) */
2017-03-25 03:10:08 +00:00
c_int16_t gtp_parse_uli(gtp_uli_t *uli, tlv_octet_t *octet)
2017-03-24 16:07:59 +00:00
{
gtp_uli_t *source = (gtp_uli_t *)octet->data;
2017-03-25 02:16:18 +00:00
c_int16_t size = 0;
2017-03-24 16:07:59 +00:00
d_assert(uli, return -1, "Null param");
d_assert(octet, return -1, "Null param");
2017-03-25 02:16:18 +00:00
memset(uli, 0, sizeof(gtp_uli_t));
2017-03-24 16:07:59 +00:00
uli->flags = source->flags;
size++;
if (uli->flags.cgi)
{
d_assert(size + sizeof(uli->cgi) <= octet->len,
return -1, "decode error");
2017-03-25 16:29:41 +00:00
memcpy(&uli->cgi, octet->data + size, sizeof(uli->cgi));
2017-03-24 16:07:59 +00:00
uli->cgi.lac = ntohs(uli->cgi.lac);
uli->cgi.ci = ntohs(uli->cgi.ci);
size += sizeof(uli->cgi);
}
if (uli->flags.sai)
{
d_assert(size + sizeof(uli->sai) <= octet->len,
return -1, "decode error");
2017-03-25 16:29:41 +00:00
memcpy(&uli->sai, octet->data + size, sizeof(uli->sai));
2017-03-24 16:07:59 +00:00
uli->sai.lac = ntohs(uli->sai.lac);
uli->sai.sac = ntohs(uli->sai.sac);
size += sizeof(uli->sai);
}
if (uli->flags.rai)
{
d_assert(size + sizeof(uli->rai) <= octet->len,
return -1, "decode error");
2017-03-25 16:29:41 +00:00
memcpy(&uli->rai, octet->data + size, sizeof(uli->rai));
2017-03-24 16:07:59 +00:00
uli->rai.lac = ntohs(uli->rai.lac);
uli->rai.rac = ntohs(uli->rai.rac);
size += sizeof(uli->rai);
}
if (uli->flags.tai)
{
d_assert(size + sizeof(uli->tai) <= octet->len,
return -1, "decode error");
2017-03-25 16:29:41 +00:00
memcpy(&uli->tai, octet->data + size, sizeof(uli->tai));
2017-03-24 16:07:59 +00:00
uli->tai.tac = ntohs(uli->tai.tac);
size += sizeof(uli->tai);
}
2017-04-11 11:44:38 +00:00
if (uli->flags.e_cgi)
2017-03-24 16:07:59 +00:00
{
2017-04-11 11:44:38 +00:00
d_assert(size + sizeof(uli->e_cgi) <= octet->len,
2017-03-24 16:07:59 +00:00
return -1, "decode error");
2017-04-11 11:44:38 +00:00
memcpy(&uli->e_cgi, octet->data + size, sizeof(uli->e_cgi));
uli->e_cgi.cell_id = ntohl(uli->e_cgi.cell_id);
size += sizeof(uli->e_cgi);
2017-03-24 16:07:59 +00:00
}
if (uli->flags.lai)
{
d_assert(size + sizeof(uli->lai) <= octet->len,
return -1, "decode error");
2017-03-25 16:29:41 +00:00
memcpy(&uli->lai, octet->data + size, sizeof(uli->lai));
2017-03-24 16:07:59 +00:00
uli->lai.lac = ntohs(uli->lai.lac);
size += sizeof(uli->lai);
}
d_assert(size == octet->len, return -1, "decode error");
return size;
}
2017-03-25 03:10:08 +00:00
c_int16_t gtp_build_uli(
2017-03-25 02:16:18 +00:00
tlv_octet_t *octet, gtp_uli_t *uli, void *data, int data_len)
2017-03-24 16:07:59 +00:00
{
gtp_uli_t target;
2017-03-25 02:16:18 +00:00
c_int16_t size = 0;
2017-03-24 16:07:59 +00:00
d_assert(uli, return -1, "Null param");
d_assert(octet, return -1, "Null param");
2017-03-25 02:16:18 +00:00
d_assert(data, return -1, "Null param");
d_assert(data_len, return -1, "Null param");
2017-03-24 16:07:59 +00:00
2017-03-25 02:16:18 +00:00
octet->data = data;
2017-03-24 16:07:59 +00:00
memcpy(&target, uli, sizeof(gtp_uli_t));
2017-03-25 02:16:18 +00:00
d_assert(size + sizeof(target.flags) <= data_len,
return -1, "encode error");
2017-03-25 16:29:41 +00:00
memcpy(octet->data + size, &target.flags, sizeof(target.flags));
2017-03-24 16:07:59 +00:00
size += sizeof(target.flags);
if (target.flags.cgi)
{
2017-03-25 02:16:18 +00:00
d_assert(size + sizeof(target.cgi) <= data_len,
return -1, "encode error");
2017-03-24 16:07:59 +00:00
target.cgi.lac = htons(target.cgi.lac);
target.cgi.ci = htons(target.cgi.ci);
2017-03-25 16:29:41 +00:00
memcpy(octet->data + size, &target.cgi, sizeof(target.cgi));
2017-03-24 16:07:59 +00:00
size += sizeof(target.cgi);
}
if (target.flags.sai)
{
2017-03-25 02:16:18 +00:00
d_assert(size + sizeof(target.sai) <= data_len,
return -1, "encode error");
2017-03-24 16:07:59 +00:00
target.sai.lac = htons(target.sai.lac);
target.sai.sac = htons(target.sai.sac);
2017-03-25 16:29:41 +00:00
memcpy(octet->data + size, &target.sai, sizeof(target.sai));
2017-03-24 16:07:59 +00:00
size += sizeof(target.sai);
}
if (target.flags.rai)
{
2017-03-25 02:16:18 +00:00
d_assert(size + sizeof(target.rai) <= data_len,
return -1, "encode error");
2017-03-24 16:07:59 +00:00
target.rai.lac = htons(target.rai.lac);
target.rai.rac = htons(target.rai.rac);
2017-03-25 16:29:41 +00:00
memcpy(octet->data + size, &target.rai, sizeof(target.rai));
2017-03-24 16:07:59 +00:00
size += sizeof(target.rai);
}
if (target.flags.tai)
{
2017-03-25 02:16:18 +00:00
d_assert(size + sizeof(target.tai) <= data_len,
return -1, "encode error");
2017-03-24 16:07:59 +00:00
target.tai.tac = htons(target.tai.tac);
2017-03-25 16:29:41 +00:00
memcpy(octet->data + size, &target.tai, sizeof(target.tai));
2017-03-24 16:07:59 +00:00
size += sizeof(target.tai);
}
2017-04-11 11:44:38 +00:00
if (target.flags.e_cgi)
2017-03-24 16:07:59 +00:00
{
2017-04-11 11:44:38 +00:00
d_assert(size + sizeof(target.e_cgi) <= data_len,
2017-03-25 02:16:18 +00:00
return -1, "encode error");
2017-04-11 11:44:38 +00:00
target.e_cgi.cell_id = htonl(target.e_cgi.cell_id);
memcpy(octet->data + size, &target.e_cgi, sizeof(target.e_cgi));
size += sizeof(target.e_cgi);
2017-03-24 16:07:59 +00:00
}
if (target.flags.lai)
{
2017-03-25 02:16:18 +00:00
d_assert(size + sizeof(target.lai) <= data_len,
return -1, "encode error");
2017-03-24 16:07:59 +00:00
target.lai.lac = htons(target.lai.lac);
2017-03-25 16:29:41 +00:00
memcpy(octet->data + size, &target.lai, sizeof(target.lai));
2017-03-24 16:07:59 +00:00
size += sizeof(target.lai);
}
octet->len = size;
return octet->len;
}