Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 1 | #ifndef _GPRS_BSSGP_H |
| 2 | #define _GPRS_BSSGP_H |
| 3 | |
Harald Welte | d85d9a9 | 2010-05-02 11:26:34 +0200 | [diff] [blame] | 4 | #include <stdint.h> |
| 5 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 6 | /*! \brief Fixed BVCI definitions (Section 5.4.1) */ |
Harald Welte | 9c97580 | 2010-05-18 11:57:08 +0200 | [diff] [blame] | 7 | #define BVCI_SIGNALLING 0x0000 |
| 8 | #define BVCI_PTM 0x0001 |
| 9 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 10 | /*! \brief BSSGP PDU types (Section 11.3.26 / Table 11.27) */ |
Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 11 | enum bssgp_pdu_type { |
| 12 | /* PDUs between RL and BSSGP SAPs */ |
| 13 | BSSGP_PDUT_DL_UNITDATA = 0x00, |
| 14 | BSSGP_PDUT_UL_UNITDATA = 0x01, |
| 15 | BSSGP_PDUT_RA_CAPABILITY = 0x02, |
| 16 | BSSGP_PDUT_PTM_UNITDATA = 0x03, |
| 17 | /* PDUs between GMM SAPs */ |
| 18 | BSSGP_PDUT_PAGING_PS = 0x06, |
| 19 | BSSGP_PDUT_PAGING_CS = 0x07, |
| 20 | BSSGP_PDUT_RA_CAPA_UDPATE = 0x08, |
| 21 | BSSGP_PDUT_RA_CAPA_UPDATE_ACK = 0x09, |
| 22 | BSSGP_PDUT_RADIO_STATUS = 0x0a, |
| 23 | BSSGP_PDUT_SUSPEND = 0x0b, |
| 24 | BSSGP_PDUT_SUSPEND_ACK = 0x0c, |
| 25 | BSSGP_PDUT_SUSPEND_NACK = 0x0d, |
| 26 | BSSGP_PDUT_RESUME = 0x0e, |
| 27 | BSSGP_PDUT_RESUME_ACK = 0x0f, |
| 28 | BSSGP_PDUT_RESUME_NACK = 0x10, |
| 29 | /* PDus between NM SAPs */ |
| 30 | BSSGP_PDUT_BVC_BLOCK = 0x20, |
| 31 | BSSGP_PDUT_BVC_BLOCK_ACK = 0x21, |
| 32 | BSSGP_PDUT_BVC_RESET = 0x22, |
| 33 | BSSGP_PDUT_BVC_RESET_ACK = 0x23, |
| 34 | BSSGP_PDUT_BVC_UNBLOCK = 0x24, |
| 35 | BSSGP_PDUT_BVC_UNBLOCK_ACK = 0x25, |
| 36 | BSSGP_PDUT_FLOW_CONTROL_BVC = 0x26, |
| 37 | BSSGP_PDUT_FLOW_CONTROL_BVC_ACK = 0x27, |
| 38 | BSSGP_PDUT_FLOW_CONTROL_MS = 0x28, |
| 39 | BSSGP_PDUT_FLOW_CONTROL_MS_ACK = 0x29, |
| 40 | BSSGP_PDUT_FLUSH_LL = 0x2a, |
| 41 | BSSGP_PDUT_FLUSH_LL_ACK = 0x2b, |
| 42 | BSSGP_PDUT_LLC_DISCARD = 0x2c, |
| 43 | BSSGP_PDUT_SGSN_INVOKE_TRACE = 0x40, |
| 44 | BSSGP_PDUT_STATUS = 0x41, |
| 45 | /* PDUs between PFM SAP's */ |
| 46 | BSSGP_PDUT_DOWNLOAD_BSS_PFC = 0x50, |
| 47 | BSSGP_PDUT_CREATE_BSS_PFC = 0x51, |
| 48 | BSSGP_PDUT_CREATE_BSS_PFC_ACK = 0x52, |
| 49 | BSSGP_PDUT_CREATE_BSS_PFC_NACK = 0x53, |
| 50 | BSSGP_PDUT_MODIFY_BSS_PFC = 0x54, |
| 51 | BSSGP_PDUT_MODIFY_BSS_PFC_ACK = 0x55, |
| 52 | BSSGP_PDUT_DELETE_BSS_PFC = 0x56, |
| 53 | BSSGP_PDUT_DELETE_BSS_PFC_ACK = 0x57, |
| 54 | }; |
| 55 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 56 | /*! \brief BSSGP User-Data header (Section 10.2.1 and 10.2.2) */ |
Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 57 | struct bssgp_ud_hdr { |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 58 | uint8_t pdu_type; /*!< BSSGP PDU type */ |
| 59 | uint32_t tlli; /*!< Temporary Link-Local Identifier */ |
| 60 | uint8_t qos_profile[3]; /*!< QoS profile */ |
| 61 | uint8_t data[0]; /* optional/conditional IEs as TLVs */ |
Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 62 | } __attribute__((packed)); |
| 63 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 64 | /*! \brief BSSGP normal header */ |
Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 65 | struct bssgp_normal_hdr { |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 66 | uint8_t pdu_type; /*!< BSSGP PDU type */ |
| 67 | uint8_t data[0]; /*!< optional/conditional IEs as TLVs */ |
Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 68 | }; |
| 69 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 70 | /*! \brief BSSGP Information Element Identifiers */ |
Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 71 | enum bssgp_iei_type { |
| 72 | BSSGP_IE_ALIGNMENT = 0x00, |
| 73 | BSSGP_IE_BMAX_DEFAULT_MS = 0x01, |
| 74 | BSSGP_IE_BSS_AREA_ID = 0x02, |
| 75 | BSSGP_IE_BUCKET_LEAK_RATE = 0x03, |
| 76 | BSSGP_IE_BVCI = 0x04, |
| 77 | BSSGP_IE_BVC_BUCKET_SIZE = 0x05, |
| 78 | BSSGP_IE_BVC_MEASUREMENT = 0x06, |
| 79 | BSSGP_IE_CAUSE = 0x07, |
| 80 | BSSGP_IE_CELL_ID = 0x08, |
| 81 | BSSGP_IE_CHAN_NEEDED = 0x09, |
| 82 | BSSGP_IE_DRX_PARAMS = 0x0a, |
| 83 | BSSGP_IE_EMLPP_PRIO = 0x0b, |
| 84 | BSSGP_IE_FLUSH_ACTION = 0x0c, |
| 85 | BSSGP_IE_IMSI = 0x0d, |
| 86 | BSSGP_IE_LLC_PDU = 0x0e, |
| 87 | BSSGP_IE_LLC_FRAMES_DISCARDED = 0x0f, |
| 88 | BSSGP_IE_LOCATION_AREA = 0x10, |
| 89 | BSSGP_IE_MOBILE_ID = 0x11, |
| 90 | BSSGP_IE_MS_BUCKET_SIZE = 0x12, |
| 91 | BSSGP_IE_MS_RADIO_ACCESS_CAP = 0x13, |
| 92 | BSSGP_IE_OMC_ID = 0x14, |
| 93 | BSSGP_IE_PDU_IN_ERROR = 0x15, |
| 94 | BSSGP_IE_PDU_LIFETIME = 0x16, |
| 95 | BSSGP_IE_PRIORITY = 0x17, |
| 96 | BSSGP_IE_QOS_PROFILE = 0x18, |
| 97 | BSSGP_IE_RADIO_CAUSE = 0x19, |
| 98 | BSSGP_IE_RA_CAP_UPD_CAUSE = 0x1a, |
| 99 | BSSGP_IE_ROUTEING_AREA = 0x1b, |
| 100 | BSSGP_IE_R_DEFAULT_MS = 0x1c, |
| 101 | BSSGP_IE_SUSPEND_REF_NR = 0x1d, |
| 102 | BSSGP_IE_TAG = 0x1e, |
| 103 | BSSGP_IE_TLLI = 0x1f, |
| 104 | BSSGP_IE_TMSI = 0x20, |
| 105 | BSSGP_IE_TRACE_REFERENC = 0x21, |
| 106 | BSSGP_IE_TRACE_TYPE = 0x22, |
| 107 | BSSGP_IE_TRANSACTION_ID = 0x23, |
| 108 | BSSGP_IE_TRIGGER_ID = 0x24, |
| 109 | BSSGP_IE_NUM_OCT_AFF = 0x25, |
| 110 | BSSGP_IE_LSA_ID_LIST = 0x26, |
| 111 | BSSGP_IE_LSA_INFORMATION = 0x27, |
| 112 | BSSGP_IE_PACKET_FLOW_ID = 0x28, |
| 113 | BSSGP_IE_PACKET_FLOW_TIMER = 0x29, |
| 114 | BSSGP_IE_AGG_BSS_QOS_PROFILE = 0x3a, |
| 115 | BSSGP_IE_FEATURE_BITMAP = 0x3b, |
| 116 | BSSGP_IE_BUCKET_FULL_RATIO = 0x3c, |
| 117 | BSSGP_IE_SERVICE_UTRAN_CCO = 0x3d, |
| 118 | }; |
| 119 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 120 | /*! \brief Cause coding (Section 11.3.8 / Table 11.10) */ |
Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 121 | enum gprs_bssgp_cause { |
| 122 | BSSGP_CAUSE_PROC_OVERLOAD = 0x00, |
| 123 | BSSGP_CAUSE_EQUIP_FAIL = 0x01, |
| 124 | BSSGP_CAUSE_TRASIT_NET_FAIL = 0x02, |
| 125 | BSSGP_CAUSE_CAPA_GREATER_0KPBS = 0x03, |
| 126 | BSSGP_CAUSE_UNKNOWN_MS = 0x04, |
| 127 | BSSGP_CAUSE_UNKNOWN_BVCI = 0x05, |
| 128 | BSSGP_CAUSE_CELL_TRAF_CONG = 0x06, |
| 129 | BSSGP_CAUSE_SGSN_CONG = 0x07, |
| 130 | BSSGP_CAUSE_OML_INTERV = 0x08, |
| 131 | BSSGP_CAUSE_BVCI_BLOCKED = 0x09, |
| 132 | BSSGP_CAUSE_PFC_CREATE_FAIL = 0x0a, |
| 133 | BSSGP_CAUSE_SEM_INCORR_PDU = 0x20, |
| 134 | BSSGP_CAUSE_INV_MAND_INF = 0x21, |
| 135 | BSSGP_CAUSE_MISSING_MAND_IE = 0x22, |
| 136 | BSSGP_CAUSE_MISSING_COND_IE = 0x23, |
| 137 | BSSGP_CAUSE_UNEXP_COND_IE = 0x24, |
| 138 | BSSGP_CAUSE_COND_IE_ERR = 0x25, |
| 139 | BSSGP_CAUSE_PDU_INCOMP_STATE = 0x26, |
| 140 | BSSGP_CAUSE_PROTO_ERR_UNSPEC = 0x27, |
| 141 | BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28, |
| 142 | }; |
| 143 | |
Harald Welte | d1991e7 | 2010-04-30 20:26:32 +0200 | [diff] [blame] | 144 | /* Our implementation */ |
| 145 | |
Harald Welte | cfb6b28 | 2012-06-16 14:59:56 +0800 | [diff] [blame] | 146 | #include <osmocom/gsm/gsm48.h> |
| 147 | |
Harald Welte | 874acec | 2010-05-11 10:01:17 +0200 | [diff] [blame] | 148 | /* gprs_bssgp_util.c */ |
| 149 | extern struct gprs_ns_inst *bssgp_nsi; |
| 150 | struct msgb *bssgp_msgb_alloc(void); |
| 151 | const char *bssgp_cause_str(enum gprs_bssgp_cause cause); |
| 152 | /* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */ |
| 153 | int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei, |
| 154 | uint16_t bvci, uint16_t ns_bvci); |
| 155 | /* Chapter 10.4.14: Status */ |
| 156 | int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg); |
| 157 | |
| 158 | /* gprs_bssgp.c */ |
| 159 | |
Harald Welte | bcc0369 | 2010-05-17 23:02:42 +0200 | [diff] [blame] | 160 | #define BVC_S_BLOCKED 0x0001 |
| 161 | |
| 162 | /* The per-BTS context that we keep on the SGSN side of the BSSGP link */ |
| 163 | struct bssgp_bvc_ctx { |
| 164 | struct llist_head list; |
| 165 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 166 | struct gprs_ra_id ra_id; /*!< parsed RA ID of the remote BTS */ |
| 167 | uint16_t cell_id; /*!< Cell ID of the remote BTS */ |
Harald Welte | bcc0369 | 2010-05-17 23:02:42 +0200 | [diff] [blame] | 168 | |
| 169 | /* NSEI and BVCI of underlying Gb link. Together they |
| 170 | * uniquely identify a link to a BTS (5.4.4) */ |
| 171 | uint16_t bvci; |
| 172 | uint16_t nsei; |
| 173 | |
| 174 | uint32_t state; |
| 175 | |
| 176 | struct rate_ctr_group *ctrg; |
| 177 | |
| 178 | /* we might want to add this as a shortcut later, avoiding the NSVC |
| 179 | * lookup for every packet, similar to a routing cache */ |
| 180 | //struct gprs_nsvc *nsvc; |
| 181 | }; |
| 182 | extern struct llist_head bssgp_bvc_ctxts; |
| 183 | /* Find a BTS Context based on parsed RA ID and Cell ID */ |
| 184 | struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t cid); |
| 185 | /* Find a BTS context based on BVCI+NSEI tuple */ |
| 186 | struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei); |
| 187 | |
Harald Welte | 73b3cac | 2011-11-25 08:58:40 +0100 | [diff] [blame] | 188 | #define BVC_F_BLOCKED 0x0001 |
| 189 | |
| 190 | enum bssgp_ctr { |
| 191 | BSSGP_CTR_PKTS_IN, |
| 192 | BSSGP_CTR_PKTS_OUT, |
| 193 | BSSGP_CTR_BYTES_IN, |
| 194 | BSSGP_CTR_BYTES_OUT, |
| 195 | BSSGP_CTR_BLOCKED, |
| 196 | BSSGP_CTR_DISCARDED, |
| 197 | }; |
| 198 | |
| 199 | |
Pablo Neira Ayuso | dd5fff4 | 2011-03-22 16:47:59 +0100 | [diff] [blame] | 200 | #include <osmocom/gsm/tlv.h> |
Harald Welte | 14f112a | 2012-06-16 16:09:52 +0800 | [diff] [blame] | 201 | #include <osmocom/gprs/gprs_msgb.h> |
Harald Welte | d1991e7 | 2010-04-30 20:26:32 +0200 | [diff] [blame] | 202 | |
Harald Welte | 6323583 | 2010-05-13 19:25:59 +0200 | [diff] [blame] | 203 | /* BSSGP-UL-UNITDATA.ind */ |
| 204 | int gprs_bssgp_rcvmsg(struct msgb *msg); |
| 205 | |
| 206 | /* BSSGP-DL-UNITDATA.req */ |
Harald Welte | cca80c9 | 2010-05-31 22:12:30 +0200 | [diff] [blame] | 207 | struct sgsn_mm_ctx; |
| 208 | int gprs_bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx); |
Harald Welte | 6323583 | 2010-05-13 19:25:59 +0200 | [diff] [blame] | 209 | |
Harald Welte | 2351f1f | 2010-05-02 11:54:55 +0200 | [diff] [blame] | 210 | uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf); |
Harald Welte | 73b3cac | 2011-11-25 08:58:40 +0100 | [diff] [blame] | 211 | int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid, |
| 212 | uint16_t cid); |
Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 213 | |
Harald Welte | d1991e7 | 2010-04-30 20:26:32 +0200 | [diff] [blame] | 214 | /* Wrapper around TLV parser to parse BSSGP IEs */ |
Harald Welte | d85d9a9 | 2010-05-02 11:26:34 +0200 | [diff] [blame] | 215 | static inline int bssgp_tlv_parse(struct tlv_parsed *tp, uint8_t *buf, int len) |
Harald Welte | d1991e7 | 2010-04-30 20:26:32 +0200 | [diff] [blame] | 216 | { |
| 217 | return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0); |
| 218 | } |
| 219 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 220 | /*! \brief BSSGP Paging mode */ |
Harald Welte | 92f27a9 | 2010-06-09 16:22:28 +0200 | [diff] [blame] | 221 | enum bssgp_paging_mode { |
| 222 | BSSGP_PAGING_PS, |
| 223 | BSSGP_PAGING_CS, |
| 224 | }; |
| 225 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 226 | /*! \brief BSSGP Paging scope */ |
Harald Welte | 92f27a9 | 2010-06-09 16:22:28 +0200 | [diff] [blame] | 227 | enum bssgp_paging_scope { |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 228 | BSSGP_PAGING_BSS_AREA, /*!< all cells in BSS */ |
| 229 | BSSGP_PAGING_LOCATION_AREA, /*!< all cells in LA */ |
| 230 | BSSGP_PAGING_ROUTEING_AREA, /*!< all cells in RA */ |
| 231 | BSSGP_PAGING_BVCI, /*!< one cell */ |
Harald Welte | 92f27a9 | 2010-06-09 16:22:28 +0200 | [diff] [blame] | 232 | }; |
| 233 | |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 234 | /*! \brief BSSGP paging information */ |
Harald Welte | 92f27a9 | 2010-06-09 16:22:28 +0200 | [diff] [blame] | 235 | struct bssgp_paging_info { |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 236 | enum bssgp_paging_mode mode; /*!< CS or PS paging */ |
| 237 | enum bssgp_paging_scope scope; /*!< bssgp_paging_scope */ |
| 238 | struct gprs_ra_id raid; /*!< RA Identifier */ |
| 239 | uint16_t bvci; /*!< BVCI */ |
Harald Welte | 73b3cac | 2011-11-25 08:58:40 +0100 | [diff] [blame] | 240 | char *imsi; /*!< IMSI, if any */ |
Harald Welte | 3177ebe | 2011-11-25 08:15:42 +0100 | [diff] [blame] | 241 | uint32_t *ptmsi; /*!< P-TMSI, if any */ |
| 242 | uint16_t drx_params; /*!< DRX parameters */ |
| 243 | uint8_t qos[3]; /*!< QoS parameters */ |
Harald Welte | 92f27a9 | 2010-06-09 16:22:28 +0200 | [diff] [blame] | 244 | }; |
| 245 | |
| 246 | /* Send a single GMM-PAGING.req to a given NSEI/NS-BVCI */ |
| 247 | int gprs_bssgp_tx_paging(uint16_t nsei, uint16_t ns_bvci, |
| 248 | struct bssgp_paging_info *pinfo); |
| 249 | |
Harald Welte | e9a6df6 | 2010-05-18 08:02:36 +0200 | [diff] [blame] | 250 | /* gprs_bssgp_vty.c */ |
| 251 | int gprs_bssgp_vty_init(void); |
Harald Welte | deb9017 | 2012-06-16 17:45:59 +0800 | [diff] [blame] | 252 | void gprs_bssgp_set_log_ss(int ss); |
Harald Welte | e9a6df6 | 2010-05-18 08:02:36 +0200 | [diff] [blame] | 253 | |
Harald Welte | 75bb820 | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 254 | #endif /* _GPRS_BSSGP_H */ |