blob: 0ef29b72f51e7f7016de2a14fa54908eeac67808 [file] [log] [blame]
Max7918f842018-12-10 10:57:59 +01001/*
2 * (C) 2018 by sysmocom - s.f.m.c. GmbH
3 * All Rights Reserved
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23#include <osmocom/gsm/protocol/gsm_08_08.h>
24#include <osmocom/gsm/gsm29205.h>
25#include <osmocom/gsm/gsm0808.h>
26#include <osmocom/core/msgb.h>
27#include <osmocom/gsm/tlv.h>
28
29#include <errno.h>
30
31/*! \addtogroup gsm29205
32 * @{
33 * \file gsm29205.c
34 * Functions related to 3GPP TS 29.205, primarily message generation/encoding.
35 */
36
37/*! Create Global Call Reference.
38 * \param[out] msg Message Buffer for appending IE
39 * \param[in] g Global Call Reference, 3GPP TS 29.205 Table B 2.1.9.1
40 * \returns number of bytes added to \a msg */
41uint8_t osmo_enc_gcr(struct msgb *msg, const struct osmo_gcr_parsed *g)
42{
43 uint8_t buf[2];
44
45 if (!g)
46 return 0;
47
48 if (g->net_len < 3 || g->net_len > 5)
49 return 0;
50
51 msgb_lv_put(msg, g->net_len, g->net);
52
53 osmo_store16be(g->node, &buf);
54 msgb_lv_put(msg, 2, buf);
55
56 msgb_lv_put(msg, 5, g->cr);
57
58 /* Length: LV(Net) + LV(Node) + LV(CRef) - see 3GPP TS ยง3.2.2.115 */
59 return (g->net_len + 1) + (2 + 1) + (5 + 1);
60}
61
62/*! Decode Global Call Reference, 3GPP TS 29.205 Table B 2.1.9.1.
63 * \param[out] gcr Caller-provided memory to store Global Call Reference
64 * \param[in] elem IE value to be decoded
65 * \param[in] len Length of \a elem in bytes
66 * \returns number of bytes parsed; negative on error */
67int osmo_dec_gcr(struct osmo_gcr_parsed *gcr, const uint8_t *elem, uint8_t len)
68{
69 uint16_t parsed = 1; /* account for length byte right away */
70
71 if (len < 13)
72 return -EBADMSG;
73
74 gcr->net_len = elem[0];
75 if (gcr->net_len < 3 || gcr->net_len > 5)
76 return -EINVAL;
77
78 memcpy(gcr->net, elem + parsed, gcr->net_len);
79 /* +1 for ignored Node ID length field */
80 parsed += (gcr->net_len + 1);
81
82 gcr->node = osmo_load16be(elem + parsed);
83 parsed += 2;
84
85 if (elem[parsed] != 5) /* see Table B 2.1.9.2 */
86 return -ENOENT;
87
88 parsed++;
89
90 memcpy(gcr->cr, elem + parsed, 5);
91
92 return parsed + 5;
93}