Move include osmocom/gprs -> osmocom/gb, deprecate osmocom/gprs/

libosmogb is an anomaly since it has its headers in osmocom/gprs
directory instead of osmocom/gb. This is really confusing for users.
Furthermore, libosmo-gprs is also using osmocom/gprs, which will create
even more confusion.

This patch moves all existing osmocom/gprs/ header files under
osmocom/gb/ directory (except the backward-compat ones which were
added pointing to the ones in osmocom/gsm/).
Next, new files are added in osmocom/gprs/ replacing the ones that used
to be tehre, with a pragma message announcing deprecating and asking
users to use the new path instead.
This allows keeping old applications working, while announcing
deprecation of the old osmocom/gprs/ patch and have all new development
happen under osmocom/gb/.

Change-Id: I6e826775552766e34e4c06fe2390084596dfc286
This commit is contained in:
Pau Espin 2023-02-17 12:55:59 +01:00
parent 2bb8a1219c
commit 4941403274
65 changed files with 2072 additions and 1991 deletions

View File

@ -610,7 +610,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = @srcdir@/include/osmocom/gprs @srcdir@/src/gb
INPUT = @srcdir@/include/osmocom/gb @srcdir@/src/gb
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is

View File

@ -143,7 +143,7 @@ $(top_builddir)/doc/libosmoctrl.tag.prep: $(top_builddir)/Doxyfile.ctrl \
touch "$@"
$(top_builddir)/doc/libosmogb.tag.prep: $(top_builddir)/Doxyfile.gb \
$(top_srcdir)/include/osmocom/gprs/*.h \
$(top_srcdir)/include/osmocom/gb/*.h \
$(top_srcdir)/src/gb/*.[hc]
rm -rf $(top_builddir)/doc/gb; mkdir -p $(top_builddir)/doc/gb
rm -rf $(top_builddir)/doc/libosmogb.map

View File

@ -594,6 +594,8 @@ AC_OUTPUT(
include/osmocom/core/Makefile
include/osmocom/crypt/Makefile
include/osmocom/ctrl/Makefile
include/osmocom/gb/Makefile
include/osmocom/gb/protocol/Makefile
include/osmocom/gprs/Makefile
include/osmocom/gprs/protocol/Makefile
include/osmocom/gsm/Makefile

View File

@ -433,6 +433,7 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
%defattr(-,root,root)
%dir %_includedir/%name
%dir %_includedir/%name/osmocom
%_includedir/%name/osmocom/gb/
%_includedir/%name/osmocom/gprs/
%_libdir/libosmogb.so
%_libdir/pkgconfig/libosmogb.pc

View File

@ -6,6 +6,7 @@ SUBDIRS = \
isdn \
crypt \
coding \
gb \
gprs \
ctrl \
sim \

View File

@ -0,0 +1,16 @@
SUBDIRS = protocol
osmogb_HEADERS = \
frame_relay.h \
bssgp_bvc_fsm.h \
gprs_bssgp.h \
gprs_bssgp2.h \
gprs_bssgp_bss.h \
gprs_bssgp_rim.h \
gprs_msgb.h \
gprs_ns.h \
gprs_ns_frgre.h \
gprs_ns2.h \
$(NULL)
osmogbdir = $(includedir)/osmocom/gb

View File

@ -0,0 +1,71 @@
#pragma once
#include <stdint.h>
struct gprs_ns2_inst;
struct osmo_fsm_inst;
struct gprs_ra_id;
struct bssgp2_flow_ctrl;
enum bssp_ptp_bvc_fsm_state {
BSSGP_BVCFSM_S_NULL,
BSSGP_BVCFSM_S_BLOCKED,
BSSGP_BVCFSM_S_WAIT_RESET_ACK,
BSSGP_BVCFSM_S_UNBLOCKED,
};
enum bssgp_ptp_bvc_fsm_event {
/* Rx of BSSGP PDUs from the remote side; 'data' is 'struct tlv_parsed', and
* the assumption is that the caller has already validated all mandatory IEs
* are present and of sufficient length */
BSSGP_BVCFSM_E_RX_BLOCK,
BSSGP_BVCFSM_E_RX_BLOCK_ACK,
BSSGP_BVCFSM_E_RX_UNBLOCK,
BSSGP_BVCFSM_E_RX_UNBLOCK_ACK,
BSSGP_BVCFSM_E_RX_RESET,
BSSGP_BVCFSM_E_RX_RESET_ACK,
BSSGP_BVCFSM_E_RX_FC_BVC,
BSSGP_BVCFSM_E_RX_FC_BVC_ACK,
/* Requests of the local user */
BSSGP_BVCFSM_E_REQ_BLOCK, /* data: uint8_t *cause */
BSSGP_BVCFSM_E_REQ_UNBLOCK,
BSSGP_BVCFSM_E_REQ_RESET, /* data: uint8_t *cause */
BSSGP_BVCFSM_E_REQ_FC_BVC, /* data: struct bssgp2_flow_ctrl */
};
struct bssgp_bvc_fsm_ops {
/* call-back notifying the user of a state change */
void (*state_chg_notification)(uint16_t nsei, uint16_t bvci, int old_state, int new_state,
void *priv);
/* call-back notifying the user of a BVC-RESET event */
void (*reset_notification)(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
uint16_t cell_id, uint8_t cause, void *priv);
void (*rx_fc_bvc)(uint16_t nsei, uint16_t bvci, const struct bssgp2_flow_ctrl *fc, void *priv);
void (*reset_ack_notification)(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
uint16_t cell_id, uint8_t cause, void *priv);
};
struct osmo_fsm_inst *
bssgp_bvc_fsm_alloc_sig_bss(void *ctx, struct gprs_ns2_inst *nsi, uint16_t nsei, uint32_t features);
struct osmo_fsm_inst *
bssgp_bvc_fsm_alloc_ptp_bss(void *ctx, struct gprs_ns2_inst *nsi, uint16_t nsei, uint16_t bvci,
const struct gprs_ra_id *ra_id, uint16_t cell_id);
struct osmo_fsm_inst *
bssgp_bvc_fsm_alloc_sig_sgsn(void *ctx, struct gprs_ns2_inst *nsi, uint16_t nsei, uint32_t features);
struct osmo_fsm_inst *
bssgp_bvc_fsm_alloc_ptp_sgsn(void *ctx, struct gprs_ns2_inst *nsi, uint16_t nsei, uint16_t bvci);
void bssgp_bvc_fsm_set_ops(struct osmo_fsm_inst *fi, const struct bssgp_bvc_fsm_ops *ops, void *ops_priv);
bool bssgp_bvc_fsm_is_unblocked(struct osmo_fsm_inst *fi);
uint8_t bssgp_bvc_fsm_get_block_cause(struct osmo_fsm_inst *fi);
uint32_t bssgp_bvc_fsm_get_features_advertised(struct osmo_fsm_inst *fi);
uint32_t bssgp_bvc_fsm_get_features_received(struct osmo_fsm_inst *fi);
uint32_t bssgp_bvc_fsm_get_features_negotiated(struct osmo_fsm_inst *fi);
void bssgp_bvc_fsm_set_max_pdu_len(struct osmo_fsm_inst *fi, uint16_t max_pdu_len);
uint16_t bssgp_bvc_fsm_get_max_pdu_len(const struct osmo_fsm_inst *fi);

View File

@ -0,0 +1,152 @@
/*! \file frame_relay.h */
/* (C) 2020 Harald Welte <laforge@gnumonks.org>
* (C) 2020 sysmocom - s.f.m.c. GmbH
* Author: Alexander Couzens <lynxis@fe80.eu>
*
* All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/utils.h>
#include <stdint.h>
struct osmo_tdef;
struct msgb;
struct vty;
enum osmo_fr_role {
FR_ROLE_USER_EQUIPMENT,
FR_ROLE_NETWORK_EQUIPMENT,
};
/* 48.016 § 6.1.4.2 default maximum information field size of 1600 octets */
#define FRAME_RELAY_MTU 1600
/* FR DLC header is 2 byte */
#define FRAME_RELAY_SDU (FRAME_RELAY_MTU - 2)
extern const struct value_string osmo_fr_role_names[];
static inline const char *osmo_fr_role_str(enum osmo_fr_role role)
{
return get_value_string(osmo_fr_role_names, role);
}
struct osmo_fr_network {
struct llist_head links;
unsigned int n391; /* full status polling counter */
unsigned int n392; /* error threshold */
unsigned int n393; /* monitored events count */
struct osmo_tdef *T_defs; /* T391, T392 */
};
struct osmo_fr_dlc;
/* Frame Relay Link */
struct osmo_fr_link {
/* list in osmo_fr_network.links */
struct llist_head list;
struct osmo_fr_network *net;
enum osmo_fr_role role;
/* human-readable name */
const char *name;
/* value of the last received send sequence number field in the
* link integrity verification information element */
uint8_t last_rx_seq;
/* value of the send sequence number field of the last link
* integrity verification information element sent */
uint8_t last_tx_seq;
struct osmo_timer_list t391;
struct osmo_timer_list t392;
unsigned int polling_count;
unsigned int err_count;
unsigned int succeed;
/* the type of the last status enquiry */
uint8_t expected_rep;
bool state;
/* list of data link connections at this link */
struct llist_head dlc_list;
/* optional call-back to be called for each PDU received on an unknown DLC */
int (*unknown_dlc_rx_cb)(void *cb_data, struct msgb *msg);
void *unknown_dlc_rx_cb_data;
/* call-back to be called for transmitting on the underlying hardware */
int (*tx_cb)(void *data, struct msgb *msg);
/* optional call-back to be called each time the status changes active/inactive */
void (*status_cb)(struct osmo_fr_link *link, void *cb_data, bool active);
void *cb_data;
};
/* Frame Relay Data Link Connection */
struct osmo_fr_dlc {
/* entry in fr_link.dlc_list */
struct llist_head list;
struct osmo_fr_link *link;
uint16_t dlci;
/* is this DLC marked active for traffic? */
bool active;
/* was this DLC newly added? */
bool add;
/* is this DLC about to be destroyed */
bool del;
/* The local state needs to be transferred to the USER;
* NET must wait until USER confirms it implicitly by a seq number check */
bool state_send;
/* call-back to be called for each PDU received on this DLC */
int (*rx_cb)(void *cb_data, struct msgb *msg);
/* optional call-back to be called each time the status changes active/inactive */
void (*status_cb)(struct osmo_fr_dlc *dlc, void *cb_data, bool active);
void *cb_data;
};
/* allocate a frame relay network */
struct osmo_fr_network *osmo_fr_network_alloc(void *ctx);
void osmo_fr_network_free(struct osmo_fr_network *net);
void osmo_fr_network_dump_vty(struct vty *vty, const struct osmo_fr_network *net);
/* allocate a frame relay link in a given network */
struct osmo_fr_link *osmo_fr_link_alloc(struct osmo_fr_network *net, enum osmo_fr_role role, const char *name);
/* free a frame link in a given network */
void osmo_fr_link_free(struct osmo_fr_link *link);
/* allocate a data link connectoin on a given framerelay link */
struct osmo_fr_dlc *osmo_fr_dlc_alloc(struct osmo_fr_link *link, uint16_t dlci);
void osmo_fr_dlc_free(struct osmo_fr_dlc *dlc);
struct osmo_fr_dlc *osmo_fr_dlc_by_dlci(struct osmo_fr_link *link, uint16_t dlci);
int osmo_fr_rx(struct msgb *msg);
int osmo_fr_tx_dlc(struct msgb *msg);

View File

@ -0,0 +1,246 @@
/*! \file gprs_bssgp.h */
#pragma once
#include <stdint.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/prim.h>
#include <osmocom/gb/protocol/gsm_08_18.h>
#include <osmocom/gb/protocol/gsm_24_301.h>
#include <osmocom/gb/gprs_bssgp_rim.h>
/* gprs_bssgp_util.c */
#define BSSGP_PDUF_UL 0x0001 /* PDU may occur in uplink */
#define BSSGP_PDUF_DL 0x0002 /* PDU may occur in downlink */
#define BSSGP_PDUF_SIG 0x0004 /* PDU may occur on Signaling BVC */
#define BSSGP_PDUF_PTP 0x0008 /* PDU may occur on PTP BVC */
#define BSSGP_PDUF_PTM 0x0010 /* PDU may occur on PTM BVC */
extern const struct osmo_tlv_prot_def osmo_pdef_bssgp;
/*! return the PDU type flags (UL/DL/SIG/PTP/PTM) of specified PDU type */
static inline uint32_t bssgp_pdu_type_flags(uint8_t pdu_type)
{
return osmo_tlv_prot_msgt_flags(&osmo_pdef_bssgp, pdu_type);
}
typedef int (*bssgp_bvc_send)(void *ctx, struct msgb *msg);
extern struct gprs_ns_inst *bssgp_nsi;
void bssgp_set_bssgp_callback(bssgp_bvc_send ns_send, void *data);
struct msgb *bssgp_msgb_alloc(void);
struct msgb *bssgp_msgb_copy(const struct msgb *msg, const char *name);
const char *bssgp_cause_str(enum gprs_bssgp_cause cause);
const char *bssgp_pdu_str(enum bssgp_pdu_type pdu);
int bssgp_tx_bvc_reset_nsei_bvci(uint16_t nsei, uint16_t bvci, enum gprs_bssgp_cause cause, const struct gprs_ra_id *ra_id, uint16_t cell_id);
/* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */
int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
uint16_t bvci, uint16_t ns_bvci);
/* Chapter 10.4.14: Status */
int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);
enum bssgp_prim {
PRIM_BSSGP_DL_UD,
PRIM_BSSGP_UL_UD,
PRIM_BSSGP_PTM_UD,
PRIM_BSSGP_GMM_SUSPEND,
PRIM_BSSGP_GMM_RESUME,
PRIM_BSSGP_GMM_PAGING,
PRIM_NM_FLUSH_LL,
PRIM_NM_LLC_DISCARDED,
PRIM_NM_BVC_RESET,
PRIM_NM_BVC_BLOCK,
PRIM_NM_BVC_UNBLOCK,
PRIM_NM_STATUS,
PRIM_BSSGP_RIM_PDU_TRANSFER,
};
struct osmo_bssgp_prim {
struct osmo_prim_hdr oph;
/* common fields */
uint16_t nsei;
uint16_t bvci;
uint32_t tlli;
struct tlv_parsed *tp;
struct gprs_ra_id *ra_id;
/* specific fields */
union {
struct {
uint8_t suspend_ref;
} resume;
struct bssgp_ran_information_pdu rim_pdu;
} u;
};
/* gprs_bssgp.c */
/*! BSSGP flow control (SGSN side) According to Section 8.2 */
struct bssgp_flow_control {
uint32_t bucket_size_max; /*!< maximum size of the bucket (octets) */
uint32_t bucket_leak_rate; /*!< leak rate of the bucket (octets/sec) */
uint32_t bucket_counter; /*!< number of tokens in the bucket */
struct timeval time_last_pdu; /*!< timestamp of last PDU sent */
/* the built-in queue */
uint32_t max_queue_depth; /*!< how many packets to queue (mgs) */
uint32_t queue_depth; /*!< current length of queue (msgs) */
struct llist_head queue; /*!< linked list of msgb's */
struct osmo_timer_list timer; /*!< timer-based dequeueing */
/*! callback to be called at output of flow control */
int (*out_cb)(struct bssgp_flow_control *fc, struct msgb *msg,
uint32_t llc_pdu_len, void *priv);
};
#define BVC_S_BLOCKED 0x0001
/* The per-BTS context that we keep on the SGSN side of the BSSGP link */
struct bssgp_bvc_ctx {
struct llist_head list;
struct gprs_ra_id ra_id; /*!< parsed RA ID of the remote BTS */
uint16_t cell_id; /*!< Cell ID of the remote BTS */
/* NSEI and BVCI of underlying Gb link. Together they
* uniquely identify a link to a BTS (5.4.4) */
uint16_t bvci;
uint16_t nsei;
uint32_t state;
struct rate_ctr_group *ctrg;
struct bssgp_flow_control *fc;
/*! default maximum size of per-MS bucket in octets */
uint32_t bmax_default_ms;
/*! default bucket leak rate of per-MS bucket in octests/s */
uint32_t r_default_ms;
/*! BSS or SGSN. This defines the local state. */
bool is_sgsn;
/* we might want to add this as a shortcut later, avoiding the NSVC
* lookup for every packet, similar to a routing cache */
//struct gprs_nsvc *nsvc;
};
extern struct llist_head bssgp_bvc_ctxts;
/* Create a BTS Context with BVCI+NSEI */
struct bssgp_bvc_ctx *btsctx_alloc(uint16_t bvci, uint16_t nsei);
/* Find a BTS Context based on parsed RA ID and Cell ID */
struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t cid);
/* Find a BTS context based on BVCI+NSEI tuple */
struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei);
/* Free a given BTS context */
void bssgp_bvc_ctx_free(struct bssgp_bvc_ctx *ctx);
#define BVC_F_BLOCKED 0x0001
enum bssgp_ctr {
BSSGP_CTR_PKTS_IN,
BSSGP_CTR_PKTS_OUT,
BSSGP_CTR_BYTES_IN,
BSSGP_CTR_BYTES_OUT,
BSSGP_CTR_BLOCKED,
BSSGP_CTR_DISCARDED,
BSSGP_CTR_STATUS,
};
#include <osmocom/gsm/tlv.h>
#include <osmocom/gb/gprs_msgb.h>
/* BSSGP-UL-UNITDATA.ind */
int bssgp_rcvmsg(struct msgb *msg);
/* BSSGP-DL-UNITDATA.req */
struct bssgp_lv {
uint16_t len;
uint8_t *v;
};
/* parameters for BSSGP downlink userdata transmission */
struct bssgp_dl_ud_par {
uint32_t *tlli;
char *imsi;
struct bssgp_flow_control *fc;
uint16_t drx_parms;
/* FIXME: priority */
struct bssgp_lv ms_ra_cap;
uint8_t qos_profile[3];
};
int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
struct bssgp_dl_ud_par *dup);
uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf);
int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid,
uint16_t cid);
/* Wrapper around TLV parser to parse BSSGP IEs */
static inline int bssgp_tlv_parse(struct tlv_parsed *tp, const uint8_t *buf, int len)
{
return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0);
}
/*! BSSGP Paging mode */
enum bssgp_paging_mode {
BSSGP_PAGING_PS,
BSSGP_PAGING_CS,
};
/*! BSSGP Paging scope */
enum bssgp_paging_scope {
BSSGP_PAGING_BSS_AREA, /*!< all cells in BSS */
BSSGP_PAGING_LOCATION_AREA, /*!< all cells in LA */
BSSGP_PAGING_ROUTEING_AREA, /*!< all cells in RA */
BSSGP_PAGING_BVCI, /*!< one cell */
};
/*! BSSGP paging information */
struct bssgp_paging_info {
enum bssgp_paging_mode mode; /*!< CS or PS paging */
enum bssgp_paging_scope scope; /*!< bssgp_paging_scope */
struct gprs_ra_id raid; /*!< RA Identifier */
uint16_t bvci; /*!< BVCI */
char *imsi; /*!< IMSI, if any */
uint32_t *ptmsi; /*!< P-TMSI, if any */
uint16_t drx_params; /*!< DRX parameters */
uint8_t qos[3]; /*!< QoS parameters */
};
/* Send a single GMM-PAGING.req to a given NSEI/NS-BVCI */
int bssgp_tx_paging(uint16_t nsei, uint16_t ns_bvci,
struct bssgp_paging_info *pinfo);
void bssgp_fc_init(struct bssgp_flow_control *fc,
uint32_t bucket_size_max, uint32_t bucket_leak_rate,
uint32_t max_queue_depth,
int (*out_cb)(struct bssgp_flow_control *fc, struct msgb *msg,
uint32_t llc_pdu_len, void *priv));
/* input function of the flow control implementation, called first
* for the MM flow control, and then as the MM flow control output
* callback in order to perform BVC flow control */
int bssgp_fc_in(struct bssgp_flow_control *fc, struct msgb *msg,
uint32_t llc_pdu_len, void *priv);
/* Initialize the Flow Control parameters for a new MS according to
* default values for the BVC specified by BVCI and NSEI */
int bssgp_fc_ms_init(struct bssgp_flow_control *fc_ms, uint16_t bvci,
uint16_t nsei, uint32_t max_queue_depth);
void bssgp_flush_all_queues(void);
void bssgp_fc_flush_queue(struct bssgp_flow_control *fc);
/* gprs_bssgp_vty.c */
int bssgp_vty_init(void);
void bssgp_set_log_ss(int ss) OSMO_DEPRECATED("Use DLBSSGP instead!\n");
int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx);

View File

@ -0,0 +1,72 @@
#pragma once
#include <stdint.h>
#include <osmocom/gb/protocol/gsm_08_18.h>
#include <osmocom/gb/gprs_ns2.h>
struct bssgp2_flow_ctrl;
struct gprs_ns2_inst;
struct gprs_ra_id;
struct msgb;
struct bssgp2_flow_ctrl {
uint8_t tag;
/* maximum bucket size (Bmax) in bytes */
uint64_t bucket_size_max;
/*! bucket leak rate in _bytes_ per second */
uint64_t bucket_leak_rate;
/* percentage how full the given bucket is */
uint8_t bucket_full_ratio;
bool bucket_full_ratio_present;
union {
/*! FC-BVC specifi members */
struct {
/*! default maximum bucket size per MS in bytes */
uint64_t bmax_default_ms;
/*! default bucket leak rate (R) for MS flow control bucket */
uint64_t r_default_ms;
/*! average milliseconds of queueing delay for a BVC */
uint32_t measurement;
bool measurement_present;
} bvc;
/*! FC-MS specifi members */
struct {
/*! TLLI of the MS */
uint32_t tlli;
} ms;
} u;
};
int bssgp2_nsi_tx_ptp(struct gprs_ns2_inst *nsi, uint16_t nsei, uint16_t bvci,
struct msgb *msg, uint32_t lsp);
int bssgp2_nsi_tx_sig(struct gprs_ns2_inst *nsi, uint16_t nsei, struct msgb *msg, uint32_t lsp);
struct msgb *bssgp2_enc_bvc_block(uint16_t bvci, enum gprs_bssgp_cause cause);
struct msgb *bssgp2_enc_bvc_block_ack(uint16_t bvci);
struct msgb *bssgp2_enc_bvc_unblock(uint16_t bvci);
struct msgb *bssgp2_enc_bvc_unblock_ack(uint16_t bvci);
struct msgb *bssgp2_enc_bvc_reset(uint16_t bvci, enum gprs_bssgp_cause cause,
const struct gprs_ra_id *ra_id, uint16_t cell_id,
const uint8_t *feat_bm, const uint8_t *ext_feat_bm);
struct msgb *bssgp2_enc_bvc_reset_ack(uint16_t bvci, const struct gprs_ra_id *ra_id, uint16_t cell_id,
const uint8_t *feat_bm, const uint8_t *ext_feat_bm);
struct msgb *bssgp2_enc_flush_ll(uint32_t tlli, uint16_t old_bvci,
const uint16_t *new_bvci, const uint16_t *nsei);
struct msgb *bssgp2_enc_status(uint8_t cause, const uint16_t *bvci, const struct msgb *orig_msg, uint16_t max_pdu_len);
int bssgp2_dec_fc_bvc(struct bssgp2_flow_ctrl *fc, const struct tlv_parsed *tp);
struct msgb *bssgp2_enc_fc_bvc(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran);
struct msgb *bssgp2_enc_fc_bvc_ack(uint8_t tag);
int bssgp2_dec_fc_ms(struct bssgp2_flow_ctrl *fc, struct tlv_parsed *tp);
struct msgb *bssgp2_enc_fc_ms(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran);
struct msgb *bssgp2_enc_fc_ms_ack(uint32_t tlli, uint8_t tag);

View File

@ -0,0 +1,75 @@
/*! \file gprs_bssgp_bss.h
* GPRS BSSGP protocol implementation as per 3GPP TS 08.18 */
/*
* (C) 2009-2012 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <osmocom/core/msgb.h>
#include <osmocom/gb/gprs_bssgp.h>
uint8_t *bssgp_msgb_tlli_put(struct msgb *msg, uint32_t tlli);
uint8_t *bssgp_msgb_ra_put(struct msgb *msg, const struct gprs_ra_id *ra_id);
int bssgp_tx_bvc_ptp_reset(uint16_t nsei, enum gprs_bssgp_cause cause);
int bssgp_tx_suspend(uint16_t nsei, uint32_t tlli,
const struct gprs_ra_id *ra_id);
int bssgp_tx_resume(uint16_t nsei, uint32_t tlli,
const struct gprs_ra_id *ra_id, uint8_t suspend_ref);
int bssgp_tx_ra_capa_upd(struct bssgp_bvc_ctx *bctx, uint32_t tlli, uint8_t tag);
int bssgp_tx_radio_status_tlli(struct bssgp_bvc_ctx *bctx, uint8_t cause,
uint32_t tlli);
int bssgp_tx_radio_status_tmsi(struct bssgp_bvc_ctx *bctx, uint8_t cause,
uint32_t tmsi);
int bssgp_tx_radio_status_imsi(struct bssgp_bvc_ctx *bctx, uint8_t cause,
const char *imsi);
int bssgp_tx_flush_ll_ack(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
uint8_t action, uint16_t bvci_new,
uint32_t num_octets);
int bssgp_tx_llc_discarded(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
uint8_t num_frames, uint32_t num_octets);
int bssgp_tx_bvc_block(struct bssgp_bvc_ctx *bctx, uint8_t cause);
int bssgp_tx_bvc_unblock(struct bssgp_bvc_ctx *bctx);
int bssgp_tx_bvc_reset(struct bssgp_bvc_ctx *bctx, uint16_t bvci, uint8_t cause);
int bssgp_tx_bvc_reset2(struct bssgp_bvc_ctx *bctx, uint16_t bvci, uint8_t cause, bool add_cell_id);
int bssgp_tx_ul_ud(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
const uint8_t *qos_profile, struct msgb *llc_pdu);
int bssgp_rx_paging(struct bssgp_paging_info *pinfo,
struct msgb *msg);
int bssgp_tx_fc_bvc(struct bssgp_bvc_ctx *bctx, uint8_t tag,
uint32_t bucket_size, uint32_t bucket_leak_rate,
uint32_t bmax_default_ms, uint32_t r_default_ms,
uint8_t *bucket_full_ratio, uint32_t *queue_delay_ms);
int bssgp_tx_fc_ms(struct bssgp_bvc_ctx *bctx, uint32_t tlli, uint8_t tag,
uint32_t ms_bucket_size, uint32_t bucket_leak_rate,
uint8_t *bucket_full_ratio);

View File

@ -0,0 +1,272 @@
/*! \file gprs_bssgp.h
* GPRS BSSGP RIM protocol implementation as per 3GPP TS 48.018. */
/*
* (C) 2020-2021 by sysmocom - s.f.m.c. GmbH
* Author: Philipp Maier <pmaier@sysmocom.de>
*
* All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gb/protocol/gsm_08_18.h>
#include <osmocom/gb/protocol/gsm_24_301.h>
enum bssgp_rim_routing_info_discr {
BSSGP_RIM_ROUTING_INFO_GERAN,
BSSGP_RIM_ROUTING_INFO_UTRAN,
BSSGP_RIM_ROUTING_INFO_EUTRAN,
};
extern const struct value_string bssgp_rim_routing_info_discr_strs[];
/*! Obtain a human-readable string for NACC Cause code */
static inline const char *bssgp_rim_routing_info_discr_str(enum bssgp_rim_routing_info_discr val)
{ return get_value_string(bssgp_rim_routing_info_discr_strs, val); }
/*! BSSGP RIM Routing information, see also 3GPP TS 48.018, section 11.3.70 */
struct bssgp_rim_routing_info {
enum bssgp_rim_routing_info_discr discr;
union {
struct {
struct gprs_ra_id raid;
uint16_t cid;
} geran;
struct {
struct gprs_ra_id raid;
uint16_t rncid;
} utran;
struct {
struct osmo_eutran_tai tai;
/* See also 3GPP TS 36.413 9.2.1.37 and 3GPP TS 36.401 */
uint8_t global_enb_id[8];
uint8_t global_enb_id_len;
} eutran;
};
};
/* The encoded result of the rim routing information is, depending on the
* address type (discr) of variable length. */
#define BSSGP_RIM_ROUTING_INFO_MAXLEN 14
char *bssgp_rim_ri_name_buf(char *buf, size_t buf_len, const struct bssgp_rim_routing_info *ri);
const char *bssgp_rim_ri_name(const struct bssgp_rim_routing_info *ri);
int bssgp_parse_rim_ri(struct bssgp_rim_routing_info *ri, const uint8_t *buf, unsigned int len);
int bssgp_create_rim_ri(uint8_t *buf, const struct bssgp_rim_routing_info *ri);
/* 3GPP TS 48.018, table 11.3.63.1.1: RAN-INFORMATION-REQUEST Application Container coding for NACC */
struct bssgp_ran_inf_req_app_cont_nacc {
struct osmo_cell_global_id_ps reprt_cell;
};
int bssgp_dec_ran_inf_req_app_cont_nacc(struct bssgp_ran_inf_req_app_cont_nacc *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_req_app_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_ran_inf_req_app_cont_nacc *cont);
/* Length of NACC system information, see also: 3GPP TS 48.018 11.3.63.2.1 */
#define BSSGP_RIM_SI_LEN 21
#define BSSGP_RIM_PSI_LEN 22
/* 3GPP TS 48.018, table 11.3.63.2.1.a: RAN-INFORMATION Application Container coding for NACC */
struct bssgp_ran_inf_app_cont_nacc {
struct osmo_cell_global_id_ps reprt_cell;
bool type_psi;
uint8_t num_si;
/* Pointer to system information messages */
const uint8_t *si[127];
};
int bssgp_dec_ran_inf_app_cont_nacc(struct bssgp_ran_inf_app_cont_nacc *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_app_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_ran_inf_app_cont_nacc *cont);
/* 3GPP TS 48.018, table 11.3.64.1.b, NACC Cause coding */
enum bssgp_nacc_cause {
BSSGP_NACC_CAUSE_UNSPEC,
BSSGP_NACC_CAUSE_SYNTAX_ERR,
BSSGP_NACC_CAUSE_RPRT_CELL_MISSMTCH,
BSSGP_NACC_CAUSE_SIPSI_TYPE_ERR,
BSSGP_NACC_CAUSE_SIPSI_LEN_ERR,
BSSGP_NACC_CAUSE_SIPSI_SET_ERR,
};
extern const struct value_string bssgp_nacc_cause_strs[];
/*! Obtain a human-readable string for NACC Cause code */
static inline const char *bssgp_nacc_cause_str(enum bssgp_nacc_cause val)
{ return get_value_string(bssgp_nacc_cause_strs, val); }
/* 3GPP TS 48.018, table 11.3.64.1.a, Application Error Container coding for NACC */
struct bssgp_app_err_cont_nacc {
enum bssgp_nacc_cause nacc_cause;
/* Pointer to errornous application container */
const uint8_t *err_app_cont;
size_t err_app_cont_len;
};
int bssgp_dec_app_err_cont_nacc(struct bssgp_app_err_cont_nacc *cont, const uint8_t *buf, size_t len);
int bssgp_enc_app_err_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_app_err_cont_nacc *cont);
/* 3GPP TS 48.018, table 11.3.61.b: RIM Application Identity coding */
enum bssgp_ran_inf_app_id {
BSSGP_RAN_INF_APP_ID_NACC = 1,
BSSGP_RAN_INF_APP_ID_SI3 = 2,
BSSGP_RAN_INF_APP_ID_MBMS = 3,
BSSGP_RAN_INF_APP_ID_SON = 4,
BSSGP_RAN_INF_APP_ID_UTRA_SI = 5,
};
extern const struct value_string bssgp_ran_inf_app_id_strs[];
/*! Obtain a human-readable string for RIM Application Identity code */
static inline const char *bssgp_ran_inf_app_id_str(enum bssgp_ran_inf_app_id val)
{ return get_value_string(bssgp_ran_inf_app_id_strs, val); }
/* 3GPP TS 48.018, table 11.3.62a.1.b: RAN-INFORMATION-REQUEST RIM Container Contents */
struct bssgp_ran_inf_req_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint32_t seq_num;
struct bssgp_rim_pdu_ind pdu_ind;
uint8_t prot_ver;
/* Nested application container */
union {
struct bssgp_ran_inf_req_app_cont_nacc app_cont_nacc;
/* TODO: add containers for Si3, MBMS, SON, UTRA-SI */
} u;
/* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",
* see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */
const uint8_t *son_trans_app_id;
size_t son_trans_app_id_len;
};
int bssgp_dec_ran_inf_req_rim_cont(struct bssgp_ran_inf_req_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_req_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_req_rim_cont *cont);
/* 3GPP TS 48.018, table 11.3.62a.2.b: RAN-INFORMATION RIM Container Contents */
struct bssgp_ran_inf_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint32_t seq_num;
struct bssgp_rim_pdu_ind pdu_ind;
uint8_t prot_ver;
bool app_err;
/* Nested application container */
union {
struct bssgp_ran_inf_app_cont_nacc app_cont_nacc;
struct bssgp_app_err_cont_nacc app_err_cont_nacc;
/* TODO: add containers for Si3, MBMS, SON, UTRA-SI */
} u;
/* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",
* see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */
const uint8_t *son_trans_app_id;
size_t son_trans_app_id_len;
};
int bssgp_dec_ran_inf_rim_cont(struct bssgp_ran_inf_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_rim_cont *cont);
/* 3GPP TS 48.018, table 11.3.62a.3.b: RAN-INFORMATION-ACK RIM Container Contents */
struct bssgp_ran_inf_ack_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint32_t seq_num;
uint8_t prot_ver;
/* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",
* see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */
const uint8_t *son_trans_app_id;
size_t son_trans_app_id_len;
};
int bssgp_dec_ran_inf_ack_rim_cont(struct bssgp_ran_inf_ack_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_ack_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_ack_rim_cont *cont);
/* 3GPP TS 48.018, table 11.3.62a.4.b: RAN-INFORMATION-ERROR RIM Container Contents */
struct bssgp_ran_inf_err_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint8_t cause;
uint8_t prot_ver;
/* Pointer to (encoded) errornous PDU,
* see also: 3GPP TS 48.018, section 11.3.24 */
const uint8_t *err_pdu;
size_t err_pdu_len;
/* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",
* see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */
const uint8_t *son_trans_app_id;
size_t son_trans_app_id_len;
};
int bssgp_dec_ran_inf_err_rim_cont(struct bssgp_ran_inf_err_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_err_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_err_rim_cont *cont);
/* 3GPP TS 48.018, table 11.3.62a.5.b: RAN-INFORMATION-APPLICATION-ERROR RIM Container Contents */
struct bssgp_ran_inf_app_err_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint32_t seq_num;
struct bssgp_rim_pdu_ind pdu_ind;
uint8_t prot_ver;
/* Nested application container */
union {
struct bssgp_app_err_cont_nacc app_err_cont_nacc;
/* TODO: add containers for Si3, MBMS, SON, UTRA-SI */
} u;
};
int bssgp_dec_ran_inf_app_err_rim_cont(struct bssgp_ran_inf_app_err_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_app_err_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_app_err_rim_cont *cont);
/* Chapter 10.6.1: RAN-INFORMATION-REQUEST */
struct bssgp_ran_information_pdu {
struct bssgp_rim_routing_info routing_info_dest;
struct bssgp_rim_routing_info routing_info_src;
/* Encoded variant of the RIM container */
uint8_t rim_cont_iei;
const uint8_t *rim_cont;
unsigned int rim_cont_len;
/* Decoded variant of the RIM container */
bool decoded_present;
union {
struct bssgp_ran_inf_req_rim_cont req_rim_cont;
struct bssgp_ran_inf_rim_cont rim_cont;
struct bssgp_ran_inf_ack_rim_cont ack_rim_cont;
struct bssgp_ran_inf_err_rim_cont err_rim_cont;
struct bssgp_ran_inf_app_err_rim_cont app_err_rim_cont;
} decoded;
/* When receiving a PDU from BSSGP the encoded variant of the RIM
* container will always be present. The decoded variant will be
* present in addition whenever BSSGP was able to decode the container.
*
* When sending a PDU to BSSGP, then the decoded variant is used when
* it is available. The encoded variant (if present) will be ignored
* then. */
};
int bssgp_parse_rim_pdu(struct bssgp_ran_information_pdu *pdu, const struct msgb *msg);
struct msgb *bssgp_encode_rim_pdu(const struct bssgp_ran_information_pdu *pdu);
int bssgp_tx_rim(const struct bssgp_ran_information_pdu *pdu, uint16_t nsei);

View File

@ -0,0 +1,33 @@
/*! \file gprs_msgb.h */
#pragma once
#include <stdint.h>
/*! the data structure stored in msgb->cb for libgb apps */
struct libgb_msgb_cb {
unsigned char *bssgph;
unsigned char *llch;
/*! Cell Identifier */
unsigned char *bssgp_cell_id;
/*! Identifiers of a BTS, equal to 'struct bssgp_bts_ctx' */
uint16_t nsei;
uint16_t bvci;
/*! Identifier of a MS (inside BTS), equal to 'struct sgsn_mm_ctx' */
uint32_t tlli;
} __attribute__((packed, may_alias));
#define LIBGB_MSGB_CB(__msgb) ((struct libgb_msgb_cb *)&((__msgb)->cb[0]))
#define msgb_tlli(__x) LIBGB_MSGB_CB(__x)->tlli
#define msgb_nsei(__x) LIBGB_MSGB_CB(__x)->nsei
#define msgb_bvci(__x) LIBGB_MSGB_CB(__x)->bvci
#define msgb_gmmh(__x) (__x)->l3h
#define msgb_bssgph(__x) LIBGB_MSGB_CB(__x)->bssgph
#define msgb_bssgp_len(__x) ((__x)->tail - (uint8_t *)msgb_bssgph(__x))
#define msgb_bcid(__x) LIBGB_MSGB_CB(__x)->bssgp_cell_id
#define msgb_llch(__x) LIBGB_MSGB_CB(__x)->llch
#include <osmocom/core/logging.h>
int gprs_log_filter_fn(const struct log_context *ctx,
struct log_target *tar);

View File

@ -0,0 +1,258 @@
/*! \file gprs_ns.h */
#pragma once
#include <stdint.h>
/* Our Implementation */
#include <netinet/in.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/select.h>
#include <osmocom/gb/gprs_msgb.h>
#include <osmocom/gb/protocol/gsm_08_16.h>
#define NS_TIMERS_COUNT 8
#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov)"
#define NS_TIMERS_HELP \
"(un)blocking Timer (Tns-block) timeout\n" \
"(un)blocking Timer (Tns-block) number of retries\n" \
"Reset Timer (Tns-reset) timeout\n" \
"Reset Timer (Tns-reset) number of retries\n" \
"Test Timer (Tns-test) timeout\n" \
"Alive Timer (Tns-alive) timeout\n" \
"Alive Timer (Tns-alive) number of retries\n" \
"SNS Provision Timer (Tsns-prov) timeout\n"
/* Educated guess - LLC user payload is 1500 bytes plus possible headers */
#define NS_ALLOC_SIZE 3072
#define NS_ALLOC_HEADROOM 20
enum ns_timeout {
NS_TOUT_TNS_BLOCK,
NS_TOUT_TNS_BLOCK_RETRIES,
NS_TOUT_TNS_RESET,
NS_TOUT_TNS_RESET_RETRIES,
NS_TOUT_TNS_TEST,
NS_TOUT_TNS_ALIVE,
NS_TOUT_TNS_ALIVE_RETRIES,
NS_TOUT_TSNS_PROV,
};
#define NSE_S_BLOCKED 0x0001
#define NSE_S_ALIVE 0x0002
#define NSE_S_RESET 0x0004
#define NS_DESC_B(st) ((st) & NSE_S_BLOCKED ? "BLOCKED" : "UNBLOCKED")
#define NS_DESC_A(st) ((st) & NSE_S_ALIVE ? "ALIVE" : "DEAD")
#define NS_DESC_R(st) ((st) & NSE_S_RESET ? "RESET" : "UNRESET")
/*! Osmocom NS link layer types */
enum gprs_ns_ll {
GPRS_NS_LL_UDP, /*!< NS/UDP/IP */
GPRS_NS_LL_E1, /*!< NS/E1 */
GPRS_NS_LL_FR_GRE, /*!< NS/FR/GRE/IP */
};
/*! Osmoco NS events */
enum gprs_ns_evt {
GPRS_NS_EVT_UNIT_DATA,
};
/*! Osmocom NS VC create status */
enum gprs_ns_cs {
GPRS_NS_CS_CREATED, /*!< A NSVC object has been created */
GPRS_NS_CS_FOUND, /*!< A NSVC object has been found */
GPRS_NS_CS_REJECTED, /*!< Rejected and answered message */
GPRS_NS_CS_SKIPPED, /*!< Skipped message */
GPRS_NS_CS_ERROR, /*!< Failed to process message */
};
struct gprs_nsvc;
/*! Osmocom GPRS callback function type */
typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
struct msgb *msg, uint16_t bvci);
/*! An instance of the NS protocol stack */
struct gprs_ns_inst {
/*! callback to the user for incoming UNIT DATA IND */
gprs_ns_cb_t *cb;
/*! linked lists of all NSVC in this instance */
struct llist_head gprs_nsvcs;
/*! a NSVC object that's needed to deal with packets for
* unknown NSVC */
struct gprs_nsvc *unknown_nsvc;
uint16_t timeout[NS_TIMERS_COUNT];
/*! NS-over-IP specific bits */
struct {
struct osmo_fd fd;
uint32_t local_ip;
uint16_t local_port;
uint32_t remote_ip;
uint16_t remote_port;
int dscp;
/*! IPA compatibility: NS-RESET/BLOCK/UNBLOCK even on IP-SNS */
bool use_reset_block_unblock;
} nsip;
/*! NS-over-FR-over-GRE-over-IP specific bits */
struct {
struct osmo_fd fd;
uint32_t local_ip;
unsigned int enabled:1;
} frgre;
struct osmo_fsm_inst *bss_sns_fi;
};
enum nsvc_timer_mode {
/* standard timers */
NSVC_TIMER_TNS_TEST,
NSVC_TIMER_TNS_ALIVE,
NSVC_TIMER_TNS_RESET,
_NSVC_TIMER_NR,
};
/*! Structure representing a single NS-VC */
struct gprs_nsvc {
/*! list of NS-VCs within NS Instance */
struct llist_head list;
/*! pointer to NS Instance */
struct gprs_ns_inst *nsi;
uint16_t nsei; /*! end-to-end significance */
uint16_t nsvci; /*! uniquely identifies NS-VC at SGSN */
uint32_t state;
uint32_t remote_state;
struct osmo_timer_list timer;
enum nsvc_timer_mode timer_mode;
struct timeval timer_started;
int alive_retries;
unsigned int remote_end_is_sgsn:1;
unsigned int persistent:1;
unsigned int nsvci_is_valid:1;
struct rate_ctr_group *ctrg;
struct osmo_stat_item_group *statg;
/*! which link-layer are we based on? */
enum gprs_ns_ll ll;
/*! make sure to always keep bts_addr as first struct member to not break the assumption
that those structs are similar */
union {
struct {
struct sockaddr_in bts_addr;
} ip;
struct {
struct sockaddr_in bts_addr;
} frgre;
};
/*! signalling weight. 0 = don't use for signalling (BVCI == 0)*/
uint8_t sig_weight;
/*! signaling weight. 0 = don't use for user data (BVCI != 0) */
uint8_t data_weight;
};
/* Create a new NS protocol instance */
struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb, void *ctx);
/* Close a NS protocol instance */
void gprs_ns_close(struct gprs_ns_inst *nsi);
/* Close and Destroy a NS protocol instance */
void gprs_ns_destroy(struct gprs_ns_inst *nsi);
/* Listen for incoming GPRS packets via NS/UDP */
int gprs_ns_nsip_listen(struct gprs_ns_inst *nsi);
/* Establish a connection (from the BSS) to the SGSN */
struct gprs_nsvc *gprs_ns_nsip_connect(struct gprs_ns_inst *nsi,
struct sockaddr_in *dest,
uint16_t nsei, uint16_t nsvci);
/* Establish a connection (from the BSS) to the SGSN using IP SNS */
struct gprs_nsvc *gprs_ns_nsip_connect_sns(struct gprs_ns_inst *nsi, struct sockaddr_in *dest,
uint16_t nsei, uint16_t nsvci);
struct sockaddr_in;
/* main function for higher layers (BSSGP) to send NS messages */
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
/* Receive incoming NS message from underlying transport layer */
int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
struct sockaddr_in *saddr, enum gprs_ns_ll ll);
int gprs_ns_tx_alive(struct gprs_nsvc *nsvc);
int gprs_ns_tx_alive_ack(struct gprs_nsvc *nsvc);
int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause);
int gprs_ns_tx_block(struct gprs_nsvc *nsvc, uint8_t cause);
int gprs_ns_tx_unblock(struct gprs_nsvc *nsvc);
/* Listen for incoming GPRS packets via NS/FR/GRE */
int gprs_ns_frgre_listen(struct gprs_ns_inst *nsi);
struct gprs_nsvc *gprs_nsvc_create2(struct gprs_ns_inst *nsi, uint16_t nsvci,
uint8_t sig_weight, uint8_t data_weight);
void gprs_nsvc_delete(struct gprs_nsvc *nsvc);
struct gprs_nsvc *gprs_nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
struct gprs_nsvc *gprs_nsvc_by_nsvci(struct gprs_ns_inst *nsi, uint16_t nsvci);
struct gprs_nsvc *gprs_nsvc_by_rem_addr(struct gprs_ns_inst *nsi, const struct sockaddr_in *sin);
/* Initiate a RESET procedure (including timer start, ...)*/
int gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause);
/* Add NS-specific VTY stuff */
int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
/* Resturn peer info as string (NOTE: the buffer is allocated statically) */
const char *gprs_ns_ll_str(const struct gprs_nsvc *nsvc);
/* Return peer info in user-supplied buffer */
char *gprs_ns_ll_str_buf(char *buf, size_t buf_len, const struct gprs_nsvc *nsvc);
char *gprs_ns_ll_str_c(const void *ctx, const struct gprs_nsvc *nsvc);
/* Copy the link layer info from other into nsvc */
void gprs_ns_ll_copy(struct gprs_nsvc *nsvc, struct gprs_nsvc *other);
/* Clear the link layer info (will never match a real link then) */
void gprs_ns_ll_clear(struct gprs_nsvc *nsvc);
struct msgb *gprs_ns_msgb_alloc(void);
enum signal_ns {
S_NS_RESET,
S_NS_BLOCK,
S_NS_UNBLOCK,
S_NS_ALIVE_EXP, /* Tns-alive expired more than N times */
S_NS_REPLACED, /* nsvc object is replaced (sets old_nsvc) */
S_NS_MISMATCH, /* got an unexpected IE (sets msg, pdu_type, ie_type) */
S_SNS_CONFIGURED, /* IP-SNS configuration completed */
};
extern const struct value_string gprs_ns_signal_ns_names[];
const char *gprs_ns_cause_str(enum ns_cause cause);
struct ns_signal_data {
struct gprs_nsvc *nsvc;
struct gprs_nsvc *old_nsvc;
uint8_t cause;
uint8_t pdu_type;
uint8_t ie_type;
struct msgb *msg;
};
void gprs_ns_set_log_ss(int ss);
char *gprs_nsvc_state_append(char *s, struct gprs_nsvc *nsvc);
/*! @} */

View File

@ -0,0 +1,276 @@
/*! \file gprs_ns2.h */
#pragma once
#include <stdint.h>
#include <netinet/in.h>
#include <osmocom/core/prim.h>
#include <osmocom/gb/protocol/gsm_08_16.h>
#include <osmocom/gb/frame_relay.h>
struct osmo_sockaddr;
struct osmo_sockaddr_str;
struct osmo_fr_network;
struct gprs_ns2_inst;
struct gprs_ns2_nse;
struct gprs_ns2_vc;
struct gprs_ns2_vc_bind;
struct gprs_ns2_vc_driver;
struct gprs_ns_ie_ip4_elem;
struct gprs_ns_ie_ip6_elem;
enum gprs_ns2_vc_mode {
/*! The VC will use RESET/BLOCK/UNBLOCK to start the connection and do ALIVE/ACK.
* This is what is needed for Frame Relay transport, and if you use a R97/R99 Gb
* interface over an IP transport (never standardized by 3GPP) */
GPRS_NS2_VC_MODE_BLOCKRESET,
/*! The VC will only use ALIVE/ACK (no RESET/BLOCK/UNBLOCK), which is for Gb-IP
* interface compliant to 3GPP Rel=4 or later. */
GPRS_NS2_VC_MODE_ALIVE,
};
enum gprs_ns2_dialect {
GPRS_NS2_DIALECT_UNDEF,
GPRS_NS2_DIALECT_STATIC_ALIVE,
GPRS_NS2_DIALECT_STATIC_RESETBLOCK,
GPRS_NS2_DIALECT_IPACCESS,
GPRS_NS2_DIALECT_SNS,
};
/*! Osmocom NS link layer types */
enum gprs_ns2_ll {
GPRS_NS2_LL_UNDEF, /*!< undefined, used by vty */
GPRS_NS2_LL_UDP, /*!< NS/UDP/IP */
GPRS_NS2_LL_FR, /*!< NS/FR */
GPRS_NS2_LL_FR_GRE, /*!< NS/FR/GRE/IP */
};
/*! Osmocom NS primitives according to 48.016 5.2 Service primitives */
enum gprs_ns2_prim {
GPRS_NS2_PRIM_UNIT_DATA,
GPRS_NS2_PRIM_CONGESTION,
GPRS_NS2_PRIM_STATUS,
};
extern const struct value_string gprs_ns2_prim_strs[];
extern const struct value_string gprs_ns2_lltype_strs[];
/*! Obtain a human-readable string for NS primitives */
static inline const char *gprs_ns2_prim_str(enum gprs_ns2_prim val)
{ return get_value_string(gprs_ns2_prim_strs, val); }
/*! Obtain a human-readable string for NS link-layer type */
static inline const char *gprs_ns2_lltype_str(enum gprs_ns2_ll val)
{ return get_value_string(gprs_ns2_lltype_strs, val); }
/*! Osmocom NS primitives according to 48.016 5.2.2.4 Service primitives */
enum gprs_ns2_congestion_cause {
GPRS_NS2_CONG_CAUSE_BACKWARD_BEGIN,
GPRS_NS2_CONG_CAUSE_BACKWARD_END,
GPRS_NS2_CONG_CAUSE_FORWARD_BEGIN,
GPRS_NS2_CONG_CAUSE_FORWARD_END,
};
/*! Osmocom NS primitives according to 48.016 5.2.2.6 Service primitives */
enum gprs_ns2_affecting_cause {
GPRS_NS2_AFF_CAUSE_VC_FAILURE,
GPRS_NS2_AFF_CAUSE_VC_RECOVERY,
GPRS_NS2_AFF_CAUSE_FAILURE,
GPRS_NS2_AFF_CAUSE_RECOVERY,
/* osmocom own causes */
GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED,
GPRS_NS2_AFF_CAUSE_SNS_FAILURE,
GPRS_NS2_AFF_CAUSE_SNS_NO_ENDPOINTS,
GPRS_NS2_AFF_CAUSE_MTU_CHANGE,
};
extern const struct value_string gprs_ns2_aff_cause_prim_strs[];
/*! Obtain a human-readable string for NS affecting cause in primitives */
static inline const char *gprs_ns2_aff_cause_prim_str(enum gprs_ns2_affecting_cause val)
{ return get_value_string(gprs_ns2_aff_cause_prim_strs, val); }
/*! Osmocom NS primitives according to 48.016 5.2.2.7 Service primitives */
enum gprs_ns2_change_ip_endpoint {
GRPS_NS2_ENDPOINT_NO_CHANGE,
GPRS_NS2_ENDPOINT_REQUEST_CHANGE,
GPRS_NS2_ENDPOINT_CONFIRM_CHANGE,
};
extern const struct value_string gprs_ns2_cause_strs[];
/*! Obtain a human-readable string for NS primitives */
static inline const char *gprs_ns2_cause_str(enum ns_cause val)
{ return get_value_string(gprs_ns2_cause_strs, val); }
struct osmo_gprs_ns2_prim {
struct osmo_prim_hdr oph;
uint16_t nsei;
uint16_t bvci;
union {
struct {
enum gprs_ns2_change_ip_endpoint change;
uint32_t link_selector;
/* TODO: implement resource distribution
* add place holder for the link selector */
long long _resource_distribution_placeholder1;
long long _resource_distribution_placeholder2;
long long _resource_distribution_placeholder3;
} unitdata;
struct {
enum gprs_ns2_congestion_cause cause;
} congestion;
struct {
enum gprs_ns2_affecting_cause cause;
char *nsvc;
/* 48.016 5.2.2.6 transfer capability */
int transfer;
/* osmocom specific */
/* Persistent NSE/NSVC are configured by vty */
bool persistent;
/* Only true on the first time it's available.
* Allow the BSSGP layer to reset persistent NSE */
bool first;
/* MTU of a NS SDU. It's the lowest MTU of all (alive & dead) NSVCs */
uint16_t mtu;
} status;
} u;
};
/* instance */
struct gprs_ns2_inst *gprs_ns2_instantiate(void *ctx, osmo_prim_cb cb, void *cb_data);
void gprs_ns2_free(struct gprs_ns2_inst *inst);
/* Entrypoint for primitives from the NS USER */
int gprs_ns2_recv_prim(struct gprs_ns2_inst *nsi, struct osmo_prim_hdr *oph);
/*! a callback to iterate over all NSVC */
typedef int (*gprs_ns2_foreach_nsvc_cb)(struct gprs_ns2_vc *nsvc, void *ctx);
int gprs_ns2_nse_foreach_nsvc(struct gprs_ns2_nse *nse,
gprs_ns2_foreach_nsvc_cb cb, void *cb_data);
struct gprs_ns2_nse *gprs_ns2_nse_by_nsei(struct gprs_ns2_inst *nsi, uint16_t nsei);
struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t nsei,
enum gprs_ns2_ll linklayer,
enum gprs_ns2_dialect dialect);
struct gprs_ns2_nse *gprs_ns2_create_nse2(struct gprs_ns2_inst *nsi, uint16_t nsei,
enum gprs_ns2_ll linklayer,
enum gprs_ns2_dialect dialect, bool local_sgsn_role);
uint16_t gprs_ns2_nse_nsei(struct gprs_ns2_nse *nse);
void gprs_ns2_free_nse(struct gprs_ns2_nse *nse);
void gprs_ns2_free_nses(struct gprs_ns2_inst *nsi);
/* create vc */
void gprs_ns2_free_nsvc(struct gprs_ns2_vc *nsvc);
void gprs_ns2_free_nsvcs(struct gprs_ns2_nse *nse);
struct gprs_ns2_vc *gprs_ns2_nsvc_by_nsvci(struct gprs_ns2_inst *nsi, uint16_t nsvci);
/* generic VL driver */
struct gprs_ns2_vc_bind *gprs_ns2_bind_by_name(struct gprs_ns2_inst *nsi,
const char *name);
/* IP VL driver */
int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
const char *name,
const struct osmo_sockaddr *local,
int dscp,
struct gprs_ns2_vc_bind **result);
struct gprs_ns2_vc_bind *gprs_ns2_ip_bind_by_sockaddr(struct gprs_ns2_inst *nsi,
const struct osmo_sockaddr *sockaddr);
/* FR VL driver */
struct gprs_ns2_vc_bind *gprs_ns2_fr_bind_by_netif(
struct gprs_ns2_inst *nsi,
const char *netif);
const char *gprs_ns2_fr_bind_netif(struct gprs_ns2_vc_bind *bind);
enum osmo_fr_role gprs_ns2_fr_bind_role(struct gprs_ns2_vc_bind *bind);
int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
const char *name,
const char *netif,
struct osmo_fr_network *fr_network,
enum osmo_fr_role fr_role,
struct gprs_ns2_vc_bind **result);
int gprs_ns2_is_fr_bind(struct gprs_ns2_vc_bind *bind);
struct gprs_ns2_vc *gprs_ns2_fr_nsvc_by_dlci(struct gprs_ns2_vc_bind *bind, uint16_t dlci);
struct gprs_ns2_vc *gprs_ns2_fr_connect(struct gprs_ns2_vc_bind *bind,
struct gprs_ns2_nse *nse,
uint16_t nsvci,
uint16_t dlci);
struct gprs_ns2_vc *gprs_ns2_fr_connect2(struct gprs_ns2_vc_bind *bind,
uint16_t nsei,
uint16_t nsvci,
uint16_t dlci);
/* create a VC connection */
struct gprs_ns2_vc *gprs_ns2_ip_connect(struct gprs_ns2_vc_bind *bind,
const struct osmo_sockaddr *remote,
struct gprs_ns2_nse *nse,
uint16_t nsvci);
struct gprs_ns2_vc *gprs_ns2_ip_connect2(struct gprs_ns2_vc_bind *bind,
const struct osmo_sockaddr *remote,
uint16_t nsei,
uint16_t nsvci,
enum gprs_ns2_dialect dialect);
struct gprs_ns2_vc *gprs_ns2_ip_connect_inactive(struct gprs_ns2_vc_bind *bind,
const struct osmo_sockaddr *remote,
struct gprs_ns2_nse *nse,
uint16_t nsvci);
void gprs_ns2_ip_bind_set_sns_weight(struct gprs_ns2_vc_bind *bind,
uint8_t signalling, uint8_t data);
void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind);
void gprs_ns2_free_binds(struct gprs_ns2_inst *nsi);
/* create a VC SNS connection */
int gprs_ns2_sns_count(struct gprs_ns2_nse *nse);
int gprs_ns2_sns_add_endpoint(struct gprs_ns2_nse *nse,
const struct osmo_sockaddr *saddr);
int gprs_ns2_sns_del_endpoint(struct gprs_ns2_nse *nse,
const struct osmo_sockaddr *saddr);
int gprs_ns2_sns_add_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);
int gprs_ns2_sns_del_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);
const struct osmo_sockaddr *gprs_ns2_nse_sns_remote(struct gprs_ns2_nse *nse);
const struct osmo_sockaddr *gprs_ns2_ip_vc_remote(const struct gprs_ns2_vc *nsvc);
const struct osmo_sockaddr *gprs_ns2_ip_vc_local(const struct gprs_ns2_vc *nsvc);
bool gprs_ns2_ip_vc_equal(const struct gprs_ns2_vc *nsvc,
const struct osmo_sockaddr *local,
const struct osmo_sockaddr *remote,
uint16_t nsvci);
const struct osmo_sockaddr *gprs_ns2_ip_bind_sockaddr(struct gprs_ns2_vc_bind *bind);
int gprs_ns2_is_ip_bind(struct gprs_ns2_vc_bind *bind);
int gprs_ns2_ip_bind_set_dscp(struct gprs_ns2_vc_bind *bind, int dscp);
int gprs_ns2_ip_bind_set_priority(struct gprs_ns2_vc_bind *bind, uint8_t priority);
struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_bind(
struct gprs_ns2_vc_bind *bind,
const struct osmo_sockaddr *saddr);
int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
const char *name,
const struct osmo_sockaddr *local,
int dscp,
struct gprs_ns2_vc_bind **result);
int gprs_ns2_is_frgre_bind(struct gprs_ns2_vc_bind *bind);
uint16_t gprs_ns2_fr_nsvc_dlci(const struct gprs_ns2_vc *nsvc);
struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_nse(
struct gprs_ns2_nse *nse,
const struct osmo_sockaddr *sockaddr);
void gprs_ns2_start_alive_all_nsvcs(struct gprs_ns2_nse *nse);
/* VC information */
const char *gprs_ns2_ll_str(struct gprs_ns2_vc *nsvc);
char *gprs_ns2_ll_str_buf(char *buf, size_t buf_len, struct gprs_ns2_vc *nsvc);
char *gprs_ns2_ll_str_c(const void *ctx, struct gprs_ns2_vc *nsvc);
const char *gprs_ns2_nsvc_state_name(struct gprs_ns2_vc *nsvc);
/* vty */
int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi);
/*! @} */

View File

@ -0,0 +1,8 @@
/*! \file gprs_ns_frgre.h */
#pragma once
struct gprs_nsvc;
struct msgb;
int gprs_ns_frgre_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg);

View File

@ -0,0 +1,7 @@
osmogbproto_HEADERS = \
gsm_08_16.h \
gsm_08_18.h \
gsm_24_301.h \
$(NULL)
osmogbprotodir = $(includedir)/osmocom/gb/protocol

View File

@ -0,0 +1,103 @@
/*! \file gsm_08_16.h
* GPRS Networks Service (NS) messages on the Gb interface.
* 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
* 3GPP TS 48.016 version 6.5.0 Release 6 / ETSI TS 148 016 V6.5.0 (2005-11) */
#pragma once
#include <stdint.h>
#include <arpa/inet.h>
#include <osmocom/core/utils.h>
/*! \addtogroup libgb
* @{
* \file gprs_ns.h */
/*! Common header of GPRS NS */
struct gprs_ns_hdr {
uint8_t pdu_type; /*!< NS PDU type */
uint8_t data[0]; /*!< variable-length payload */
} __attribute__((packed));
/*! Section 10.3.2c List of IP4 Elements */
struct gprs_ns_ie_ip4_elem {
uint32_t ip_addr;
uint16_t udp_port;
uint8_t sig_weight;
uint8_t data_weight;
} __attribute__ ((packed));
/*! Section 10.3.2d List of IP6 Elements */
struct gprs_ns_ie_ip6_elem {
struct in6_addr ip_addr;
uint16_t udp_port;
uint8_t sig_weight;
uint8_t data_weight;
} __attribute__ ((packed));
extern const struct value_string gprs_ns_pdu_strings[];
/*! NS PDU Type (TS 08.16, Section 10.3.7, Table 14) */
enum ns_pdu_type {
NS_PDUT_UNITDATA = 0x00,
NS_PDUT_RESET = 0x02,
NS_PDUT_RESET_ACK = 0x03,
NS_PDUT_BLOCK = 0x04,
NS_PDUT_BLOCK_ACK = 0x05,
NS_PDUT_UNBLOCK = 0x06,
NS_PDUT_UNBLOCK_ACK = 0x07,
NS_PDUT_STATUS = 0x08,
NS_PDUT_ALIVE = 0x0a,
NS_PDUT_ALIVE_ACK = 0x0b,
/* TS 48.016 Section 10.3.7, Table 10.3.7.1 */
SNS_PDUT_ACK = 0x0c,
SNS_PDUT_ADD = 0x0d,
SNS_PDUT_CHANGE_WEIGHT = 0x0e,
SNS_PDUT_CONFIG = 0x0f,
SNS_PDUT_CONFIG_ACK = 0x10,
SNS_PDUT_DELETE = 0x11,
SNS_PDUT_SIZE = 0x12,
SNS_PDUT_SIZE_ACK = 0x13,
};
/*! NS Control IE (TS 08.16, Section 10.3, Table 12) */
enum ns_ctrl_ie {
NS_IE_CAUSE = 0x00,
NS_IE_VCI = 0x01,
NS_IE_PDU = 0x02,
NS_IE_BVCI = 0x03,
NS_IE_NSEI = 0x04,
/* TS 48.016 Section 10.3, Table 10.3.1 */
NS_IE_IPv4_LIST = 0x05,
NS_IE_IPv6_LIST = 0x06,
NS_IE_MAX_NR_NSVC = 0x07,
NS_IE_IPv4_EP_NR = 0x08,
NS_IE_IPv6_EP_NR = 0x09,
NS_IE_RESET_FLAG = 0x0a,
NS_IE_IP_ADDR = 0x0b,
NS_IE_TRANS_ID = 0xff, /* osmocom. Spec has this IE but without IEI! */
};
/*! NS Cause (TS 08.16, Section 10.3.2, Table 13) */
enum ns_cause {
NS_CAUSE_TRANSIT_FAIL = 0x00,
NS_CAUSE_OM_INTERVENTION = 0x01,
NS_CAUSE_EQUIP_FAIL = 0x02,
NS_CAUSE_NSVC_BLOCKED = 0x03,
NS_CAUSE_NSVC_UNKNOWN = 0x04,
NS_CAUSE_BVCI_UNKNOWN = 0x05,
NS_CAUSE_SEM_INCORR_PDU = 0x08,
NS_CAUSE_PDU_INCOMP_PSTATE = 0x0a,
NS_CAUSE_PROTO_ERR_UNSPEC = 0x0b,
NS_CAUSE_INVAL_ESSENT_IE = 0x0c,
NS_CAUSE_MISSING_ESSENT_IE = 0x0d,
/* TS 48.016 Section 10.3.2, Table 10.3.2.1 */
NS_CAUSE_INVAL_NR_IPv4_EP = 0x0e,
NS_CAUSE_INVAL_NR_IPv6_EP = 0x0f,
NS_CAUSE_INVAL_NR_NS_VC = 0x10,
NS_CAUSE_INVAL_WEIGH = 0x11,
NS_CAUSE_UNKN_IP_EP = 0x12,
NS_CAUSE_UNKN_IP_ADDR = 0x13,
NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14,
};

View File

@ -0,0 +1,373 @@
/*! \file gsm_08_18.h */
/* Updated to reflect TS 48.018 version 15.0.0 Release 15 */
#pragma once
#include <stdint.h>
#include <osmocom/core/endian.h>
/*! Fixed BVCI definitions (Section 5.4.1) */
#define BVCI_SIGNALLING 0x0000
#define BVCI_PTM 0x0001
/* typo backwards compatibility */
#define BSSGP_PDUT_RA_CAPA_UDPATE BSSGP_PDUT_RA_CAPA_UPDATE
/*! BSSGP PDU types (Section 11.3.26 / Table 11.27) */
enum bssgp_pdu_type {
/* PDUs between RL and BSSGP SAPs */
BSSGP_PDUT_DL_UNITDATA = 0x00,
BSSGP_PDUT_UL_UNITDATA = 0x01,
BSSGP_PDUT_RA_CAPABILITY = 0x02,
/* PDUs between MBMS SAPs */
BSSGP_PDUT_PTM_UNITDATA = 0x03, /* reserved in later specs */
BSSGP_PDUT_DL_MMBS_UNITDATA = 0x04,
BSSGP_PDUT_UL_MMBS_UNITDATA = 0x05,
/* PDUs between GMM SAPs */
BSSGP_PDUT_PAGING_PS = 0x06,
BSSGP_PDUT_PAGING_CS = 0x07,
BSSGP_PDUT_RA_CAPA_UPDATE = 0x08,
BSSGP_PDUT_RA_CAPA_UPDATE_ACK = 0x09,
BSSGP_PDUT_RADIO_STATUS = 0x0a,
BSSGP_PDUT_SUSPEND = 0x0b,
BSSGP_PDUT_SUSPEND_ACK = 0x0c,
BSSGP_PDUT_SUSPEND_NACK = 0x0d,
BSSGP_PDUT_RESUME = 0x0e,
BSSGP_PDUT_RESUME_ACK = 0x0f,
BSSGP_PDUT_RESUME_NACK = 0x10,
BSSGP_PDUT_PAGING_PS_REJECT = 0x11,
BSSGP_PDUT_DUMMY_PAGING_PS = 0x12,
BSSGP_PDUT_DUMMY_PAGING_PS_RESP = 0x13,
BSSGP_PDUT_MS_REGISTR_ENQ = 0x14,
BSSGP_PDUT_MS_REGISTR_ENQ_RESP = 0x15,
/* PDus between NM SAPs */
BSSGP_PDUT_BVC_BLOCK = 0x20,
BSSGP_PDUT_BVC_BLOCK_ACK = 0x21,
BSSGP_PDUT_BVC_RESET = 0x22,
BSSGP_PDUT_BVC_RESET_ACK = 0x23,
BSSGP_PDUT_BVC_UNBLOCK = 0x24,
BSSGP_PDUT_BVC_UNBLOCK_ACK = 0x25,
BSSGP_PDUT_FLOW_CONTROL_BVC = 0x26,
BSSGP_PDUT_FLOW_CONTROL_BVC_ACK = 0x27,
BSSGP_PDUT_FLOW_CONTROL_MS = 0x28,
BSSGP_PDUT_FLOW_CONTROL_MS_ACK = 0x29,
BSSGP_PDUT_FLUSH_LL = 0x2a,
BSSGP_PDUT_FLUSH_LL_ACK = 0x2b,
BSSGP_PDUT_LLC_DISCARD = 0x2c,
BSSGP_PDUT_FLOW_CONTROL_PFC = 0x2d,
BSSGP_PDUT_FLOW_CONTROL_PFC_ACK = 0x2e,
BSSGP_PDUT_SGSN_INVOKE_TRACE = 0x40,
BSSGP_PDUT_STATUS = 0x41,
BSSGP_PDUT_OVERLOAD = 0x42,
/* PDUs between PFM SAP's */
BSSGP_PDUT_DOWNLOAD_BSS_PFC = 0x50,
BSSGP_PDUT_CREATE_BSS_PFC = 0x51,
BSSGP_PDUT_CREATE_BSS_PFC_ACK = 0x52,
BSSGP_PDUT_CREATE_BSS_PFC_NACK = 0x53,
BSSGP_PDUT_MODIFY_BSS_PFC = 0x54,
BSSGP_PDUT_MODIFY_BSS_PFC_ACK = 0x55,
BSSGP_PDUT_DELETE_BSS_PFC = 0x56,
BSSGP_PDUT_DELETE_BSS_PFC_ACK = 0x57,
BSSGP_PDUT_DELETE_BSS_PFC_REQ = 0x58,
BSSGP_PDUT_PS_HO_REQUIRED = 0x59,
BSSGP_PDUT_PS_HO_REQUIRED_ACK = 0x5a,
BSSGP_PDUT_PS_HO_REQUIRED_NACK = 0x5b,
BSSGP_PDUT_PS_HO_REQUEST = 0x5c,
BSSGP_PDUT_PS_HO_REQUEST_ACK = 0x5d,
BSSGP_PDUT_PS_HO_REQUEST_NACK = 0x5e,
BSSGP_PDUT_PS_HO_COMPLETE = 0x91,
BSSGP_PDUT_PS_HO_CANCEL = 0x92,
BSSGP_PDUT_PS_HO_COMPLETE_ACK = 0x93,
/* PDUs between LCS SAPs */
BSSGP_PDUT_PERFORM_LOC_REQ = 0x60,
BSSGP_PDUT_PERFORM_LOC_RESP = 0x61,
BSSGP_PDUT_PERFORM_LOC_ABORT = 0x62,
BSSGP_PDUT_POSITION_COMMAND = 0x63,
BSSGP_PDUT_POSITION_RESPONSE = 0x64,
/* PDUs between RIM SAPs */
BSSGP_PDUT_RAN_INFO = 0x70,
BSSGP_PDUT_RAN_INFO_REQ = 0x71,
BSSGP_PDUT_RAN_INFO_ACK = 0x72,
BSSGP_PDUT_RAN_INFO_ERROR = 0x73,
BSSGP_PDUT_RAN_INFO_APP_ERROR = 0x74,
/* PDUs between MBMS SAPs */
BSSGP_PDUT_MBMS_START_REQ = 0x80,
BSSGP_PDUT_MBMS_START_RESP = 0x81,
BSSGP_PDUT_MBMS_STOP_REQ = 0x82,
BSSGP_PDUT_MBMS_STOP_RESP = 0x83,
BSSGP_PDUT_MBMS_UPDATE_REQ = 0x84,
BSSGP_PDUT_MBMS_UPDATE_RESP = 0x85,
};
/*! BSSGP User-Data header (Section 10.2.1 and 10.2.2) */
struct bssgp_ud_hdr {
uint8_t pdu_type; /*!< BSSGP PDU type */
uint32_t tlli; /*!< Temporary Link-Local Identifier */
uint8_t qos_profile[3]; /*!< QoS profile */
uint8_t data[0]; /* optional/conditional IEs as TLVs */
} __attribute__((packed));
/*! BSSGP normal header */
struct bssgp_normal_hdr {
uint8_t pdu_type; /*!< BSSGP PDU type */
uint8_t data[0]; /*!< optional/conditional IEs as TLVs */
};
/*! BSSGP Information Element Identifiers (Section 11.3 / Table 11.3) */
enum bssgp_iei_type {
BSSGP_IE_ALIGNMENT = 0x00,
BSSGP_IE_BMAX_DEFAULT_MS = 0x01,
BSSGP_IE_BSS_AREA_ID = 0x02,
BSSGP_IE_BUCKET_LEAK_RATE = 0x03,
BSSGP_IE_BVCI = 0x04,
BSSGP_IE_BVC_BUCKET_SIZE = 0x05,
BSSGP_IE_BVC_MEASUREMENT = 0x06,
BSSGP_IE_CAUSE = 0x07,
BSSGP_IE_CELL_ID = 0x08,
BSSGP_IE_CHAN_NEEDED = 0x09,
BSSGP_IE_DRX_PARAMS = 0x0a,
BSSGP_IE_EMLPP_PRIO = 0x0b,
BSSGP_IE_FLUSH_ACTION = 0x0c,
BSSGP_IE_IMSI = 0x0d,
BSSGP_IE_LLC_PDU = 0x0e,
BSSGP_IE_LLC_FRAMES_DISCARDED = 0x0f,
BSSGP_IE_LOCATION_AREA = 0x10,
BSSGP_IE_MOBILE_ID = 0x11,
BSSGP_IE_MS_BUCKET_SIZE = 0x12,
BSSGP_IE_MS_RADIO_ACCESS_CAP = 0x13,
BSSGP_IE_OMC_ID = 0x14,
BSSGP_IE_PDU_IN_ERROR = 0x15,
BSSGP_IE_PDU_LIFETIME = 0x16,
BSSGP_IE_PRIORITY = 0x17,
BSSGP_IE_QOS_PROFILE = 0x18,
BSSGP_IE_RADIO_CAUSE = 0x19,
BSSGP_IE_RA_CAP_UPD_CAUSE = 0x1a,
BSSGP_IE_ROUTEING_AREA = 0x1b,
BSSGP_IE_R_DEFAULT_MS = 0x1c,
BSSGP_IE_SUSPEND_REF_NR = 0x1d,
BSSGP_IE_TAG = 0x1e,
BSSGP_IE_TLLI = 0x1f,
BSSGP_IE_TMSI = 0x20,
BSSGP_IE_TRACE_REFERENC = 0x21,
BSSGP_IE_TRACE_TYPE = 0x22,
BSSGP_IE_TRANSACTION_ID = 0x23,
BSSGP_IE_TRIGGER_ID = 0x24,
BSSGP_IE_NUM_OCT_AFF = 0x25,
BSSGP_IE_LSA_ID_LIST = 0x26,
BSSGP_IE_LSA_INFORMATION = 0x27,
BSSGP_IE_PACKET_FLOW_ID = 0x28,
BSSGP_IE_PACKET_FLOW_TIMER = 0x29,
BSSGP_IE_AGG_BSS_QOS_PROFILE = 0x3a,
BSSGP_IE_FEATURE_BITMAP = 0x3b,
BSSGP_IE_BUCKET_FULL_RATIO = 0x3c,
BSSGP_IE_SERVICE_UTRAN_CCO = 0x3d,
BSSGP_IE_NSEI = 0x3e,
BSSGP_IE_RRLP_APDU = 0x3f,
BSSGP_IE_LCS_QOS = 0x40,
BSSGP_IE_LCS_CLIENT_TYPE = 0x41,
BSSGP_IE_REQUESTED_GPS_AST_DATA = 0x42,
BSSGP_IE_LOCATION_TYPE = 0x43,
BSSGP_IE_LOCATION_ESTIMATE = 0x44,
BSSGP_IE_POSITIONING_DATA = 0x45,
BSSGP_IE_DECIPHERING_KEYS = 0x46,
BSSGP_IE_LCS_PRIORITY = 0x47,
BSSGP_IE_LCS_CAUSE = 0x48,
BSSGP_IE_LCS_CAPABILITY = 0x49,
BSSGP_IE_RRLP_FLAGS = 0x4a,
BSSGP_IE_RIM_APP_IDENTITY = 0x4b,
BSSGP_IE_RIM_SEQ_NR = 0x4c,
BSSGP_IE_RIM_REQ_APP_CONTAINER = 0x4d,
BSSGP_IE_RAN_INFO_APP_CONTAINER = 0x4e,
BSSGP_IE_RIM_PDU_INDICATIONS = 0x4f,
BSSGP_IE_PFC_FLOW_CTRL_PARAMS = 0x52,
BSSGP_IE_GLOBAL_CN_ID = 0x53,
BSSGP_IE_RIM_ROUTING_INFO = 0x54,
BSSGP_IE_RIM_PROTOCOL_VERSION = 0x55,
BSSGP_IE_APP_ERROR_CONTAINER = 0x56,
BSSGP_IE_RI_REQ_RIM_CONTAINER = 0x57,
BSSGP_IE_RI_RIM_CONTAINER = 0x58,
BSSGP_IE_RI_APP_ERROR_RIM_CONT = 0x59,
BSSGP_IE_RI_ACK_RIM_CONTAINER = 0x5a,
BSSGP_IE_RI_ERROR_RIM_COINTAINER = 0x5b,
BSSGP_IE_TMGI = 0x5c,
BSSGP_IE_MBMS_SESSION_ID = 0x5d,
BSSGP_IE_MBMS_SESSION_DURATION = 0x5e,
BSSGP_IE_MBMS_SA_ID_LIST = 0x5f,
BSSGP_IE_MBMS_RESPONSE = 0x60,
BSSGP_IE_MBMS_RA_LIST = 0x61,
BSSGP_IE_MBMS_SESSION_INFO = 0x62,
BSSGP_IE_MBMS_STOP_CAUSE = 0x63,
BSSGP_IE_SBSS_TO_TBSS_TR_CONT = 0x64,
BSSGP_IE_TBSS_TO_SBSS_TR_CONT = 0x65,
BSSGP_IE_NAS_CONT_FOR_PS_HO = 0x66,
BSSGP_IE_PFC_TO_BE_SETUP_LIST = 0x67,
BSSGP_IE_LIST_OF_SETUP_PFC = 0x68,
BSSGP_IE_EXT_FEATURE_BITMAP = 0x69,
BSSGP_IE_SRC_TO_TGT_TR_CONT = 0x6a,
BSSGP_IE_TGT_TO_SRC_TR_CONT = 0x6b,
BSSGP_IE_NC_ID = 0x6c,
BSSGP_IE_PAGE_MODE = 0x6d,
BSSGP_IE_CONTAINER_ID = 0x6e,
BSSGP_IE_GLOBAL_TFI = 0x6f,
BSSGP_IE_IMEI = 0x70,
BSSGP_IE_TIME_TO_MBMS_DATA_XFR = 0x71,
BSSGP_IE_MBMS_SESSION_REP_NR = 0x72,
BSSGP_IE_INTER_RAT_HO_INFO = 0x73,
BSSGP_IE_PS_HO_COMMAND = 0x74,
BSSGP_IE_PS_HO_INDICATIONS = 0x75,
BSSGP_IE_SI_PSI_CONTAINER = 0x76,
BSSGP_IE_ACTIVE_PFC_LIST = 0x77,
BSSGP_IE_VELOCITY_DATA = 0x78,
BSSGP_IE_DTM_HO_COMMAND = 0x79,
BSSGP_IE_CS_INDICATION = 0x7a,
BSSGP_IE_RQD_GANNS_AST_DATA = 0x7b,
BSSGP_IE_GANSS_LOCATION_TYPE = 0x7c,
BSSGP_IE_GANSS_POSITIONING_DATA = 0x7d,
BSSGP_IE_FLOW_CTRL_GRANULARITY = 0x7e,
BSSGP_IE_ENB_ID = 0x7f,
BSSGP_IE_EUTRAN_IRAT_HO_INFO = 0x80,
BSSGP_IE_SUB_PID4RAT_FREQ_PRIO = 0x81,
BSSGP_IE_REQ4IRAT_HO_INFO = 0x82,
BSSGP_IE_RELIABLE_IRAT_HO_INFO = 0x83,
BSSGP_IE_SON_TRANSFER_APP_ID = 0x84,
BSSGP_IE_CSG_ID = 0x85,
BSSGP_IE_TAC = 0x86,
BSSGP_IE_REDIRECT_ATTEMPT_FLAG = 0x87,
BSSGP_IE_REDIRECTION_INDICATION = 0x88,
BSSGP_IE_REDIRECTION_COMPLETED = 0x89,
BSSGP_IE_UNCONF_SEND_STATE_VAR = 0x8a,
BSSGP_IE_IRAT_MEASUREMENT_CONF = 0x8b,
BSSGP_IE_SCI = 0x8c,
BSSGP_IE_GGSN_PGW_LOCATION = 0x8d,
BSSGP_IE_SELECTED_PLMN_ID = 0x8e,
BSSGP_IE_PRIO_CLASS_IND = 0x8f,
BSSGP_IE_SOURCE_CELL_ID = 0x90,
BSSGP_IE_IRAT_MEAS_CFG_E_EARFCN = 0x91,
BSSGP_IE_EDRX_PARAMETERS = 0x92,
BSSGP_IE_T_UNTIL_NEXT_PAGING = 0x93,
BSSGP_IE_COVERAGE_CLASS = 0x98,
BSSGP_IE_PAGING_ATTEMPT_INFO = 0x99,
BSSGP_IE_EXCEPTION_REPORT_FLAG = 0x9a,
BSSGP_IE_OLD_RA_ID = 0x9b,
BSSGP_IE_ATTACH_IND = 0x9c,
BSSGP_IE_PLMN_ID = 0x9d,
BSSGP_IE_MME_QUERY = 0x9e,
BSSGP_IE_SGSN_GROUP_ID = 0x9f,
BSSGP_IE_ADDITIONAL_PTMSI = 0xa0,
BSSGP_IE_UE_USAGE_TYPE = 0xa1,
BSSGP_IE_MLAT_TIMER = 0xa2,
BSSGP_IE_MLAT_TA = 0xa3,
BSSGP_IE_MS_SYNC_ACCURACY = 0xa4,
BSSGP_IE_BTS_RX_ACCURACY_LVL = 0xa5,
BSSGP_IE_TA_REQ = 0xa6,
};
/*! Cause coding (Section 11.3.8 / Table 11.10) */
enum gprs_bssgp_cause {
BSSGP_CAUSE_PROC_OVERLOAD = 0x00,
BSSGP_CAUSE_EQUIP_FAIL = 0x01,
BSSGP_CAUSE_TRASIT_NET_FAIL = 0x02,
BSSGP_CAUSE_CAPA_GREATER_0KPBS = 0x03,
BSSGP_CAUSE_UNKNOWN_MS = 0x04,
BSSGP_CAUSE_UNKNOWN_BVCI = 0x05,
BSSGP_CAUSE_CELL_TRAF_CONG = 0x06,
BSSGP_CAUSE_SGSN_CONG = 0x07,
BSSGP_CAUSE_OML_INTERV = 0x08,
BSSGP_CAUSE_BVCI_BLOCKED = 0x09,
BSSGP_CAUSE_PFC_CREATE_FAIL = 0x0a,
BSSGP_CAUSE_PFC_PREEMPTED = 0x0b,
BSSGP_CAUSE_ABQP_NOT_SUPP = 0x0c,
BSSGP_CAUSE_SEM_INCORR_PDU = 0x20,
BSSGP_CAUSE_INV_MAND_INF = 0x21,
BSSGP_CAUSE_MISSING_MAND_IE = 0x22,
BSSGP_CAUSE_MISSING_COND_IE = 0x23,
BSSGP_CAUSE_UNEXP_COND_IE = 0x24,
BSSGP_CAUSE_COND_IE_ERR = 0x25,
BSSGP_CAUSE_PDU_INCOMP_STATE = 0x26,
BSSGP_CAUSE_PROTO_ERR_UNSPEC = 0x27,
BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28,
BSSGP_CAUSE_REQ_INFO_NOT_AVAIL = 0x29,
BSSGP_CAUSE_UNKN_DST = 0x2a,
BSSGP_CAUSE_UNKN_RIM_AI = 0x2b,
BSSGP_CAUSE_INVAL_CONT_UI = 0x2c,
BSSGP_CAUSE_PFC_QUEUE = 0x2d,
BSSGP_CAUSE_PFC_CREATED = 0x2e,
BSSGP_CAUSE_T12_EXPIRY = 0x2f,
BSSGP_CAUSE_MS_UNDER_PS_HO = 0x30,
BSSGP_CAUSE_UL_QUALITY = 0x31,
BSSGP_CAUSE_UL_STRENGTH = 0x32,
BSSGP_CAUSE_DL_QUALITY = 0x33,
BSSGP_CAUSE_DL_STRENGTH = 0x34,
BSSGP_CAUSE_DISTANCE = 0x35,
BSSGP_CAUSE_BETTER_CELL = 0x36,
BSSGP_CAUSE_TRAFFIC = 0x37,
BSSGP_CAUSE_MS_RADIO_LOSS = 0x38,
BSSGP_CAUSE_MS_BACK_OLD_CHAN = 0x39,
BSSGP_CAUSE_T13_EXPIRY = 0x3a,
BSSGP_CAUSE_T14_EXPIRY = 0x3b,
BSSGP_CAUSE_NOT_ALL_PFC = 0x3c,
BSSGP_CAUSE_CS = 0x3d,
BSSGP_CAUSE_REQ_ALG_NOT_SUPP = 0x3e,
BSSGP_CAUSE_RELOC_FAIL = 0x3f,
BSSGP_CAUSE_DIR_RETRY = 0x40,
BSSGP_CAUSE_TIME_CRIT_RELOC = 0x41,
BSSGP_CAUSE_PS_HO_TARG_NA = 0x42,
BSSGP_CAUSE_PS_HO_TARG_NOT_SUPP = 0x43,
BSSGP_CAUSE_PUESBINE = 0x44,
BSSGP_CAUSE_DTM_HO_NO_CS_RES = 0x45,
BSSGP_CAUSE_DTM_HO_PS_ALLOC_FAIL = 0x46,
BSSGP_CAUSE_DTM_HO_T24_EXPIRY = 0x47,
BSSGP_CAUSE_DTM_HO_INVAL_CS_IND = 0x48,
BSSGP_CAUSE_DTM_HO_T23_EXPIRY = 0x49,
BSSGP_CAUSE_DTM_HO_MSC_ERR = 0x4a,
BSSGP_CAUSE_INVAL_CSG_CELL = 0x4b,
};
/* Feature Bitmap (Section 11.3.45) */
#define BSSGP_FEAT_PFC 0x01 /* Packet Flow Context */
#define BSSGP_FEAT_CBL 0x02 /* Current Bucket Level */
#define BSSGP_FEAT_INR 0x04 /* Inter-NSE re-routing */
#define BSSGP_FEAT_LCS 0x08 /* Location Services */
#define BSSGP_FEAT_RIM 0x10 /* RAN Inoformation Management */
#define BSSGP_FEAT_PFC_FC 0x20 /* PFC Flow Control */
#define BSSGP_FEAT_ERS 0x40 /* Enhanced Radio Status */
#define BSSGP_FEAT_MBMS 0x80 /* Multimedia Broadcast */
/* Extended Feature Bitmap (Section 11.3.84) */
#define BSSGP_XFEAT_PSHO 0x01 /* PS Handover */
#define BSSGP_XFEAT_GBIT 0x02 /* Gigabit Interface */
#define BSSGP_XFEAT_MOCN 0x04 /* Multi-Operator CN */
#define BSSGP_XFEAT_CSPS 0x08 /* CS/PS coordination enhancements */
#define BSSGP_XFEAT_ECIoT 0x10 /* EC-GSM-IoT */
#define BSSGP_XFEAT_DCN 0x20 /* Dedicated CN */
#define BSSGP_XFEAT_eDRX 0x40 /* eDRX */
#define BSSGP_XFEAT_MSAD 0x80 /* MS-assisted Dedicated CN selection */
/* Flow Control Granularity (Section 11.3.102) */
enum bssgp_fc_granularity {
BSSGP_FC_GRAN_100 = 0,
BSSGP_FC_GRAN_1000 = 1,
BSSGP_FC_GRAN_10000 = 2,
BSSGP_FC_GRAN_100000 = 3,
};
/* RAN-INFORMATION-REQUEST PDU Type Extension
* 3GPP TS 48.018, table 11.3.65.1 */
enum bssgp_rim_pdu_type {
RIM_PDU_TYPE_STOP = 0,
RIM_PDU_TYPE_SING_REP = 1,
RIM_PDU_TYPE_MULT_REP = 2,
};
/* RIM PDU Indications
* 3GPP TS 48.018, section 11.3.65.0 */
struct bssgp_rim_pdu_ind {
#if OSMO_IS_LITTLE_ENDIAN
uint8_t ack_requested:1,
pdu_type_ext:3,
reserved:4;
#elif OSMO_IS_BIG_ENDIAN
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
uint8_t reserved:4, pdu_type_ext:3, ack_requested:1;
#endif
} __attribute__ ((packed));

View File

@ -0,0 +1,11 @@
/*! \file gsm_24_301.h */
#pragma once
/*! Tracking area TS 24.301, section 9.9.3.32 */
struct osmo_eutran_tai {
uint16_t mcc;
uint16_t mnc;
bool mnc_3_digits;
uint16_t tac;
};

View File

@ -1,71 +1,4 @@
#pragma once
#include <stdint.h>
struct gprs_ns2_inst;
struct osmo_fsm_inst;
struct gprs_ra_id;
struct bssgp2_flow_ctrl;
enum bssp_ptp_bvc_fsm_state {
BSSGP_BVCFSM_S_NULL,
BSSGP_BVCFSM_S_BLOCKED,
BSSGP_BVCFSM_S_WAIT_RESET_ACK,
BSSGP_BVCFSM_S_UNBLOCKED,
};
enum bssgp_ptp_bvc_fsm_event {
/* Rx of BSSGP PDUs from the remote side; 'data' is 'struct tlv_parsed', and
* the assumption is that the caller has already validated all mandatory IEs
* are present and of sufficient length */
BSSGP_BVCFSM_E_RX_BLOCK,
BSSGP_BVCFSM_E_RX_BLOCK_ACK,
BSSGP_BVCFSM_E_RX_UNBLOCK,
BSSGP_BVCFSM_E_RX_UNBLOCK_ACK,
BSSGP_BVCFSM_E_RX_RESET,
BSSGP_BVCFSM_E_RX_RESET_ACK,
BSSGP_BVCFSM_E_RX_FC_BVC,
BSSGP_BVCFSM_E_RX_FC_BVC_ACK,
/* Requests of the local user */
BSSGP_BVCFSM_E_REQ_BLOCK, /* data: uint8_t *cause */
BSSGP_BVCFSM_E_REQ_UNBLOCK,
BSSGP_BVCFSM_E_REQ_RESET, /* data: uint8_t *cause */
BSSGP_BVCFSM_E_REQ_FC_BVC, /* data: struct bssgp2_flow_ctrl */
};
struct bssgp_bvc_fsm_ops {
/* call-back notifying the user of a state change */
void (*state_chg_notification)(uint16_t nsei, uint16_t bvci, int old_state, int new_state,
void *priv);
/* call-back notifying the user of a BVC-RESET event */
void (*reset_notification)(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
uint16_t cell_id, uint8_t cause, void *priv);
void (*rx_fc_bvc)(uint16_t nsei, uint16_t bvci, const struct bssgp2_flow_ctrl *fc, void *priv);
void (*reset_ack_notification)(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id,
uint16_t cell_id, uint8_t cause, void *priv);
};
struct osmo_fsm_inst *
bssgp_bvc_fsm_alloc_sig_bss(void *ctx, struct gprs_ns2_inst *nsi, uint16_t nsei, uint32_t features);
struct osmo_fsm_inst *
bssgp_bvc_fsm_alloc_ptp_bss(void *ctx, struct gprs_ns2_inst *nsi, uint16_t nsei, uint16_t bvci,
const struct gprs_ra_id *ra_id, uint16_t cell_id);
struct osmo_fsm_inst *
bssgp_bvc_fsm_alloc_sig_sgsn(void *ctx, struct gprs_ns2_inst *nsi, uint16_t nsei, uint32_t features);
struct osmo_fsm_inst *
bssgp_bvc_fsm_alloc_ptp_sgsn(void *ctx, struct gprs_ns2_inst *nsi, uint16_t nsei, uint16_t bvci);
void bssgp_bvc_fsm_set_ops(struct osmo_fsm_inst *fi, const struct bssgp_bvc_fsm_ops *ops, void *ops_priv);
bool bssgp_bvc_fsm_is_unblocked(struct osmo_fsm_inst *fi);
uint8_t bssgp_bvc_fsm_get_block_cause(struct osmo_fsm_inst *fi);
uint32_t bssgp_bvc_fsm_get_features_advertised(struct osmo_fsm_inst *fi);
uint32_t bssgp_bvc_fsm_get_features_received(struct osmo_fsm_inst *fi);
uint32_t bssgp_bvc_fsm_get_features_negotiated(struct osmo_fsm_inst *fi);
void bssgp_bvc_fsm_set_max_pdu_len(struct osmo_fsm_inst *fi, uint16_t max_pdu_len);
uint16_t bssgp_bvc_fsm_get_max_pdu_len(const struct osmo_fsm_inst *fi);
#pragma message "Header osmocom/gprs/bssgp_bvc_fsm.h is deprecated, include osmocom/gb/bssgp_bvc_fsm.h instead"
#include <osmocom/gb/bssgp_bvc_fsm.h>

View File

@ -1,151 +1,4 @@
/*! \file frame_relay.h */
/* (C) 2020 Harald Welte <laforge@gnumonks.org>
* (C) 2020 sysmocom - s.f.m.c. GmbH
* Author: Alexander Couzens <lynxis@fe80.eu>
*
* All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/utils.h>
#include <stdint.h>
struct osmo_tdef;
struct msgb;
struct vty;
enum osmo_fr_role {
FR_ROLE_USER_EQUIPMENT,
FR_ROLE_NETWORK_EQUIPMENT,
};
/* 48.016 § 6.1.4.2 default maximum information field size of 1600 octets */
#define FRAME_RELAY_MTU 1600
/* FR DLC header is 2 byte */
#define FRAME_RELAY_SDU (FRAME_RELAY_MTU - 2)
extern const struct value_string osmo_fr_role_names[];
static inline const char *osmo_fr_role_str(enum osmo_fr_role role) {
return get_value_string(osmo_fr_role_names, role);
}
struct osmo_fr_network {
struct llist_head links;
unsigned int n391; /* full status polling counter */
unsigned int n392; /* error threshold */
unsigned int n393; /* monitored events count */
struct osmo_tdef *T_defs; /* T391, T392 */
};
struct osmo_fr_dlc;
/* Frame Relay Link */
struct osmo_fr_link {
/* list in osmo_fr_network.links */
struct llist_head list;
struct osmo_fr_network *net;
enum osmo_fr_role role;
/* human-readable name */
const char *name;
/* value of the last received send sequence number field in the
* link integrity verification information element */
uint8_t last_rx_seq;
/* value of the send sequence number field of the last link
* integrity verification information element sent */
uint8_t last_tx_seq;
struct osmo_timer_list t391;
struct osmo_timer_list t392;
unsigned int polling_count;
unsigned int err_count;
unsigned int succeed;
/* the type of the last status enquiry */
uint8_t expected_rep;
bool state;
/* list of data link connections at this link */
struct llist_head dlc_list;
/* optional call-back to be called for each PDU received on an unknown DLC */
int (*unknown_dlc_rx_cb)(void *cb_data, struct msgb *msg);
void *unknown_dlc_rx_cb_data;
/* call-back to be called for transmitting on the underlying hardware */
int (*tx_cb)(void *data, struct msgb *msg);
/* optional call-back to be called each time the status changes active/inactive */
void (*status_cb)(struct osmo_fr_link *link, void *cb_data, bool active);
void *cb_data;
};
/* Frame Relay Data Link Connection */
struct osmo_fr_dlc {
/* entry in fr_link.dlc_list */
struct llist_head list;
struct osmo_fr_link *link;
uint16_t dlci;
/* is this DLC marked active for traffic? */
bool active;
/* was this DLC newly added? */
bool add;
/* is this DLC about to be destroyed */
bool del;
/* The local state needs to be transferred to the USER;
* NET must wait until USER confirms it implicitly by a seq number check */
bool state_send;
/* call-back to be called for each PDU received on this DLC */
int (*rx_cb)(void *cb_data, struct msgb *msg);
/* optional call-back to be called each time the status changes active/inactive */
void (*status_cb)(struct osmo_fr_dlc *dlc, void *cb_data, bool active);
void *cb_data;
};
/* allocate a frame relay network */
struct osmo_fr_network *osmo_fr_network_alloc(void *ctx);
void osmo_fr_network_free(struct osmo_fr_network *net);
void osmo_fr_network_dump_vty(struct vty *vty, const struct osmo_fr_network *net);
/* allocate a frame relay link in a given network */
struct osmo_fr_link *osmo_fr_link_alloc(struct osmo_fr_network *net, enum osmo_fr_role role, const char *name);
/* free a frame link in a given network */
void osmo_fr_link_free(struct osmo_fr_link *link);
/* allocate a data link connectoin on a given framerelay link */
struct osmo_fr_dlc *osmo_fr_dlc_alloc(struct osmo_fr_link *link, uint16_t dlci);
void osmo_fr_dlc_free(struct osmo_fr_dlc *dlc);
struct osmo_fr_dlc *osmo_fr_dlc_by_dlci(struct osmo_fr_link *link, uint16_t dlci);
int osmo_fr_rx(struct msgb *msg);
int osmo_fr_tx_dlc(struct msgb *msg);
#pragma message "Header osmocom/gprs/frame_relay.h is deprecated, include osmocom/gb/frame_relay.h instead"
#include <osmocom/gb/frame_relay.h>

View File

@ -1,245 +1,4 @@
/*! \file gprs_bssgp.h */
#pragma once
#include <stdint.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/prim.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
#include <osmocom/gprs/protocol/gsm_24_301.h>
#include <osmocom/gprs/gprs_bssgp_rim.h>
/* gprs_bssgp_util.c */
#define BSSGP_PDUF_UL 0x0001 /* PDU may occur in uplink */
#define BSSGP_PDUF_DL 0x0002 /* PDU may occur in downlink */
#define BSSGP_PDUF_SIG 0x0004 /* PDU may occur on Signaling BVC */
#define BSSGP_PDUF_PTP 0x0008 /* PDU may occur on PTP BVC */
#define BSSGP_PDUF_PTM 0x0010 /* PDU may occur on PTM BVC */
extern const struct osmo_tlv_prot_def osmo_pdef_bssgp;
/*! return the PDU type flags (UL/DL/SIG/PTP/PTM) of specified PDU type */
static inline uint32_t bssgp_pdu_type_flags(uint8_t pdu_type) {
return osmo_tlv_prot_msgt_flags(&osmo_pdef_bssgp, pdu_type);
}
typedef int (*bssgp_bvc_send)(void *ctx, struct msgb *msg);
extern struct gprs_ns_inst *bssgp_nsi;
void bssgp_set_bssgp_callback(bssgp_bvc_send ns_send, void *data);
struct msgb *bssgp_msgb_alloc(void);
struct msgb *bssgp_msgb_copy(const struct msgb *msg, const char *name);
const char *bssgp_cause_str(enum gprs_bssgp_cause cause);
const char *bssgp_pdu_str(enum bssgp_pdu_type pdu);
int bssgp_tx_bvc_reset_nsei_bvci(uint16_t nsei, uint16_t bvci, enum gprs_bssgp_cause cause, const struct gprs_ra_id *ra_id, uint16_t cell_id);
/* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */
int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
uint16_t bvci, uint16_t ns_bvci);
/* Chapter 10.4.14: Status */
int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);
enum bssgp_prim {
PRIM_BSSGP_DL_UD,
PRIM_BSSGP_UL_UD,
PRIM_BSSGP_PTM_UD,
PRIM_BSSGP_GMM_SUSPEND,
PRIM_BSSGP_GMM_RESUME,
PRIM_BSSGP_GMM_PAGING,
PRIM_NM_FLUSH_LL,
PRIM_NM_LLC_DISCARDED,
PRIM_NM_BVC_RESET,
PRIM_NM_BVC_BLOCK,
PRIM_NM_BVC_UNBLOCK,
PRIM_NM_STATUS,
PRIM_BSSGP_RIM_PDU_TRANSFER,
};
struct osmo_bssgp_prim {
struct osmo_prim_hdr oph;
/* common fields */
uint16_t nsei;
uint16_t bvci;
uint32_t tlli;
struct tlv_parsed *tp;
struct gprs_ra_id *ra_id;
/* specific fields */
union {
struct {
uint8_t suspend_ref;
} resume;
struct bssgp_ran_information_pdu rim_pdu;
} u;
};
/* gprs_bssgp.c */
/*! BSSGP flow control (SGSN side) According to Section 8.2 */
struct bssgp_flow_control {
uint32_t bucket_size_max; /*!< maximum size of the bucket (octets) */
uint32_t bucket_leak_rate; /*!< leak rate of the bucket (octets/sec) */
uint32_t bucket_counter; /*!< number of tokens in the bucket */
struct timeval time_last_pdu; /*!< timestamp of last PDU sent */
/* the built-in queue */
uint32_t max_queue_depth; /*!< how many packets to queue (mgs) */
uint32_t queue_depth; /*!< current length of queue (msgs) */
struct llist_head queue; /*!< linked list of msgb's */
struct osmo_timer_list timer; /*!< timer-based dequeueing */
/*! callback to be called at output of flow control */
int (*out_cb)(struct bssgp_flow_control *fc, struct msgb *msg,
uint32_t llc_pdu_len, void *priv);
};
#define BVC_S_BLOCKED 0x0001
/* The per-BTS context that we keep on the SGSN side of the BSSGP link */
struct bssgp_bvc_ctx {
struct llist_head list;
struct gprs_ra_id ra_id; /*!< parsed RA ID of the remote BTS */
uint16_t cell_id; /*!< Cell ID of the remote BTS */
/* NSEI and BVCI of underlying Gb link. Together they
* uniquely identify a link to a BTS (5.4.4) */
uint16_t bvci;
uint16_t nsei;
uint32_t state;
struct rate_ctr_group *ctrg;
struct bssgp_flow_control *fc;
/*! default maximum size of per-MS bucket in octets */
uint32_t bmax_default_ms;
/*! default bucket leak rate of per-MS bucket in octests/s */
uint32_t r_default_ms;
/*! BSS or SGSN. This defines the local state. */
bool is_sgsn;
/* we might want to add this as a shortcut later, avoiding the NSVC
* lookup for every packet, similar to a routing cache */
//struct gprs_nsvc *nsvc;
};
extern struct llist_head bssgp_bvc_ctxts;
/* Create a BTS Context with BVCI+NSEI */
struct bssgp_bvc_ctx *btsctx_alloc(uint16_t bvci, uint16_t nsei);
/* Find a BTS Context based on parsed RA ID and Cell ID */
struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t cid);
/* Find a BTS context based on BVCI+NSEI tuple */
struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei);
/* Free a given BTS context */
void bssgp_bvc_ctx_free(struct bssgp_bvc_ctx *ctx);
#define BVC_F_BLOCKED 0x0001
enum bssgp_ctr {
BSSGP_CTR_PKTS_IN,
BSSGP_CTR_PKTS_OUT,
BSSGP_CTR_BYTES_IN,
BSSGP_CTR_BYTES_OUT,
BSSGP_CTR_BLOCKED,
BSSGP_CTR_DISCARDED,
BSSGP_CTR_STATUS,
};
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_msgb.h>
/* BSSGP-UL-UNITDATA.ind */
int bssgp_rcvmsg(struct msgb *msg);
/* BSSGP-DL-UNITDATA.req */
struct bssgp_lv {
uint16_t len;
uint8_t *v;
};
/* parameters for BSSGP downlink userdata transmission */
struct bssgp_dl_ud_par {
uint32_t *tlli;
char *imsi;
struct bssgp_flow_control *fc;
uint16_t drx_parms;
/* FIXME: priority */
struct bssgp_lv ms_ra_cap;
uint8_t qos_profile[3];
};
int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
struct bssgp_dl_ud_par *dup);
uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf);
int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid,
uint16_t cid);
/* Wrapper around TLV parser to parse BSSGP IEs */
static inline int bssgp_tlv_parse(struct tlv_parsed *tp, const uint8_t *buf, int len)
{
return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0);
}
/*! BSSGP Paging mode */
enum bssgp_paging_mode {
BSSGP_PAGING_PS,
BSSGP_PAGING_CS,
};
/*! BSSGP Paging scope */
enum bssgp_paging_scope {
BSSGP_PAGING_BSS_AREA, /*!< all cells in BSS */
BSSGP_PAGING_LOCATION_AREA, /*!< all cells in LA */
BSSGP_PAGING_ROUTEING_AREA, /*!< all cells in RA */
BSSGP_PAGING_BVCI, /*!< one cell */
};
/*! BSSGP paging information */
struct bssgp_paging_info {
enum bssgp_paging_mode mode; /*!< CS or PS paging */
enum bssgp_paging_scope scope; /*!< bssgp_paging_scope */
struct gprs_ra_id raid; /*!< RA Identifier */
uint16_t bvci; /*!< BVCI */
char *imsi; /*!< IMSI, if any */
uint32_t *ptmsi; /*!< P-TMSI, if any */
uint16_t drx_params; /*!< DRX parameters */
uint8_t qos[3]; /*!< QoS parameters */
};
/* Send a single GMM-PAGING.req to a given NSEI/NS-BVCI */
int bssgp_tx_paging(uint16_t nsei, uint16_t ns_bvci,
struct bssgp_paging_info *pinfo);
void bssgp_fc_init(struct bssgp_flow_control *fc,
uint32_t bucket_size_max, uint32_t bucket_leak_rate,
uint32_t max_queue_depth,
int (*out_cb)(struct bssgp_flow_control *fc, struct msgb *msg,
uint32_t llc_pdu_len, void *priv));
/* input function of the flow control implementation, called first
* for the MM flow control, and then as the MM flow control output
* callback in order to perform BVC flow control */
int bssgp_fc_in(struct bssgp_flow_control *fc, struct msgb *msg,
uint32_t llc_pdu_len, void *priv);
/* Initialize the Flow Control parameters for a new MS according to
* default values for the BVC specified by BVCI and NSEI */
int bssgp_fc_ms_init(struct bssgp_flow_control *fc_ms, uint16_t bvci,
uint16_t nsei, uint32_t max_queue_depth);
void bssgp_flush_all_queues(void);
void bssgp_fc_flush_queue(struct bssgp_flow_control *fc);
/* gprs_bssgp_vty.c */
int bssgp_vty_init(void);
void bssgp_set_log_ss(int ss) OSMO_DEPRECATED("Use DLBSSGP instead!\n");
int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
#pragma message "Header osmocom/gprs/gprs_bssgp.h is deprecated, include osmocom/gb/gprs_bssgp.h instead"
#include <osmocom/gb/gprs_bssgp.h>

View File

@ -1,72 +1,4 @@
#pragma once
#include <stdint.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
#include <osmocom/gprs/gprs_ns2.h>
struct bssgp2_flow_ctrl;
struct gprs_ns2_inst;
struct gprs_ra_id;
struct msgb;
struct bssgp2_flow_ctrl {
uint8_t tag;
/* maximum bucket size (Bmax) in bytes */
uint64_t bucket_size_max;
/*! bucket leak rate in _bytes_ per second */
uint64_t bucket_leak_rate;
/* percentage how full the given bucket is */
uint8_t bucket_full_ratio;
bool bucket_full_ratio_present;
union {
/*! FC-BVC specifi members */
struct {
/*! default maximum bucket size per MS in bytes */
uint64_t bmax_default_ms;
/*! default bucket leak rate (R) for MS flow control bucket */
uint64_t r_default_ms;
/*! average milliseconds of queueing delay for a BVC */
uint32_t measurement;
bool measurement_present;
} bvc;
/*! FC-MS specifi members */
struct {
/*! TLLI of the MS */
uint32_t tlli;
} ms;
} u;
};
int bssgp2_nsi_tx_ptp(struct gprs_ns2_inst *nsi, uint16_t nsei, uint16_t bvci,
struct msgb *msg, uint32_t lsp);
int bssgp2_nsi_tx_sig(struct gprs_ns2_inst *nsi, uint16_t nsei, struct msgb *msg, uint32_t lsp);
struct msgb *bssgp2_enc_bvc_block(uint16_t bvci, enum gprs_bssgp_cause cause);
struct msgb *bssgp2_enc_bvc_block_ack(uint16_t bvci);
struct msgb *bssgp2_enc_bvc_unblock(uint16_t bvci);
struct msgb *bssgp2_enc_bvc_unblock_ack(uint16_t bvci);
struct msgb *bssgp2_enc_bvc_reset(uint16_t bvci, enum gprs_bssgp_cause cause,
const struct gprs_ra_id *ra_id, uint16_t cell_id,
const uint8_t *feat_bm, const uint8_t *ext_feat_bm);
struct msgb *bssgp2_enc_bvc_reset_ack(uint16_t bvci, const struct gprs_ra_id *ra_id, uint16_t cell_id,
const uint8_t *feat_bm, const uint8_t *ext_feat_bm);
struct msgb *bssgp2_enc_flush_ll(uint32_t tlli, uint16_t old_bvci,
const uint16_t *new_bvci, const uint16_t *nsei);
struct msgb *bssgp2_enc_status(uint8_t cause, const uint16_t *bvci, const struct msgb *orig_msg, uint16_t max_pdu_len);
int bssgp2_dec_fc_bvc(struct bssgp2_flow_ctrl *fc, const struct tlv_parsed *tp);
struct msgb *bssgp2_enc_fc_bvc(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran);
struct msgb *bssgp2_enc_fc_bvc_ack(uint8_t tag);
int bssgp2_dec_fc_ms(struct bssgp2_flow_ctrl *fc, struct tlv_parsed *tp);
struct msgb *bssgp2_enc_fc_ms(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran);
struct msgb *bssgp2_enc_fc_ms_ack(uint32_t tlli, uint8_t tag);
#pragma message "Header osmocom/gprs/gprs_bssgp2.h is deprecated, include osmocom/gb/gprs_bssgp2.h instead"
#include <osmocom/gb/gprs_bssgp2.h>

View File

@ -1,75 +1,4 @@
/*! \file gprs_bssgp_bss.h
* GPRS BSSGP protocol implementation as per 3GPP TS 08.18 */
/*
* (C) 2009-2012 by Harald Welte <laforge@gnumonks.org>
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <osmocom/core/msgb.h>
#include <osmocom/gprs/gprs_bssgp.h>
uint8_t *bssgp_msgb_tlli_put(struct msgb *msg, uint32_t tlli);
uint8_t *bssgp_msgb_ra_put(struct msgb *msg, const struct gprs_ra_id *ra_id);
int bssgp_tx_bvc_ptp_reset(uint16_t nsei, enum gprs_bssgp_cause cause);
int bssgp_tx_suspend(uint16_t nsei, uint32_t tlli,
const struct gprs_ra_id *ra_id);
int bssgp_tx_resume(uint16_t nsei, uint32_t tlli,
const struct gprs_ra_id *ra_id, uint8_t suspend_ref);
int bssgp_tx_ra_capa_upd(struct bssgp_bvc_ctx *bctx, uint32_t tlli, uint8_t tag);
int bssgp_tx_radio_status_tlli(struct bssgp_bvc_ctx *bctx, uint8_t cause,
uint32_t tlli);
int bssgp_tx_radio_status_tmsi(struct bssgp_bvc_ctx *bctx, uint8_t cause,
uint32_t tmsi);
int bssgp_tx_radio_status_imsi(struct bssgp_bvc_ctx *bctx, uint8_t cause,
const char *imsi);
int bssgp_tx_flush_ll_ack(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
uint8_t action, uint16_t bvci_new,
uint32_t num_octets);
int bssgp_tx_llc_discarded(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
uint8_t num_frames, uint32_t num_octets);
int bssgp_tx_bvc_block(struct bssgp_bvc_ctx *bctx, uint8_t cause);
int bssgp_tx_bvc_unblock(struct bssgp_bvc_ctx *bctx);
int bssgp_tx_bvc_reset(struct bssgp_bvc_ctx *bctx, uint16_t bvci, uint8_t cause);
int bssgp_tx_bvc_reset2(struct bssgp_bvc_ctx *bctx, uint16_t bvci, uint8_t cause, bool add_cell_id);
int bssgp_tx_ul_ud(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
const uint8_t *qos_profile, struct msgb *llc_pdu);
int bssgp_rx_paging(struct bssgp_paging_info *pinfo,
struct msgb *msg);
int bssgp_tx_fc_bvc(struct bssgp_bvc_ctx *bctx, uint8_t tag,
uint32_t bucket_size, uint32_t bucket_leak_rate,
uint32_t bmax_default_ms, uint32_t r_default_ms,
uint8_t *bucket_full_ratio, uint32_t *queue_delay_ms);
int bssgp_tx_fc_ms(struct bssgp_bvc_ctx *bctx, uint32_t tlli, uint8_t tag,
uint32_t ms_bucket_size, uint32_t bucket_leak_rate,
uint8_t *bucket_full_ratio);
#pragma message "Header osmocom/gprs/gprs_bssgp_bss.h is deprecated, include osmocom/gb/gprs_bssgp_bss.h instead"
#include <osmocom/gb/gprs_bssgp_bss.h>

View File

@ -1,272 +1,4 @@
/*! \file gprs_bssgp.h
* GPRS BSSGP RIM protocol implementation as per 3GPP TS 48.018. */
/*
* (C) 2020-2021 by sysmocom - s.f.m.c. GmbH
* Author: Philipp Maier <pmaier@sysmocom.de>
*
* All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
#include <osmocom/gprs/protocol/gsm_24_301.h>
enum bssgp_rim_routing_info_discr {
BSSGP_RIM_ROUTING_INFO_GERAN,
BSSGP_RIM_ROUTING_INFO_UTRAN,
BSSGP_RIM_ROUTING_INFO_EUTRAN,
};
extern const struct value_string bssgp_rim_routing_info_discr_strs[];
/*! Obtain a human-readable string for NACC Cause code */
static inline const char *bssgp_rim_routing_info_discr_str(enum bssgp_rim_routing_info_discr val)
{ return get_value_string(bssgp_rim_routing_info_discr_strs, val); }
/*! BSSGP RIM Routing information, see also 3GPP TS 48.018, section 11.3.70 */
struct bssgp_rim_routing_info {
enum bssgp_rim_routing_info_discr discr;
union {
struct {
struct gprs_ra_id raid;
uint16_t cid;
} geran;
struct {
struct gprs_ra_id raid;
uint16_t rncid;
} utran;
struct {
struct osmo_eutran_tai tai;
/* See also 3GPP TS 36.413 9.2.1.37 and 3GPP TS 36.401 */
uint8_t global_enb_id[8];
uint8_t global_enb_id_len;
} eutran;
};
};
/* The encoded result of the rim routing information is, depending on the
* address type (discr) of variable length. */
#define BSSGP_RIM_ROUTING_INFO_MAXLEN 14
char *bssgp_rim_ri_name_buf(char *buf, size_t buf_len, const struct bssgp_rim_routing_info *ri);
const char *bssgp_rim_ri_name(const struct bssgp_rim_routing_info *ri);
int bssgp_parse_rim_ri(struct bssgp_rim_routing_info *ri, const uint8_t *buf, unsigned int len);
int bssgp_create_rim_ri(uint8_t *buf, const struct bssgp_rim_routing_info *ri);
/* 3GPP TS 48.018, table 11.3.63.1.1: RAN-INFORMATION-REQUEST Application Container coding for NACC */
struct bssgp_ran_inf_req_app_cont_nacc {
struct osmo_cell_global_id_ps reprt_cell;
};
int bssgp_dec_ran_inf_req_app_cont_nacc(struct bssgp_ran_inf_req_app_cont_nacc *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_req_app_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_ran_inf_req_app_cont_nacc *cont);
/* Length of NACC system information, see also: 3GPP TS 48.018 11.3.63.2.1 */
#define BSSGP_RIM_SI_LEN 21
#define BSSGP_RIM_PSI_LEN 22
/* 3GPP TS 48.018, table 11.3.63.2.1.a: RAN-INFORMATION Application Container coding for NACC */
struct bssgp_ran_inf_app_cont_nacc {
struct osmo_cell_global_id_ps reprt_cell;
bool type_psi;
uint8_t num_si;
/* Pointer to system information messages */
const uint8_t *si[127];
};
int bssgp_dec_ran_inf_app_cont_nacc(struct bssgp_ran_inf_app_cont_nacc *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_app_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_ran_inf_app_cont_nacc *cont);
/* 3GPP TS 48.018, table 11.3.64.1.b, NACC Cause coding */
enum bssgp_nacc_cause {
BSSGP_NACC_CAUSE_UNSPEC,
BSSGP_NACC_CAUSE_SYNTAX_ERR,
BSSGP_NACC_CAUSE_RPRT_CELL_MISSMTCH,
BSSGP_NACC_CAUSE_SIPSI_TYPE_ERR,
BSSGP_NACC_CAUSE_SIPSI_LEN_ERR,
BSSGP_NACC_CAUSE_SIPSI_SET_ERR,
};
extern const struct value_string bssgp_nacc_cause_strs[];
/*! Obtain a human-readable string for NACC Cause code */
static inline const char *bssgp_nacc_cause_str(enum bssgp_nacc_cause val)
{ return get_value_string(bssgp_nacc_cause_strs, val); }
/* 3GPP TS 48.018, table 11.3.64.1.a, Application Error Container coding for NACC */
struct bssgp_app_err_cont_nacc {
enum bssgp_nacc_cause nacc_cause;
/* Pointer to errornous application container */
const uint8_t *err_app_cont;
size_t err_app_cont_len;
};
int bssgp_dec_app_err_cont_nacc(struct bssgp_app_err_cont_nacc *cont, const uint8_t *buf, size_t len);
int bssgp_enc_app_err_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_app_err_cont_nacc *cont);
/* 3GPP TS 48.018, table 11.3.61.b: RIM Application Identity coding */
enum bssgp_ran_inf_app_id {
BSSGP_RAN_INF_APP_ID_NACC = 1,
BSSGP_RAN_INF_APP_ID_SI3 = 2,
BSSGP_RAN_INF_APP_ID_MBMS = 3,
BSSGP_RAN_INF_APP_ID_SON = 4,
BSSGP_RAN_INF_APP_ID_UTRA_SI = 5,
};
extern const struct value_string bssgp_ran_inf_app_id_strs[];
/*! Obtain a human-readable string for RIM Application Identity code */
static inline const char *bssgp_ran_inf_app_id_str(enum bssgp_ran_inf_app_id val)
{ return get_value_string(bssgp_ran_inf_app_id_strs, val); }
/* 3GPP TS 48.018, table 11.3.62a.1.b: RAN-INFORMATION-REQUEST RIM Container Contents */
struct bssgp_ran_inf_req_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint32_t seq_num;
struct bssgp_rim_pdu_ind pdu_ind;
uint8_t prot_ver;
/* Nested application container */
union {
struct bssgp_ran_inf_req_app_cont_nacc app_cont_nacc;
/* TODO: add containers for Si3, MBMS, SON, UTRA-SI */
} u;
/* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",
* see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */
const uint8_t *son_trans_app_id;
size_t son_trans_app_id_len;
};
int bssgp_dec_ran_inf_req_rim_cont(struct bssgp_ran_inf_req_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_req_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_req_rim_cont *cont);
/* 3GPP TS 48.018, table 11.3.62a.2.b: RAN-INFORMATION RIM Container Contents */
struct bssgp_ran_inf_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint32_t seq_num;
struct bssgp_rim_pdu_ind pdu_ind;
uint8_t prot_ver;
bool app_err;
/* Nested application container */
union {
struct bssgp_ran_inf_app_cont_nacc app_cont_nacc;
struct bssgp_app_err_cont_nacc app_err_cont_nacc;
/* TODO: add containers for Si3, MBMS, SON, UTRA-SI */
} u;
/* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",
* see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */
const uint8_t *son_trans_app_id;
size_t son_trans_app_id_len;
};
int bssgp_dec_ran_inf_rim_cont(struct bssgp_ran_inf_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_rim_cont *cont);
/* 3GPP TS 48.018, table 11.3.62a.3.b: RAN-INFORMATION-ACK RIM Container Contents */
struct bssgp_ran_inf_ack_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint32_t seq_num;
uint8_t prot_ver;
/* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",
* see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */
const uint8_t *son_trans_app_id;
size_t son_trans_app_id_len;
};
int bssgp_dec_ran_inf_ack_rim_cont(struct bssgp_ran_inf_ack_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_ack_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_ack_rim_cont *cont);
/* 3GPP TS 48.018, table 11.3.62a.4.b: RAN-INFORMATION-ERROR RIM Container Contents */
struct bssgp_ran_inf_err_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint8_t cause;
uint8_t prot_ver;
/* Pointer to (encoded) errornous PDU,
* see also: 3GPP TS 48.018, section 11.3.24 */
const uint8_t *err_pdu;
size_t err_pdu_len;
/* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",
* see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */
const uint8_t *son_trans_app_id;
size_t son_trans_app_id_len;
};
int bssgp_dec_ran_inf_err_rim_cont(struct bssgp_ran_inf_err_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_err_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_err_rim_cont *cont);
/* 3GPP TS 48.018, table 11.3.62a.5.b: RAN-INFORMATION-APPLICATION-ERROR RIM Container Contents */
struct bssgp_ran_inf_app_err_rim_cont {
enum bssgp_ran_inf_app_id app_id;
uint32_t seq_num;
struct bssgp_rim_pdu_ind pdu_ind;
uint8_t prot_ver;
/* Nested application container */
union {
struct bssgp_app_err_cont_nacc app_err_cont_nacc;
/* TODO: add containers for Si3, MBMS, SON, UTRA-SI */
} u;
};
int bssgp_dec_ran_inf_app_err_rim_cont(struct bssgp_ran_inf_app_err_rim_cont *cont, const uint8_t *buf, size_t len);
int bssgp_enc_ran_inf_app_err_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_app_err_rim_cont *cont);
/* Chapter 10.6.1: RAN-INFORMATION-REQUEST */
struct bssgp_ran_information_pdu {
struct bssgp_rim_routing_info routing_info_dest;
struct bssgp_rim_routing_info routing_info_src;
/* Encoded variant of the RIM container */
uint8_t rim_cont_iei;
const uint8_t *rim_cont;
unsigned int rim_cont_len;
/* Decoded variant of the RIM container */
bool decoded_present;
union {
struct bssgp_ran_inf_req_rim_cont req_rim_cont;
struct bssgp_ran_inf_rim_cont rim_cont;
struct bssgp_ran_inf_ack_rim_cont ack_rim_cont;
struct bssgp_ran_inf_err_rim_cont err_rim_cont;
struct bssgp_ran_inf_app_err_rim_cont app_err_rim_cont;
} decoded;
/* When receiving a PDU from BSSGP the encoded variant of the RIM
* container will always be present. The decoded variant will be
* present in addition whenever BSSGP was able to decode the container.
*
* When sending a PDU to BSSGP, then the decoded variant is used when
* it is available. The encoded variant (if present) will be ignored
* then. */
};
int bssgp_parse_rim_pdu(struct bssgp_ran_information_pdu *pdu, const struct msgb *msg);
struct msgb *bssgp_encode_rim_pdu(const struct bssgp_ran_information_pdu *pdu);
int bssgp_tx_rim(const struct bssgp_ran_information_pdu *pdu, uint16_t nsei);
#pragma message "Header osmocom/gprs/gprs_bssgp_rim.h is deprecated, include osmocom/gb/gprs_bssgp_rim.h instead"
#include <osmocom/gb/gprs_bssgp_rim.h>

View File

@ -1,33 +1,4 @@
/*! \file gprs_msgb.h */
#pragma once
#include <stdint.h>
/*! the data structure stored in msgb->cb for libgb apps */
struct libgb_msgb_cb {
unsigned char *bssgph;
unsigned char *llch;
/*! Cell Identifier */
unsigned char *bssgp_cell_id;
/*! Identifiers of a BTS, equal to 'struct bssgp_bts_ctx' */
uint16_t nsei;
uint16_t bvci;
/*! Identifier of a MS (inside BTS), equal to 'struct sgsn_mm_ctx' */
uint32_t tlli;
} __attribute__((packed, may_alias));
#define LIBGB_MSGB_CB(__msgb) ((struct libgb_msgb_cb *)&((__msgb)->cb[0]))
#define msgb_tlli(__x) LIBGB_MSGB_CB(__x)->tlli
#define msgb_nsei(__x) LIBGB_MSGB_CB(__x)->nsei
#define msgb_bvci(__x) LIBGB_MSGB_CB(__x)->bvci
#define msgb_gmmh(__x) (__x)->l3h
#define msgb_bssgph(__x) LIBGB_MSGB_CB(__x)->bssgph
#define msgb_bssgp_len(__x) ((__x)->tail - (uint8_t *)msgb_bssgph(__x))
#define msgb_bcid(__x) LIBGB_MSGB_CB(__x)->bssgp_cell_id
#define msgb_llch(__x) LIBGB_MSGB_CB(__x)->llch
#include <osmocom/core/logging.h>
int gprs_log_filter_fn(const struct log_context *ctx,
struct log_target *tar);
#pragma message "Header osmocom/gprs/gprs_msgb.h is deprecated, include osmocom/gb/gprs_msgb.h instead"
#include <osmocom/gb/gprs_msgb.h>

View File

@ -1,258 +1,4 @@
/*! \file gprs_ns.h */
#pragma once
#include <stdint.h>
/* Our Implementation */
#include <netinet/in.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/select.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>
#define NS_TIMERS_COUNT 8
#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries|tsns-prov)"
#define NS_TIMERS_HELP \
"(un)blocking Timer (Tns-block) timeout\n" \
"(un)blocking Timer (Tns-block) number of retries\n" \
"Reset Timer (Tns-reset) timeout\n" \
"Reset Timer (Tns-reset) number of retries\n" \
"Test Timer (Tns-test) timeout\n" \
"Alive Timer (Tns-alive) timeout\n" \
"Alive Timer (Tns-alive) number of retries\n" \
"SNS Provision Timer (Tsns-prov) timeout\n"
/* Educated guess - LLC user payload is 1500 bytes plus possible headers */
#define NS_ALLOC_SIZE 3072
#define NS_ALLOC_HEADROOM 20
enum ns_timeout {
NS_TOUT_TNS_BLOCK,
NS_TOUT_TNS_BLOCK_RETRIES,
NS_TOUT_TNS_RESET,
NS_TOUT_TNS_RESET_RETRIES,
NS_TOUT_TNS_TEST,
NS_TOUT_TNS_ALIVE,
NS_TOUT_TNS_ALIVE_RETRIES,
NS_TOUT_TSNS_PROV,
};
#define NSE_S_BLOCKED 0x0001
#define NSE_S_ALIVE 0x0002
#define NSE_S_RESET 0x0004
#define NS_DESC_B(st) ((st) & NSE_S_BLOCKED ? "BLOCKED" : "UNBLOCKED")
#define NS_DESC_A(st) ((st) & NSE_S_ALIVE ? "ALIVE" : "DEAD")
#define NS_DESC_R(st) ((st) & NSE_S_RESET ? "RESET" : "UNRESET")
/*! Osmocom NS link layer types */
enum gprs_ns_ll {
GPRS_NS_LL_UDP, /*!< NS/UDP/IP */
GPRS_NS_LL_E1, /*!< NS/E1 */
GPRS_NS_LL_FR_GRE, /*!< NS/FR/GRE/IP */
};
/*! Osmoco NS events */
enum gprs_ns_evt {
GPRS_NS_EVT_UNIT_DATA,
};
/*! Osmocom NS VC create status */
enum gprs_ns_cs {
GPRS_NS_CS_CREATED, /*!< A NSVC object has been created */
GPRS_NS_CS_FOUND, /*!< A NSVC object has been found */
GPRS_NS_CS_REJECTED, /*!< Rejected and answered message */
GPRS_NS_CS_SKIPPED, /*!< Skipped message */
GPRS_NS_CS_ERROR, /*!< Failed to process message */
};
struct gprs_nsvc;
/*! Osmocom GPRS callback function type */
typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
struct msgb *msg, uint16_t bvci);
/*! An instance of the NS protocol stack */
struct gprs_ns_inst {
/*! callback to the user for incoming UNIT DATA IND */
gprs_ns_cb_t *cb;
/*! linked lists of all NSVC in this instance */
struct llist_head gprs_nsvcs;
/*! a NSVC object that's needed to deal with packets for
* unknown NSVC */
struct gprs_nsvc *unknown_nsvc;
uint16_t timeout[NS_TIMERS_COUNT];
/*! NS-over-IP specific bits */
struct {
struct osmo_fd fd;
uint32_t local_ip;
uint16_t local_port;
uint32_t remote_ip;
uint16_t remote_port;
int dscp;
/*! IPA compatibility: NS-RESET/BLOCK/UNBLOCK even on IP-SNS */
bool use_reset_block_unblock;
} nsip;
/*! NS-over-FR-over-GRE-over-IP specific bits */
struct {
struct osmo_fd fd;
uint32_t local_ip;
unsigned int enabled:1;
} frgre;
struct osmo_fsm_inst *bss_sns_fi;
};
enum nsvc_timer_mode {
/* standard timers */
NSVC_TIMER_TNS_TEST,
NSVC_TIMER_TNS_ALIVE,
NSVC_TIMER_TNS_RESET,
_NSVC_TIMER_NR,
};
/*! Structure representing a single NS-VC */
struct gprs_nsvc {
/*! list of NS-VCs within NS Instance */
struct llist_head list;
/*! pointer to NS Instance */
struct gprs_ns_inst *nsi;
uint16_t nsei; /*! end-to-end significance */
uint16_t nsvci; /*! uniquely identifies NS-VC at SGSN */
uint32_t state;
uint32_t remote_state;
struct osmo_timer_list timer;
enum nsvc_timer_mode timer_mode;
struct timeval timer_started;
int alive_retries;
unsigned int remote_end_is_sgsn:1;
unsigned int persistent:1;
unsigned int nsvci_is_valid:1;
struct rate_ctr_group *ctrg;
struct osmo_stat_item_group *statg;
/*! which link-layer are we based on? */
enum gprs_ns_ll ll;
/*! make sure to always keep bts_addr as first struct member to not break the assumption
that those structs are similar */
union {
struct {
struct sockaddr_in bts_addr;
} ip;
struct {
struct sockaddr_in bts_addr;
} frgre;
};
/*! signalling weight. 0 = don't use for signalling (BVCI == 0)*/
uint8_t sig_weight;
/*! signaling weight. 0 = don't use for user data (BVCI != 0) */
uint8_t data_weight;
};
/* Create a new NS protocol instance */
struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb, void *ctx);
/* Close a NS protocol instance */
void gprs_ns_close(struct gprs_ns_inst *nsi);
/* Close and Destroy a NS protocol instance */
void gprs_ns_destroy(struct gprs_ns_inst *nsi);
/* Listen for incoming GPRS packets via NS/UDP */
int gprs_ns_nsip_listen(struct gprs_ns_inst *nsi);
/* Establish a connection (from the BSS) to the SGSN */
struct gprs_nsvc *gprs_ns_nsip_connect(struct gprs_ns_inst *nsi,
struct sockaddr_in *dest,
uint16_t nsei, uint16_t nsvci);
/* Establish a connection (from the BSS) to the SGSN using IP SNS */
struct gprs_nsvc *gprs_ns_nsip_connect_sns(struct gprs_ns_inst *nsi, struct sockaddr_in *dest,
uint16_t nsei, uint16_t nsvci);
struct sockaddr_in;
/* main function for higher layers (BSSGP) to send NS messages */
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
/* Receive incoming NS message from underlying transport layer */
int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
struct sockaddr_in *saddr, enum gprs_ns_ll ll);
int gprs_ns_tx_alive(struct gprs_nsvc *nsvc);
int gprs_ns_tx_alive_ack(struct gprs_nsvc *nsvc);
int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause);
int gprs_ns_tx_block(struct gprs_nsvc *nsvc, uint8_t cause);
int gprs_ns_tx_unblock(struct gprs_nsvc *nsvc);
/* Listen for incoming GPRS packets via NS/FR/GRE */
int gprs_ns_frgre_listen(struct gprs_ns_inst *nsi);
struct gprs_nsvc *gprs_nsvc_create2(struct gprs_ns_inst *nsi, uint16_t nsvci,
uint8_t sig_weight, uint8_t data_weight);
void gprs_nsvc_delete(struct gprs_nsvc *nsvc);
struct gprs_nsvc *gprs_nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
struct gprs_nsvc *gprs_nsvc_by_nsvci(struct gprs_ns_inst *nsi, uint16_t nsvci);
struct gprs_nsvc *gprs_nsvc_by_rem_addr(struct gprs_ns_inst *nsi, const struct sockaddr_in *sin);
/* Initiate a RESET procedure (including timer start, ...)*/
int gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause);
/* Add NS-specific VTY stuff */
int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
/* Resturn peer info as string (NOTE: the buffer is allocated statically) */
const char *gprs_ns_ll_str(const struct gprs_nsvc *nsvc);
/* Return peer info in user-supplied buffer */
char *gprs_ns_ll_str_buf(char *buf, size_t buf_len, const struct gprs_nsvc *nsvc);
char *gprs_ns_ll_str_c(const void *ctx, const struct gprs_nsvc *nsvc);
/* Copy the link layer info from other into nsvc */
void gprs_ns_ll_copy(struct gprs_nsvc *nsvc, struct gprs_nsvc *other);
/* Clear the link layer info (will never match a real link then) */
void gprs_ns_ll_clear(struct gprs_nsvc *nsvc);
struct msgb *gprs_ns_msgb_alloc(void);
enum signal_ns {
S_NS_RESET,
S_NS_BLOCK,
S_NS_UNBLOCK,
S_NS_ALIVE_EXP, /* Tns-alive expired more than N times */
S_NS_REPLACED, /* nsvc object is replaced (sets old_nsvc) */
S_NS_MISMATCH, /* got an unexpected IE (sets msg, pdu_type, ie_type) */
S_SNS_CONFIGURED, /* IP-SNS configuration completed */
};
extern const struct value_string gprs_ns_signal_ns_names[];
const char *gprs_ns_cause_str(enum ns_cause cause);
struct ns_signal_data {
struct gprs_nsvc *nsvc;
struct gprs_nsvc *old_nsvc;
uint8_t cause;
uint8_t pdu_type;
uint8_t ie_type;
struct msgb *msg;
};
void gprs_ns_set_log_ss(int ss);
char *gprs_nsvc_state_append(char *s, struct gprs_nsvc *nsvc);
/*! @} */
#pragma message "Header osmocom/gprs/gprs_ns.h is deprecated, include osmocom/gb/gprs_ns.h instead"
#include <osmocom/gb/gprs_ns.h>

View File

@ -1,276 +1,4 @@
/*! \file gprs_ns2.h */
#pragma once
#include <stdint.h>
#include <netinet/in.h>
#include <osmocom/core/prim.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>
#include <osmocom/gprs/frame_relay.h>
struct osmo_sockaddr;
struct osmo_sockaddr_str;
struct osmo_fr_network;
struct gprs_ns2_inst;
struct gprs_ns2_nse;
struct gprs_ns2_vc;
struct gprs_ns2_vc_bind;
struct gprs_ns2_vc_driver;
struct gprs_ns_ie_ip4_elem;
struct gprs_ns_ie_ip6_elem;
enum gprs_ns2_vc_mode {
/*! The VC will use RESET/BLOCK/UNBLOCK to start the connection and do ALIVE/ACK.
* This is what is needed for Frame Relay transport, and if you use a R97/R99 Gb
* interface over an IP transport (never standardized by 3GPP) */
GPRS_NS2_VC_MODE_BLOCKRESET,
/*! The VC will only use ALIVE/ACK (no RESET/BLOCK/UNBLOCK), which is for Gb-IP
* interface compliant to 3GPP Rel=4 or later. */
GPRS_NS2_VC_MODE_ALIVE,
};
enum gprs_ns2_dialect {
GPRS_NS2_DIALECT_UNDEF,
GPRS_NS2_DIALECT_STATIC_ALIVE,
GPRS_NS2_DIALECT_STATIC_RESETBLOCK,
GPRS_NS2_DIALECT_IPACCESS,
GPRS_NS2_DIALECT_SNS,
};
/*! Osmocom NS link layer types */
enum gprs_ns2_ll {
GPRS_NS2_LL_UNDEF, /*!< undefined, used by vty */
GPRS_NS2_LL_UDP, /*!< NS/UDP/IP */
GPRS_NS2_LL_FR, /*!< NS/FR */
GPRS_NS2_LL_FR_GRE, /*!< NS/FR/GRE/IP */
};
/*! Osmocom NS primitives according to 48.016 5.2 Service primitives */
enum gprs_ns2_prim {
GPRS_NS2_PRIM_UNIT_DATA,
GPRS_NS2_PRIM_CONGESTION,
GPRS_NS2_PRIM_STATUS,
};
extern const struct value_string gprs_ns2_prim_strs[];
extern const struct value_string gprs_ns2_lltype_strs[];
/*! Obtain a human-readable string for NS primitives */
static inline const char *gprs_ns2_prim_str(enum gprs_ns2_prim val)
{ return get_value_string(gprs_ns2_prim_strs, val); }
/*! Obtain a human-readable string for NS link-layer type */
static inline const char *gprs_ns2_lltype_str(enum gprs_ns2_ll val)
{ return get_value_string(gprs_ns2_lltype_strs, val); }
/*! Osmocom NS primitives according to 48.016 5.2.2.4 Service primitives */
enum gprs_ns2_congestion_cause {
GPRS_NS2_CONG_CAUSE_BACKWARD_BEGIN,
GPRS_NS2_CONG_CAUSE_BACKWARD_END,
GPRS_NS2_CONG_CAUSE_FORWARD_BEGIN,
GPRS_NS2_CONG_CAUSE_FORWARD_END,
};
/*! Osmocom NS primitives according to 48.016 5.2.2.6 Service primitives */
enum gprs_ns2_affecting_cause {
GPRS_NS2_AFF_CAUSE_VC_FAILURE,
GPRS_NS2_AFF_CAUSE_VC_RECOVERY,
GPRS_NS2_AFF_CAUSE_FAILURE,
GPRS_NS2_AFF_CAUSE_RECOVERY,
/* osmocom own causes */
GPRS_NS2_AFF_CAUSE_SNS_CONFIGURED,
GPRS_NS2_AFF_CAUSE_SNS_FAILURE,
GPRS_NS2_AFF_CAUSE_SNS_NO_ENDPOINTS,
GPRS_NS2_AFF_CAUSE_MTU_CHANGE,
};
extern const struct value_string gprs_ns2_aff_cause_prim_strs[];
/*! Obtain a human-readable string for NS affecting cause in primitives */
static inline const char *gprs_ns2_aff_cause_prim_str(enum gprs_ns2_affecting_cause val)
{ return get_value_string(gprs_ns2_aff_cause_prim_strs, val); }
/*! Osmocom NS primitives according to 48.016 5.2.2.7 Service primitives */
enum gprs_ns2_change_ip_endpoint {
GRPS_NS2_ENDPOINT_NO_CHANGE,
GPRS_NS2_ENDPOINT_REQUEST_CHANGE,
GPRS_NS2_ENDPOINT_CONFIRM_CHANGE,
};
extern const struct value_string gprs_ns2_cause_strs[];
/*! Obtain a human-readable string for NS primitives */
static inline const char *gprs_ns2_cause_str(enum ns_cause val)
{ return get_value_string(gprs_ns2_cause_strs, val); }
struct osmo_gprs_ns2_prim {
struct osmo_prim_hdr oph;
uint16_t nsei;
uint16_t bvci;
union {
struct {
enum gprs_ns2_change_ip_endpoint change;
uint32_t link_selector;
/* TODO: implement resource distribution
* add place holder for the link selector */
long long _resource_distribution_placeholder1;
long long _resource_distribution_placeholder2;
long long _resource_distribution_placeholder3;
} unitdata;
struct {
enum gprs_ns2_congestion_cause cause;
} congestion;
struct {
enum gprs_ns2_affecting_cause cause;
char *nsvc;
/* 48.016 5.2.2.6 transfer capability */
int transfer;
/* osmocom specific */
/* Persistent NSE/NSVC are configured by vty */
bool persistent;
/* Only true on the first time it's available.
* Allow the BSSGP layer to reset persistent NSE */
bool first;
/* MTU of a NS SDU. It's the lowest MTU of all (alive & dead) NSVCs */
uint16_t mtu;
} status;
} u;
};
/* instance */
struct gprs_ns2_inst *gprs_ns2_instantiate(void *ctx, osmo_prim_cb cb, void *cb_data);
void gprs_ns2_free(struct gprs_ns2_inst *inst);
/* Entrypoint for primitives from the NS USER */
int gprs_ns2_recv_prim(struct gprs_ns2_inst *nsi, struct osmo_prim_hdr *oph);
/*! a callback to iterate over all NSVC */
typedef int (*gprs_ns2_foreach_nsvc_cb)(struct gprs_ns2_vc *nsvc, void *ctx);
int gprs_ns2_nse_foreach_nsvc(struct gprs_ns2_nse *nse,
gprs_ns2_foreach_nsvc_cb cb, void *cb_data);
struct gprs_ns2_nse *gprs_ns2_nse_by_nsei(struct gprs_ns2_inst *nsi, uint16_t nsei);
struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t nsei,
enum gprs_ns2_ll linklayer,
enum gprs_ns2_dialect dialect);
struct gprs_ns2_nse *gprs_ns2_create_nse2(struct gprs_ns2_inst *nsi, uint16_t nsei,
enum gprs_ns2_ll linklayer,
enum gprs_ns2_dialect dialect, bool local_sgsn_role);
uint16_t gprs_ns2_nse_nsei(struct gprs_ns2_nse *nse);
void gprs_ns2_free_nse(struct gprs_ns2_nse *nse);
void gprs_ns2_free_nses(struct gprs_ns2_inst *nsi);
/* create vc */
void gprs_ns2_free_nsvc(struct gprs_ns2_vc *nsvc);
void gprs_ns2_free_nsvcs(struct gprs_ns2_nse *nse);
struct gprs_ns2_vc *gprs_ns2_nsvc_by_nsvci(struct gprs_ns2_inst *nsi, uint16_t nsvci);
/* generic VL driver */
struct gprs_ns2_vc_bind *gprs_ns2_bind_by_name(struct gprs_ns2_inst *nsi,
const char *name);
/* IP VL driver */
int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
const char *name,
const struct osmo_sockaddr *local,
int dscp,
struct gprs_ns2_vc_bind **result);
struct gprs_ns2_vc_bind *gprs_ns2_ip_bind_by_sockaddr(struct gprs_ns2_inst *nsi,
const struct osmo_sockaddr *sockaddr);
/* FR VL driver */
struct gprs_ns2_vc_bind *gprs_ns2_fr_bind_by_netif(
struct gprs_ns2_inst *nsi,
const char *netif);
const char *gprs_ns2_fr_bind_netif(struct gprs_ns2_vc_bind *bind);
enum osmo_fr_role gprs_ns2_fr_bind_role(struct gprs_ns2_vc_bind *bind);
int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
const char *name,
const char *netif,
struct osmo_fr_network *fr_network,
enum osmo_fr_role fr_role,
struct gprs_ns2_vc_bind **result);
int gprs_ns2_is_fr_bind(struct gprs_ns2_vc_bind *bind);
struct gprs_ns2_vc *gprs_ns2_fr_nsvc_by_dlci(struct gprs_ns2_vc_bind *bind, uint16_t dlci);
struct gprs_ns2_vc *gprs_ns2_fr_connect(struct gprs_ns2_vc_bind *bind,
struct gprs_ns2_nse *nse,
uint16_t nsvci,
uint16_t dlci);
struct gprs_ns2_vc *gprs_ns2_fr_connect2(struct gprs_ns2_vc_bind *bind,
uint16_t nsei,
uint16_t nsvci,
uint16_t dlci);
/* create a VC connection */
struct gprs_ns2_vc *gprs_ns2_ip_connect(struct gprs_ns2_vc_bind *bind,
const struct osmo_sockaddr *remote,
struct gprs_ns2_nse *nse,
uint16_t nsvci);
struct gprs_ns2_vc *gprs_ns2_ip_connect2(struct gprs_ns2_vc_bind *bind,
const struct osmo_sockaddr *remote,
uint16_t nsei,
uint16_t nsvci,
enum gprs_ns2_dialect dialect);
struct gprs_ns2_vc *gprs_ns2_ip_connect_inactive(struct gprs_ns2_vc_bind *bind,
const struct osmo_sockaddr *remote,
struct gprs_ns2_nse *nse,
uint16_t nsvci);
void gprs_ns2_ip_bind_set_sns_weight(struct gprs_ns2_vc_bind *bind,
uint8_t signalling, uint8_t data);
void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind);
void gprs_ns2_free_binds(struct gprs_ns2_inst *nsi);
/* create a VC SNS connection */
int gprs_ns2_sns_count(struct gprs_ns2_nse *nse);
int gprs_ns2_sns_add_endpoint(struct gprs_ns2_nse *nse,
const struct osmo_sockaddr *saddr);
int gprs_ns2_sns_del_endpoint(struct gprs_ns2_nse *nse,
const struct osmo_sockaddr *saddr);
int gprs_ns2_sns_add_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);
int gprs_ns2_sns_del_bind(struct gprs_ns2_nse *nse, struct gprs_ns2_vc_bind *bind);
const struct osmo_sockaddr *gprs_ns2_nse_sns_remote(struct gprs_ns2_nse *nse);
const struct osmo_sockaddr *gprs_ns2_ip_vc_remote(const struct gprs_ns2_vc *nsvc);
const struct osmo_sockaddr *gprs_ns2_ip_vc_local(const struct gprs_ns2_vc *nsvc);
bool gprs_ns2_ip_vc_equal(const struct gprs_ns2_vc *nsvc,
const struct osmo_sockaddr *local,
const struct osmo_sockaddr *remote,
uint16_t nsvci);
const struct osmo_sockaddr *gprs_ns2_ip_bind_sockaddr(struct gprs_ns2_vc_bind *bind);
int gprs_ns2_is_ip_bind(struct gprs_ns2_vc_bind *bind);
int gprs_ns2_ip_bind_set_dscp(struct gprs_ns2_vc_bind *bind, int dscp);
int gprs_ns2_ip_bind_set_priority(struct gprs_ns2_vc_bind *bind, uint8_t priority);
struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_bind(
struct gprs_ns2_vc_bind *bind,
const struct osmo_sockaddr *saddr);
int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
const char *name,
const struct osmo_sockaddr *local,
int dscp,
struct gprs_ns2_vc_bind **result);
int gprs_ns2_is_frgre_bind(struct gprs_ns2_vc_bind *bind);
uint16_t gprs_ns2_fr_nsvc_dlci(const struct gprs_ns2_vc *nsvc);
struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_nse(
struct gprs_ns2_nse *nse,
const struct osmo_sockaddr *sockaddr);
void gprs_ns2_start_alive_all_nsvcs(struct gprs_ns2_nse *nse);
/* VC information */
const char *gprs_ns2_ll_str(struct gprs_ns2_vc *nsvc);
char *gprs_ns2_ll_str_buf(char *buf, size_t buf_len, struct gprs_ns2_vc *nsvc);
char *gprs_ns2_ll_str_c(const void *ctx, struct gprs_ns2_vc *nsvc);
const char *gprs_ns2_nsvc_state_name(struct gprs_ns2_vc *nsvc);
/* vty */
int gprs_ns2_vty_init(struct gprs_ns2_inst *nsi);
/*! @} */
#pragma message "Header osmocom/gprs/gprs_ns2.h is deprecated, include osmocom/gb/gprs_ns2.h instead"
#include <osmocom/gb/gprs_ns2.h>

View File

@ -1,8 +1,4 @@
/*! \file gprs_ns_frgre.h */
#pragma once
struct gprs_nsvc;
struct msgb;
int gprs_ns_frgre_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg);
#pragma message "Header osmocom/gprs/gprs_ns_frgre.h is deprecated, include osmocom/gb/gprs_ns_frgre.h instead"
#include <osmocom/gb/gprs_ns_frgre.h>

View File

@ -1,103 +1,4 @@
/*! \file gsm_08_16.h
* GPRS Networks Service (NS) messages on the Gb interface.
* 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
* 3GPP TS 48.016 version 6.5.0 Release 6 / ETSI TS 148 016 V6.5.0 (2005-11) */
#pragma once
#include <stdint.h>
#include <arpa/inet.h>
#include <osmocom/core/utils.h>
/*! \addtogroup libgb
* @{
* \file gprs_ns.h */
/*! Common header of GPRS NS */
struct gprs_ns_hdr {
uint8_t pdu_type; /*!< NS PDU type */
uint8_t data[0]; /*!< variable-length payload */
} __attribute__((packed));
/*! Section 10.3.2c List of IP4 Elements */
struct gprs_ns_ie_ip4_elem {
uint32_t ip_addr;
uint16_t udp_port;
uint8_t sig_weight;
uint8_t data_weight;
} __attribute__ ((packed));
/*! Section 10.3.2d List of IP6 Elements */
struct gprs_ns_ie_ip6_elem {
struct in6_addr ip_addr;
uint16_t udp_port;
uint8_t sig_weight;
uint8_t data_weight;
} __attribute__ ((packed));
extern const struct value_string gprs_ns_pdu_strings[];
/*! NS PDU Type (TS 08.16, Section 10.3.7, Table 14) */
enum ns_pdu_type {
NS_PDUT_UNITDATA = 0x00,
NS_PDUT_RESET = 0x02,
NS_PDUT_RESET_ACK = 0x03,
NS_PDUT_BLOCK = 0x04,
NS_PDUT_BLOCK_ACK = 0x05,
NS_PDUT_UNBLOCK = 0x06,
NS_PDUT_UNBLOCK_ACK = 0x07,
NS_PDUT_STATUS = 0x08,
NS_PDUT_ALIVE = 0x0a,
NS_PDUT_ALIVE_ACK = 0x0b,
/* TS 48.016 Section 10.3.7, Table 10.3.7.1 */
SNS_PDUT_ACK = 0x0c,
SNS_PDUT_ADD = 0x0d,
SNS_PDUT_CHANGE_WEIGHT = 0x0e,
SNS_PDUT_CONFIG = 0x0f,
SNS_PDUT_CONFIG_ACK = 0x10,
SNS_PDUT_DELETE = 0x11,
SNS_PDUT_SIZE = 0x12,
SNS_PDUT_SIZE_ACK = 0x13,
};
/*! NS Control IE (TS 08.16, Section 10.3, Table 12) */
enum ns_ctrl_ie {
NS_IE_CAUSE = 0x00,
NS_IE_VCI = 0x01,
NS_IE_PDU = 0x02,
NS_IE_BVCI = 0x03,
NS_IE_NSEI = 0x04,
/* TS 48.016 Section 10.3, Table 10.3.1 */
NS_IE_IPv4_LIST = 0x05,
NS_IE_IPv6_LIST = 0x06,
NS_IE_MAX_NR_NSVC = 0x07,
NS_IE_IPv4_EP_NR = 0x08,
NS_IE_IPv6_EP_NR = 0x09,
NS_IE_RESET_FLAG = 0x0a,
NS_IE_IP_ADDR = 0x0b,
NS_IE_TRANS_ID = 0xff, /* osmocom. Spec has this IE but without IEI! */
};
/*! NS Cause (TS 08.16, Section 10.3.2, Table 13) */
enum ns_cause {
NS_CAUSE_TRANSIT_FAIL = 0x00,
NS_CAUSE_OM_INTERVENTION = 0x01,
NS_CAUSE_EQUIP_FAIL = 0x02,
NS_CAUSE_NSVC_BLOCKED = 0x03,
NS_CAUSE_NSVC_UNKNOWN = 0x04,
NS_CAUSE_BVCI_UNKNOWN = 0x05,
NS_CAUSE_SEM_INCORR_PDU = 0x08,
NS_CAUSE_PDU_INCOMP_PSTATE = 0x0a,
NS_CAUSE_PROTO_ERR_UNSPEC = 0x0b,
NS_CAUSE_INVAL_ESSENT_IE = 0x0c,
NS_CAUSE_MISSING_ESSENT_IE = 0x0d,
/* TS 48.016 Section 10.3.2, Table 10.3.2.1 */
NS_CAUSE_INVAL_NR_IPv4_EP = 0x0e,
NS_CAUSE_INVAL_NR_IPv6_EP = 0x0f,
NS_CAUSE_INVAL_NR_NS_VC = 0x10,
NS_CAUSE_INVAL_WEIGH = 0x11,
NS_CAUSE_UNKN_IP_EP = 0x12,
NS_CAUSE_UNKN_IP_ADDR = 0x13,
NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14,
};
#pragma message "Header osmocom/gprs/protocol/gsm_08_16.h is deprecated, include osmocom/gb/protocol/gsm_08_16.h instead"
#include <osmocom/gb/protocol/gsm_08_16.h>

View File

@ -1,373 +1,4 @@
/*! \file gsm_08_18.h */
/* Updated to reflect TS 48.018 version 15.0.0 Release 15 */
#pragma once
#include <stdint.h>
#include <osmocom/core/endian.h>
/*! Fixed BVCI definitions (Section 5.4.1) */
#define BVCI_SIGNALLING 0x0000
#define BVCI_PTM 0x0001
/* typo backwards compatiblity */
#define BSSGP_PDUT_RA_CAPA_UDPATE BSSGP_PDUT_RA_CAPA_UPDATE
/*! BSSGP PDU types (Section 11.3.26 / Table 11.27) */
enum bssgp_pdu_type {
/* PDUs between RL and BSSGP SAPs */
BSSGP_PDUT_DL_UNITDATA = 0x00,
BSSGP_PDUT_UL_UNITDATA = 0x01,
BSSGP_PDUT_RA_CAPABILITY = 0x02,
/* PDUs between MBMS SAPs */
BSSGP_PDUT_PTM_UNITDATA = 0x03, /* reserved in later specs */
BSSGP_PDUT_DL_MMBS_UNITDATA = 0x04,
BSSGP_PDUT_UL_MMBS_UNITDATA = 0x05,
/* PDUs between GMM SAPs */
BSSGP_PDUT_PAGING_PS = 0x06,
BSSGP_PDUT_PAGING_CS = 0x07,
BSSGP_PDUT_RA_CAPA_UPDATE = 0x08,
BSSGP_PDUT_RA_CAPA_UPDATE_ACK = 0x09,
BSSGP_PDUT_RADIO_STATUS = 0x0a,
BSSGP_PDUT_SUSPEND = 0x0b,
BSSGP_PDUT_SUSPEND_ACK = 0x0c,
BSSGP_PDUT_SUSPEND_NACK = 0x0d,
BSSGP_PDUT_RESUME = 0x0e,
BSSGP_PDUT_RESUME_ACK = 0x0f,
BSSGP_PDUT_RESUME_NACK = 0x10,
BSSGP_PDUT_PAGING_PS_REJECT = 0x11,
BSSGP_PDUT_DUMMY_PAGING_PS = 0x12,
BSSGP_PDUT_DUMMY_PAGING_PS_RESP = 0x13,
BSSGP_PDUT_MS_REGISTR_ENQ = 0x14,
BSSGP_PDUT_MS_REGISTR_ENQ_RESP = 0x15,
/* PDus between NM SAPs */
BSSGP_PDUT_BVC_BLOCK = 0x20,
BSSGP_PDUT_BVC_BLOCK_ACK = 0x21,
BSSGP_PDUT_BVC_RESET = 0x22,
BSSGP_PDUT_BVC_RESET_ACK = 0x23,
BSSGP_PDUT_BVC_UNBLOCK = 0x24,
BSSGP_PDUT_BVC_UNBLOCK_ACK = 0x25,
BSSGP_PDUT_FLOW_CONTROL_BVC = 0x26,
BSSGP_PDUT_FLOW_CONTROL_BVC_ACK = 0x27,
BSSGP_PDUT_FLOW_CONTROL_MS = 0x28,
BSSGP_PDUT_FLOW_CONTROL_MS_ACK = 0x29,
BSSGP_PDUT_FLUSH_LL = 0x2a,
BSSGP_PDUT_FLUSH_LL_ACK = 0x2b,
BSSGP_PDUT_LLC_DISCARD = 0x2c,
BSSGP_PDUT_FLOW_CONTROL_PFC = 0x2d,
BSSGP_PDUT_FLOW_CONTROL_PFC_ACK = 0x2e,
BSSGP_PDUT_SGSN_INVOKE_TRACE = 0x40,
BSSGP_PDUT_STATUS = 0x41,
BSSGP_PDUT_OVERLOAD = 0x42,
/* PDUs between PFM SAP's */
BSSGP_PDUT_DOWNLOAD_BSS_PFC = 0x50,
BSSGP_PDUT_CREATE_BSS_PFC = 0x51,
BSSGP_PDUT_CREATE_BSS_PFC_ACK = 0x52,
BSSGP_PDUT_CREATE_BSS_PFC_NACK = 0x53,
BSSGP_PDUT_MODIFY_BSS_PFC = 0x54,
BSSGP_PDUT_MODIFY_BSS_PFC_ACK = 0x55,
BSSGP_PDUT_DELETE_BSS_PFC = 0x56,
BSSGP_PDUT_DELETE_BSS_PFC_ACK = 0x57,
BSSGP_PDUT_DELETE_BSS_PFC_REQ = 0x58,
BSSGP_PDUT_PS_HO_REQUIRED = 0x59,
BSSGP_PDUT_PS_HO_REQUIRED_ACK = 0x5a,
BSSGP_PDUT_PS_HO_REQUIRED_NACK = 0x5b,
BSSGP_PDUT_PS_HO_REQUEST = 0x5c,
BSSGP_PDUT_PS_HO_REQUEST_ACK = 0x5d,
BSSGP_PDUT_PS_HO_REQUEST_NACK = 0x5e,
BSSGP_PDUT_PS_HO_COMPLETE = 0x91,
BSSGP_PDUT_PS_HO_CANCEL = 0x92,
BSSGP_PDUT_PS_HO_COMPLETE_ACK = 0x93,
/* PDUs between LCS SAPs */
BSSGP_PDUT_PERFORM_LOC_REQ = 0x60,
BSSGP_PDUT_PERFORM_LOC_RESP = 0x61,
BSSGP_PDUT_PERFORM_LOC_ABORT = 0x62,
BSSGP_PDUT_POSITION_COMMAND = 0x63,
BSSGP_PDUT_POSITION_RESPONSE = 0x64,
/* PDUs between RIM SAPs */
BSSGP_PDUT_RAN_INFO = 0x70,
BSSGP_PDUT_RAN_INFO_REQ = 0x71,
BSSGP_PDUT_RAN_INFO_ACK = 0x72,
BSSGP_PDUT_RAN_INFO_ERROR = 0x73,
BSSGP_PDUT_RAN_INFO_APP_ERROR = 0x74,
/* PDUs between MBMS SAPs */
BSSGP_PDUT_MBMS_START_REQ = 0x80,
BSSGP_PDUT_MBMS_START_RESP = 0x81,
BSSGP_PDUT_MBMS_STOP_REQ = 0x82,
BSSGP_PDUT_MBMS_STOP_RESP = 0x83,
BSSGP_PDUT_MBMS_UPDATE_REQ = 0x84,
BSSGP_PDUT_MBMS_UPDATE_RESP = 0x85,
};
/*! BSSGP User-Data header (Section 10.2.1 and 10.2.2) */
struct bssgp_ud_hdr {
uint8_t pdu_type; /*!< BSSGP PDU type */
uint32_t tlli; /*!< Temporary Link-Local Identifier */
uint8_t qos_profile[3]; /*!< QoS profile */
uint8_t data[0]; /* optional/conditional IEs as TLVs */
} __attribute__((packed));
/*! BSSGP normal header */
struct bssgp_normal_hdr {
uint8_t pdu_type; /*!< BSSGP PDU type */
uint8_t data[0]; /*!< optional/conditional IEs as TLVs */
};
/*! BSSGP Information Element Identifiers (Section 11.3 / Table 11.3) */
enum bssgp_iei_type {
BSSGP_IE_ALIGNMENT = 0x00,
BSSGP_IE_BMAX_DEFAULT_MS = 0x01,
BSSGP_IE_BSS_AREA_ID = 0x02,
BSSGP_IE_BUCKET_LEAK_RATE = 0x03,
BSSGP_IE_BVCI = 0x04,
BSSGP_IE_BVC_BUCKET_SIZE = 0x05,
BSSGP_IE_BVC_MEASUREMENT = 0x06,
BSSGP_IE_CAUSE = 0x07,
BSSGP_IE_CELL_ID = 0x08,
BSSGP_IE_CHAN_NEEDED = 0x09,
BSSGP_IE_DRX_PARAMS = 0x0a,
BSSGP_IE_EMLPP_PRIO = 0x0b,
BSSGP_IE_FLUSH_ACTION = 0x0c,
BSSGP_IE_IMSI = 0x0d,
BSSGP_IE_LLC_PDU = 0x0e,
BSSGP_IE_LLC_FRAMES_DISCARDED = 0x0f,
BSSGP_IE_LOCATION_AREA = 0x10,
BSSGP_IE_MOBILE_ID = 0x11,
BSSGP_IE_MS_BUCKET_SIZE = 0x12,
BSSGP_IE_MS_RADIO_ACCESS_CAP = 0x13,
BSSGP_IE_OMC_ID = 0x14,
BSSGP_IE_PDU_IN_ERROR = 0x15,
BSSGP_IE_PDU_LIFETIME = 0x16,
BSSGP_IE_PRIORITY = 0x17,
BSSGP_IE_QOS_PROFILE = 0x18,
BSSGP_IE_RADIO_CAUSE = 0x19,
BSSGP_IE_RA_CAP_UPD_CAUSE = 0x1a,
BSSGP_IE_ROUTEING_AREA = 0x1b,
BSSGP_IE_R_DEFAULT_MS = 0x1c,
BSSGP_IE_SUSPEND_REF_NR = 0x1d,
BSSGP_IE_TAG = 0x1e,
BSSGP_IE_TLLI = 0x1f,
BSSGP_IE_TMSI = 0x20,
BSSGP_IE_TRACE_REFERENC = 0x21,
BSSGP_IE_TRACE_TYPE = 0x22,
BSSGP_IE_TRANSACTION_ID = 0x23,
BSSGP_IE_TRIGGER_ID = 0x24,
BSSGP_IE_NUM_OCT_AFF = 0x25,
BSSGP_IE_LSA_ID_LIST = 0x26,
BSSGP_IE_LSA_INFORMATION = 0x27,
BSSGP_IE_PACKET_FLOW_ID = 0x28,
BSSGP_IE_PACKET_FLOW_TIMER = 0x29,
BSSGP_IE_AGG_BSS_QOS_PROFILE = 0x3a,
BSSGP_IE_FEATURE_BITMAP = 0x3b,
BSSGP_IE_BUCKET_FULL_RATIO = 0x3c,
BSSGP_IE_SERVICE_UTRAN_CCO = 0x3d,
BSSGP_IE_NSEI = 0x3e,
BSSGP_IE_RRLP_APDU = 0x3f,
BSSGP_IE_LCS_QOS = 0x40,
BSSGP_IE_LCS_CLIENT_TYPE = 0x41,
BSSGP_IE_REQUESTED_GPS_AST_DATA = 0x42,
BSSGP_IE_LOCATION_TYPE = 0x43,
BSSGP_IE_LOCATION_ESTIMATE = 0x44,
BSSGP_IE_POSITIONING_DATA = 0x45,
BSSGP_IE_DECIPHERING_KEYS = 0x46,
BSSGP_IE_LCS_PRIORITY = 0x47,
BSSGP_IE_LCS_CAUSE = 0x48,
BSSGP_IE_LCS_CAPABILITY = 0x49,
BSSGP_IE_RRLP_FLAGS = 0x4a,
BSSGP_IE_RIM_APP_IDENTITY = 0x4b,
BSSGP_IE_RIM_SEQ_NR = 0x4c,
BSSGP_IE_RIM_REQ_APP_CONTAINER = 0x4d,
BSSGP_IE_RAN_INFO_APP_CONTAINER = 0x4e,
BSSGP_IE_RIM_PDU_INDICATIONS = 0x4f,
BSSGP_IE_PFC_FLOW_CTRL_PARAMS = 0x52,
BSSGP_IE_GLOBAL_CN_ID = 0x53,
BSSGP_IE_RIM_ROUTING_INFO = 0x54,
BSSGP_IE_RIM_PROTOCOL_VERSION = 0x55,
BSSGP_IE_APP_ERROR_CONTAINER = 0x56,
BSSGP_IE_RI_REQ_RIM_CONTAINER = 0x57,
BSSGP_IE_RI_RIM_CONTAINER = 0x58,
BSSGP_IE_RI_APP_ERROR_RIM_CONT = 0x59,
BSSGP_IE_RI_ACK_RIM_CONTAINER = 0x5a,
BSSGP_IE_RI_ERROR_RIM_COINTAINER= 0x5b,
BSSGP_IE_TMGI = 0x5c,
BSSGP_IE_MBMS_SESSION_ID = 0x5d,
BSSGP_IE_MBMS_SESSION_DURATION = 0x5e,
BSSGP_IE_MBMS_SA_ID_LIST = 0x5f,
BSSGP_IE_MBMS_RESPONSE = 0x60,
BSSGP_IE_MBMS_RA_LIST = 0x61,
BSSGP_IE_MBMS_SESSION_INFO = 0x62,
BSSGP_IE_MBMS_STOP_CAUSE = 0x63,
BSSGP_IE_SBSS_TO_TBSS_TR_CONT = 0x64,
BSSGP_IE_TBSS_TO_SBSS_TR_CONT = 0x65,
BSSGP_IE_NAS_CONT_FOR_PS_HO = 0x66,
BSSGP_IE_PFC_TO_BE_SETUP_LIST = 0x67,
BSSGP_IE_LIST_OF_SETUP_PFC = 0x68,
BSSGP_IE_EXT_FEATURE_BITMAP = 0x69,
BSSGP_IE_SRC_TO_TGT_TR_CONT = 0x6a,
BSSGP_IE_TGT_TO_SRC_TR_CONT = 0x6b,
BSSGP_IE_NC_ID = 0x6c,
BSSGP_IE_PAGE_MODE = 0x6d,
BSSGP_IE_CONTAINER_ID = 0x6e,
BSSGP_IE_GLOBAL_TFI = 0x6f,
BSSGP_IE_IMEI = 0x70,
BSSGP_IE_TIME_TO_MBMS_DATA_XFR = 0x71,
BSSGP_IE_MBMS_SESSION_REP_NR = 0x72,
BSSGP_IE_INTER_RAT_HO_INFO = 0x73,
BSSGP_IE_PS_HO_COMMAND = 0x74,
BSSGP_IE_PS_HO_INDICATIONS = 0x75,
BSSGP_IE_SI_PSI_CONTAINER = 0x76,
BSSGP_IE_ACTIVE_PFC_LIST = 0x77,
BSSGP_IE_VELOCITY_DATA = 0x78,
BSSGP_IE_DTM_HO_COMMAND = 0x79,
BSSGP_IE_CS_INDICATION = 0x7a,
BSSGP_IE_RQD_GANNS_AST_DATA = 0x7b,
BSSGP_IE_GANSS_LOCATION_TYPE = 0x7c,
BSSGP_IE_GANSS_POSITIONING_DATA = 0x7d,
BSSGP_IE_FLOW_CTRL_GRANULARITY = 0x7e,
BSSGP_IE_ENB_ID = 0x7f,
BSSGP_IE_EUTRAN_IRAT_HO_INFO = 0x80,
BSSGP_IE_SUB_PID4RAT_FREQ_PRIO = 0x81,
BSSGP_IE_REQ4IRAT_HO_INFO = 0x82,
BSSGP_IE_RELIABLE_IRAT_HO_INFO = 0x83,
BSSGP_IE_SON_TRANSFER_APP_ID = 0x84,
BSSGP_IE_CSG_ID = 0x85,
BSSGP_IE_TAC = 0x86,
BSSGP_IE_REDIRECT_ATTEMPT_FLAG = 0x87,
BSSGP_IE_REDIRECTION_INDICATION = 0x88,
BSSGP_IE_REDIRECTION_COMPLETED = 0x89,
BSSGP_IE_UNCONF_SEND_STATE_VAR = 0x8a,
BSSGP_IE_IRAT_MEASUREMENT_CONF = 0x8b,
BSSGP_IE_SCI = 0x8c,
BSSGP_IE_GGSN_PGW_LOCATION = 0x8d,
BSSGP_IE_SELECTED_PLMN_ID = 0x8e,
BSSGP_IE_PRIO_CLASS_IND = 0x8f,
BSSGP_IE_SOURCE_CELL_ID = 0x90,
BSSGP_IE_IRAT_MEAS_CFG_E_EARFCN = 0x91,
BSSGP_IE_EDRX_PARAMETERS = 0x92,
BSSGP_IE_T_UNTIL_NEXT_PAGING = 0x93,
BSSGP_IE_COVERAGE_CLASS = 0x98,
BSSGP_IE_PAGING_ATTEMPT_INFO = 0x99,
BSSGP_IE_EXCEPTION_REPORT_FLAG = 0x9a,
BSSGP_IE_OLD_RA_ID = 0x9b,
BSSGP_IE_ATTACH_IND = 0x9c,
BSSGP_IE_PLMN_ID = 0x9d,
BSSGP_IE_MME_QUERY = 0x9e,
BSSGP_IE_SGSN_GROUP_ID = 0x9f,
BSSGP_IE_ADDITIONAL_PTMSI = 0xa0,
BSSGP_IE_UE_USAGE_TYPE = 0xa1,
BSSGP_IE_MLAT_TIMER = 0xa2,
BSSGP_IE_MLAT_TA = 0xa3,
BSSGP_IE_MS_SYNC_ACCURACY = 0xa4,
BSSGP_IE_BTS_RX_ACCURACY_LVL = 0xa5,
BSSGP_IE_TA_REQ = 0xa6,
};
/*! Cause coding (Section 11.3.8 / Table 11.10) */
enum gprs_bssgp_cause {
BSSGP_CAUSE_PROC_OVERLOAD = 0x00,
BSSGP_CAUSE_EQUIP_FAIL = 0x01,
BSSGP_CAUSE_TRASIT_NET_FAIL = 0x02,
BSSGP_CAUSE_CAPA_GREATER_0KPBS = 0x03,
BSSGP_CAUSE_UNKNOWN_MS = 0x04,
BSSGP_CAUSE_UNKNOWN_BVCI = 0x05,
BSSGP_CAUSE_CELL_TRAF_CONG = 0x06,
BSSGP_CAUSE_SGSN_CONG = 0x07,
BSSGP_CAUSE_OML_INTERV = 0x08,
BSSGP_CAUSE_BVCI_BLOCKED = 0x09,
BSSGP_CAUSE_PFC_CREATE_FAIL = 0x0a,
BSSGP_CAUSE_PFC_PREEMPTED = 0x0b,
BSSGP_CAUSE_ABQP_NOT_SUPP = 0x0c,
BSSGP_CAUSE_SEM_INCORR_PDU = 0x20,
BSSGP_CAUSE_INV_MAND_INF = 0x21,
BSSGP_CAUSE_MISSING_MAND_IE = 0x22,
BSSGP_CAUSE_MISSING_COND_IE = 0x23,
BSSGP_CAUSE_UNEXP_COND_IE = 0x24,
BSSGP_CAUSE_COND_IE_ERR = 0x25,
BSSGP_CAUSE_PDU_INCOMP_STATE = 0x26,
BSSGP_CAUSE_PROTO_ERR_UNSPEC = 0x27,
BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28,
BSSGP_CAUSE_REQ_INFO_NOT_AVAIL = 0x29,
BSSGP_CAUSE_UNKN_DST = 0x2a,
BSSGP_CAUSE_UNKN_RIM_AI = 0x2b,
BSSGP_CAUSE_INVAL_CONT_UI = 0x2c,
BSSGP_CAUSE_PFC_QUEUE = 0x2d,
BSSGP_CAUSE_PFC_CREATED = 0x2e,
BSSGP_CAUSE_T12_EXPIRY = 0x2f,
BSSGP_CAUSE_MS_UNDER_PS_HO = 0x30,
BSSGP_CAUSE_UL_QUALITY = 0x31,
BSSGP_CAUSE_UL_STRENGTH = 0x32,
BSSGP_CAUSE_DL_QUALITY = 0x33,
BSSGP_CAUSE_DL_STRENGTH = 0x34,
BSSGP_CAUSE_DISTANCE = 0x35,
BSSGP_CAUSE_BETTER_CELL = 0x36,
BSSGP_CAUSE_TRAFFIC = 0x37,
BSSGP_CAUSE_MS_RADIO_LOSS = 0x38,
BSSGP_CAUSE_MS_BACK_OLD_CHAN = 0x39,
BSSGP_CAUSE_T13_EXPIRY = 0x3a,
BSSGP_CAUSE_T14_EXPIRY = 0x3b,
BSSGP_CAUSE_NOT_ALL_PFC = 0x3c,
BSSGP_CAUSE_CS = 0x3d,
BSSGP_CAUSE_REQ_ALG_NOT_SUPP = 0x3e,
BSSGP_CAUSE_RELOC_FAIL = 0x3f,
BSSGP_CAUSE_DIR_RETRY = 0x40,
BSSGP_CAUSE_TIME_CRIT_RELOC = 0x41,
BSSGP_CAUSE_PS_HO_TARG_NA = 0x42,
BSSGP_CAUSE_PS_HO_TARG_NOT_SUPP = 0x43,
BSSGP_CAUSE_PUESBINE = 0x44,
BSSGP_CAUSE_DTM_HO_NO_CS_RES = 0x45,
BSSGP_CAUSE_DTM_HO_PS_ALLOC_FAIL = 0x46,
BSSGP_CAUSE_DTM_HO_T24_EXPIRY = 0x47,
BSSGP_CAUSE_DTM_HO_INVAL_CS_IND = 0x48,
BSSGP_CAUSE_DTM_HO_T23_EXPIRY = 0x49,
BSSGP_CAUSE_DTM_HO_MSC_ERR = 0x4a,
BSSGP_CAUSE_INVAL_CSG_CELL = 0x4b,
};
/* Feature Bitmap (Section 11.3.45) */
#define BSSGP_FEAT_PFC 0x01 /* Packet Flow Context */
#define BSSGP_FEAT_CBL 0x02 /* Current Bucket Level */
#define BSSGP_FEAT_INR 0x04 /* Inter-NSE re-routing */
#define BSSGP_FEAT_LCS 0x08 /* Location Services */
#define BSSGP_FEAT_RIM 0x10 /* RAN Inoformation Management */
#define BSSGP_FEAT_PFC_FC 0x20 /* PFC Flow Control */
#define BSSGP_FEAT_ERS 0x40 /* Enhanced Radio Status */
#define BSSGP_FEAT_MBMS 0x80 /* Multimedia Broadcast */
/* Extended Feature Bitmap (Section 11.3.84) */
#define BSSGP_XFEAT_PSHO 0x01 /* PS Handover */
#define BSSGP_XFEAT_GBIT 0x02 /* Gigabit Interface */
#define BSSGP_XFEAT_MOCN 0x04 /* Multi-Operator CN */
#define BSSGP_XFEAT_CSPS 0x08 /* CS/PS coordination enhancements */
#define BSSGP_XFEAT_ECIoT 0x10 /* EC-GSM-IoT */
#define BSSGP_XFEAT_DCN 0x20 /* Dedicated CN */
#define BSSGP_XFEAT_eDRX 0x40 /* eDRX */
#define BSSGP_XFEAT_MSAD 0x80 /* MS-assisted Dedicated CN selection */
/* Flow Control Granularity (Section 11.3.102) */
enum bssgp_fc_granularity {
BSSGP_FC_GRAN_100 = 0,
BSSGP_FC_GRAN_1000 = 1,
BSSGP_FC_GRAN_10000 = 2,
BSSGP_FC_GRAN_100000 = 3,
};
/* RAN-INFORMATION-REQUEST PDU Type Extension
* 3GPP TS 48.018, table 11.3.65.1 */
enum bssgp_rim_pdu_type {
RIM_PDU_TYPE_STOP = 0,
RIM_PDU_TYPE_SING_REP = 1,
RIM_PDU_TYPE_MULT_REP = 2,
};
/* RIM PDU Indications
* 3GPP TS 48.018, section 11.3.65.0 */
struct bssgp_rim_pdu_ind {
#if OSMO_IS_LITTLE_ENDIAN
uint8_t ack_requested:1,
pdu_type_ext:3,
reserved:4;
#elif OSMO_IS_BIG_ENDIAN
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
uint8_t reserved:4, pdu_type_ext:3, ack_requested:1;
#endif
} __attribute__ ((packed));
#pragma message "Header osmocom/gprs/protocol/gsm_08_18.h is deprecated, include osmocom/gb/protocol/gsm_08_18.h instead"
#include <osmocom/gb/protocol/gsm_08_18.h>

View File

@ -1,11 +1,4 @@
/*! \file gsm_24_301.h */
#pragma once
/*! Tracking area TS 24.301, section 9.9.3.32 */
struct osmo_eutran_tai {
uint16_t mcc;
uint16_t mnc;
bool mnc_3_digits;
uint16_t tac;
};
#pragma message "Header osmocom/gprs/protocol/gsm_24_301.h is deprecated, include osmocom/gb/protocol/gsm_24_301.h instead"
#include <osmocom/gb/protocol/gsm_24_301.h>

View File

@ -32,10 +32,10 @@
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp2.h>
#include <osmocom/gprs/bssgp_bvc_fsm.h>
#include <osmocom/gb/gprs_msgb.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_bssgp2.h>
#include <osmocom/gb/bssgp_bvc_fsm.h>
#include "common_vty.h"

View File

@ -33,7 +33,7 @@
#include <osmocom/vty/buffer.h>
#include <osmocom/vty/vty.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gb/gprs_msgb.h>
#include "common_vty.h"

View File

@ -29,7 +29,7 @@
#include <unistd.h>
#include <errno.h>
#include <osmocom/gprs/frame_relay.h>
#include <osmocom/gb/frame_relay.h>
#include <osmocom/core/endian.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>

View File

@ -2,7 +2,7 @@
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gb/gprs_ns.h>
/* gprs_ns_sns.c */
int gprs_ns_rx_sns(struct gprs_ns_inst *nsi, struct msgb *msg, struct tlv_parsed *tp);

View File

@ -36,9 +36,9 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_bssgp_bss.h>
#include <osmocom/gb/gprs_ns.h>
#include "osmocom/gsm/gsm48.h"
#include "gprs_bssgp_internal.h"

View File

@ -28,9 +28,9 @@
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp2.h>
#include <osmocom/gb/gprs_ns2.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_bssgp2.h>
/*! transmit BSSGP PDU over NS (PTP BVC)

View File

@ -30,9 +30,9 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_bssgp_bss.h>
#include <osmocom/gb/gprs_ns.h>
#include "gprs_bssgp_internal.h"

View File

@ -1,7 +1,7 @@
#pragma once
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gb/gprs_bssgp.h>
extern bssgp_bvc_send bssgp_ns_send;
extern void *bssgp_ns_send_data;

View File

@ -24,8 +24,8 @@
*/
#include <errno.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_rim.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_bssgp_rim.h>
#include <osmocom/gsm/gsm0808_utils.h>
#include "gprs_bssgp_internal.h"

View File

@ -29,8 +29,8 @@
#include <osmocom/core/byteswap.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_ns.h>
#include "gprs_bssgp_internal.h"

View File

@ -34,9 +34,9 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/gb/gprs_ns.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_bssgp_bss.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/command.h>

View File

@ -82,9 +82,9 @@
#include <osmocom/core/stats.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/signal.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns_frgre.h>
#include <osmocom/gb/gprs_ns.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_ns_frgre.h>
#include "common_vty.h"
#include "gb_internal.h"

View File

@ -80,7 +80,7 @@
#include <osmocom/core/stats.h>
#include <osmocom/core/stat_item.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gb/gprs_msgb.h>
#include <osmocom/gsm/prim.h>
#include <osmocom/gsm/tlv.h>

View File

@ -45,7 +45,7 @@
#include <linux/hdlc/ioctl.h>
#include <linux/sockios.h>
#include <osmocom/gprs/frame_relay.h>
#include <osmocom/gb/frame_relay.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/core/stat_item.h>
#include <osmocom/core/logging.h>
@ -54,10 +54,10 @@
#include <osmocom/core/socket.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gb/gprs_ns2.h>
#include <osmocom/core/netdev.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
#include <osmocom/gb/protocol/gsm_08_16.h>
#include <osmocom/gb/protocol/gsm_08_18.h>
#include "config.h"
#include "common_vty.h"

View File

@ -43,7 +43,7 @@
#include <osmocom/core/select.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gb/gprs_ns2.h>
#include "gprs_ns2_internal.h"

View File

@ -6,8 +6,8 @@
#include <stdint.h>
#include <osmocom/core/logging.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gb/protocol/gsm_08_16.h>
#include <osmocom/gb/gprs_ns2.h>
#define LOGNSE(nse, lvl, fmt, args ...) \
LOGP(DLNS, lvl, "NSE(%05u) " fmt, (nse)->nsei, ## args)

View File

@ -33,9 +33,9 @@
#include <osmocom/core/stat_item.h>
#include <osmocom/core/stats.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>
#include <osmocom/gb/gprs_msgb.h>
#include <osmocom/gb/gprs_ns2.h>
#include <osmocom/gb/protocol/gsm_08_16.h>
#include "gprs_ns2_internal.h"

View File

@ -48,9 +48,9 @@
#include <osmocom/core/socket.h>
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>
#include <osmocom/gb/gprs_msgb.h>
#include <osmocom/gb/gprs_ns2.h>
#include <osmocom/gb/protocol/gsm_08_16.h>
#include "gprs_ns2_internal.h"

View File

@ -31,7 +31,7 @@
#include <osmocom/core/select.h>
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/core/socket.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gb/gprs_ns2.h>
#include "common_vty.h"
#include "gprs_ns2_internal.h"

View File

@ -42,8 +42,8 @@
#include <osmocom/core/stat_item.h>
#include <osmocom/gsm/prim.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>
#include <osmocom/gb/gprs_msgb.h>
#include <osmocom/gb/protocol/gsm_08_16.h>
#include "gprs_ns2_internal.h"

View File

@ -41,8 +41,8 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/core/socket.h>
#include <osmocom/gprs/frame_relay.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gb/frame_relay.h>
#include <osmocom/gb/gprs_ns2.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/vty/command.h>
#include <osmocom/vty/logging.h>

View File

@ -38,7 +38,7 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/socket.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gb/gprs_ns.h>
#include "common_vty.h"

View File

@ -16,8 +16,8 @@
#include <osmocom/core/signal.h>
#include <osmocom/core/socket.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gb/gprs_msgb.h>
#include <osmocom/gb/gprs_ns.h>
#include "common_vty.h"
#include "gb_internal.h"

View File

@ -36,8 +36,8 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gb/gprs_ns.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/core/socket.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/command.h>

View File

@ -17,7 +17,7 @@
#define _GNU_SOURCE
#include <osmocom/core/application.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gb/gprs_ns.h>
#include <sys/types.h>
#include <sys/socket.h>

View File

@ -13,7 +13,7 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gb/gprs_bssgp.h>
static unsigned long in_ctr = 1;
static struct timeval tv_start;

View File

@ -14,9 +14,9 @@
#include <osmocom/core/application.h>
#include <osmocom/core/utils.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp_rim.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_ns.h>
#include <osmocom/gb/gprs_bssgp_rim.h>
#include <stdio.h>
#include <stdlib.h>

View File

@ -17,9 +17,9 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/prim.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/gb/gprs_bssgp.h>
#include <osmocom/gb/gprs_ns.h>
#include <osmocom/gb/gprs_bssgp_bss.h>
#include <stdio.h>
#include <stdlib.h>

View File

@ -27,9 +27,9 @@
#include <osmocom/core/socket.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gb/gprs_msgb.h>
#include <osmocom/gb/gprs_ns2.h>
#include <osmocom/gb/gprs_bssgp.h>
#include "../../src/gb/gprs_ns2_internal.h"

View File

@ -25,9 +25,9 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/signal.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gb/gprs_msgb.h>
#include <osmocom/gb/gprs_ns.h>
#include <osmocom/gb/gprs_bssgp.h>
#define REMOTE_BSS_ADDR 0x01020304
#define REMOTE_SGSN_ADDR 0x05060708

View File

@ -38,7 +38,7 @@
#include <osmocom/core/logging.h>
#include <osmocom/gsm/prim.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gb/gprs_ns2.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/command.h>

View File

@ -10,7 +10,7 @@
#include <osmocom/core/stats.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/control_vty.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gb/gprs_ns2.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/command.h>