libosmo-gprs/include/osmocom/gprs/sm/sm_private.h

192 lines
5.5 KiB
C

#pragma once
/* 3GPP TS 24.007, private header */
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/endian.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gprs/gmm/gmm_prim.h>
#include <osmocom/gprs/sm/sm.h>
#include <osmocom/gprs/sm/sm_prim.h>
#include <osmocom/gprs/sm/sm_ms_fsm.h>
extern int g_sm_log_cat[_OSMO_GPRS_SM_LOGC_MAX];
#define LOGSM(lvl, fmt, args...) LOGP(g_sm_log_cat[OSMO_GPRS_SM_LOGC_SM], lvl, fmt, ## args)
#define msgb_sm_prim(msg) ((struct osmo_gprs_sm_prim *)(msg)->l1h)
/* 10.5.6.4 Packet data protocol address */
enum gprs_sm_pdp_addr_org {
GPRS_SM_PDP_ADDR_ORG_ETSI = 0x00,
GPRS_SM_PDP_ADDR_ORG_IETF = 0x01,
GPRS_SM_PDP_ADDR_ORG_EMPTY = 0x0f,
/* All other values are reserved. */
};
/* 10.5.6.4 Packet data protocol address */
enum gprs_sm_pdp_addr_etsi_type {
GPRS_SM_PDP_ADDR_ETSI_RESERVED = 00, /* used in earlier version of this protocol */
GPRS_SM_PDP_ADDR_ETSI_PPP = 0x01,
GPRS_SM_PDP_ADDR_ETSI_NON_IP = 0x02,
/* All other values are reserved in this version of the protocol. */
};
struct gprs_sm_pdp_addr {
#if OSMO_IS_LITTLE_ENDIAN
uint8_t organization:4, /* enum gprs_sm_pdp_addr_org */
spare:4;
#elif OSMO_IS_BIG_ENDIAN
/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
uint8_t spare:4, organization:4;
#endif
uint8_t type; /* osmo_gprs_sm_pdp_addr_{etsi,ietf}_type */
union {
/* IPv4 */
uint32_t addr;
/* IPv6 */
uint8_t addr6[16];
/* IPv4v6 */
struct {
uint32_t addr;
uint8_t addr6[16];
} __attribute__ ((packed)) both;
};
} __attribute__ ((packed));
struct gprs_sm_ms;
struct gprs_sm_ctx {
enum osmo_gprs_sm_location location;
osmo_gprs_sm_prim_up_cb sm_up_cb;
void *sm_up_cb_user_data;
osmo_gprs_sm_prim_sndcp_up_cb sm_sndcp_up_cb;
void *sm_sndcp_up_cb_user_data;
osmo_gprs_sm_prim_down_cb sm_down_cb;
void *sm_down_cb_user_data;
osmo_gprs_sm_prim_gmm_down_cb sm_gmm_down_cb;
void *sm_gmm_down_cb_user_data;
struct osmo_tdef *T_defs; /* timers controlled by SM layer */
struct llist_head ms_list; /* list of struct gprs_sm_ms->list */
uint32_t next_sess_id;
};
extern struct gprs_sm_ctx *g_sm_ctx;
/* SM Entity, PDP CTX */
struct gprs_sm_entity {
struct gprs_sm_ms *ms; /* backpointer */
uint32_t sess_id;
uint8_t nsapi;
enum osmo_gprs_sm_llc_sapi llc_sapi;
enum osmo_gprs_sm_pdp_addr_ietf_type pdp_addr_ietf_type;
struct osmo_sockaddr pdp_addr_v4;
struct osmo_sockaddr pdp_addr_v6;
uint8_t radio_prio; /* TS 24.008 10.5.7.2 */
uint8_t qos[OSMO_GPRS_SM_QOS_MAXLEN];
uint8_t qos_len;
char apn[OSMO_GPRS_SM_APN_MAXLEN];
uint8_t pco[OSMO_GPRS_SM_MBIFORM_MAXLEN];
uint8_t pco_len;
uint8_t ti; /* transaction identifier */
struct gprs_sm_ms_fsm_ctx ms_fsm;
};
/* Mobile Station: */
struct gprs_sm_ms {
struct llist_head list; /* item in (struct gprs_sm_ctx)->ms_list */
uint32_t ms_id;
struct gprs_sm_entity *pdp[OSMO_GPRS_SM_PDP_MAXNSAPI];
struct {
uint32_t ptmsi;
uint32_t ptmsi_sig;
uint32_t tlli;
char imsi[OSMO_IMSI_BUF_SIZE];
char imei[GSM23003_IMEI_NUM_DIGITS + 1];
char imeisv[GSM23003_IMEISV_NUM_DIGITS+1];
struct gprs_ra_id ra; /* TS 24.008 10.5.5.15 (decoded) */
} gmm;
};
/* 10.5.6.2 Network service access point identifier */
static inline bool gprs_sm_nsapi_is_valid(uint8_t nsapi)
{
return nsapi >= 5 && nsapi <= 15;
}
static inline struct gprs_sm_entity *gprs_sm_ms_get_pdp_ctx(struct gprs_sm_ms *ms,
uint8_t nsapi) {
OSMO_ASSERT(gprs_sm_nsapi_is_valid(nsapi));
return ms->pdp[nsapi];
}
/* sm_prim.c: */
int gprs_sm_prim_call_up_cb(struct osmo_gprs_sm_prim *sm_prim);
int gprs_sm_prim_call_down_cb(struct osmo_gprs_sm_prim *sm_prim);
int gprs_sm_prim_call_gmm_down_cb(struct osmo_gprs_gmm_prim *gmm_prim);
int gprs_sm_prim_call_sndcp_up_cb(struct osmo_gprs_sndcp_prim *sndcp_prim);
struct osmo_gprs_sm_prim *gprs_sm_prim_alloc_smreg_pdp_act_cnf(void);
struct osmo_gprs_sm_prim *gprs_sm_prim_alloc_smreg_pdp_act_ind(void);
struct osmo_gprs_sm_prim *gprs_sm_prim_alloc_smreg_pdp_deact_ind(void);
/* sm.c: */
struct gprs_sm_ms *gprs_sm_ms_alloc(uint32_t ms_id);
void gprs_sm_ms_free(struct gprs_sm_ms *ms);
struct gprs_sm_ms *gprs_sm_find_ms_by_id(uint32_t ms_id);
struct gprs_sm_ms *gprs_sm_find_ms_by_tlli(uint32_t tlli);
struct gprs_sm_entity *gprs_sm_entity_alloc(struct gprs_sm_ms *ms, uint32_t nsapi);
void gprs_sm_entity_free(struct gprs_sm_entity *sme);
struct gprs_sm_entity *gprs_sm_find_sme_by_sess_id(uint32_t sess_id);
void gprs_sm_handle_ie_pdp_ctx_status(struct gprs_sm_ms *ms, const uint8_t *pdp_status);
int gprs_sm_submit_gmmsm_assign_req(const struct gprs_sm_entity *sme);
int gprs_sm_submit_smreg_pdp_act_cnf(const struct gprs_sm_entity *sme, enum gsm48_gsm_cause cause);
int gprs_sm_submit_smreg_pdp_deact_ind(const struct gprs_sm_entity *sme, enum gsm48_gsm_cause cause);
int gprs_sm_submit_snsm_act_ind(const struct gprs_sm_entity *sme);
int gprs_sm_submit_snsm_deact_ind(const struct gprs_sm_entity *sme);
int gprs_sm_tx_act_pdp_ctx_req(struct gprs_sm_entity *sme);
int gprs_sm_rx(struct gprs_sm_entity *sme, struct gsm48_hdr *gh, unsigned int len);
#define LOGMS(ms, level, fmt, args...) \
LOGSM(level, "MS(ID-%u) " fmt, \
ms->ms_id, \
## args)
#define LOGSME(sme, level, fmt, args...) \
LOGSM(level, "PDP(ID-%u:NSAPI-%u) " fmt, \
sme->ms->ms_id, \
sme->nsapi, \
## args)