Harald Welte | 9b455bf | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 1 | #ifndef _GPRS_BSSGP_H |
| 2 | #define _GPRS_BSSGP_H |
| 3 | |
Harald Welte | eaa614c | 2010-05-02 11:26:34 +0200 | [diff] [blame] | 4 | #include <stdint.h> |
| 5 | |
Harald Welte | 9b455bf | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 6 | /* Section 11.3.26 / Table 11.27 */ |
| 7 | enum bssgp_pdu_type { |
| 8 | /* PDUs between RL and BSSGP SAPs */ |
| 9 | BSSGP_PDUT_DL_UNITDATA = 0x00, |
| 10 | BSSGP_PDUT_UL_UNITDATA = 0x01, |
| 11 | BSSGP_PDUT_RA_CAPABILITY = 0x02, |
| 12 | BSSGP_PDUT_PTM_UNITDATA = 0x03, |
| 13 | /* PDUs between GMM SAPs */ |
| 14 | BSSGP_PDUT_PAGING_PS = 0x06, |
| 15 | BSSGP_PDUT_PAGING_CS = 0x07, |
| 16 | BSSGP_PDUT_RA_CAPA_UDPATE = 0x08, |
| 17 | BSSGP_PDUT_RA_CAPA_UPDATE_ACK = 0x09, |
| 18 | BSSGP_PDUT_RADIO_STATUS = 0x0a, |
| 19 | BSSGP_PDUT_SUSPEND = 0x0b, |
| 20 | BSSGP_PDUT_SUSPEND_ACK = 0x0c, |
| 21 | BSSGP_PDUT_SUSPEND_NACK = 0x0d, |
| 22 | BSSGP_PDUT_RESUME = 0x0e, |
| 23 | BSSGP_PDUT_RESUME_ACK = 0x0f, |
| 24 | BSSGP_PDUT_RESUME_NACK = 0x10, |
| 25 | /* PDus between NM SAPs */ |
| 26 | BSSGP_PDUT_BVC_BLOCK = 0x20, |
| 27 | BSSGP_PDUT_BVC_BLOCK_ACK = 0x21, |
| 28 | BSSGP_PDUT_BVC_RESET = 0x22, |
| 29 | BSSGP_PDUT_BVC_RESET_ACK = 0x23, |
| 30 | BSSGP_PDUT_BVC_UNBLOCK = 0x24, |
| 31 | BSSGP_PDUT_BVC_UNBLOCK_ACK = 0x25, |
| 32 | BSSGP_PDUT_FLOW_CONTROL_BVC = 0x26, |
| 33 | BSSGP_PDUT_FLOW_CONTROL_BVC_ACK = 0x27, |
| 34 | BSSGP_PDUT_FLOW_CONTROL_MS = 0x28, |
| 35 | BSSGP_PDUT_FLOW_CONTROL_MS_ACK = 0x29, |
| 36 | BSSGP_PDUT_FLUSH_LL = 0x2a, |
| 37 | BSSGP_PDUT_FLUSH_LL_ACK = 0x2b, |
| 38 | BSSGP_PDUT_LLC_DISCARD = 0x2c, |
| 39 | BSSGP_PDUT_SGSN_INVOKE_TRACE = 0x40, |
| 40 | BSSGP_PDUT_STATUS = 0x41, |
| 41 | /* PDUs between PFM SAP's */ |
| 42 | BSSGP_PDUT_DOWNLOAD_BSS_PFC = 0x50, |
| 43 | BSSGP_PDUT_CREATE_BSS_PFC = 0x51, |
| 44 | BSSGP_PDUT_CREATE_BSS_PFC_ACK = 0x52, |
| 45 | BSSGP_PDUT_CREATE_BSS_PFC_NACK = 0x53, |
| 46 | BSSGP_PDUT_MODIFY_BSS_PFC = 0x54, |
| 47 | BSSGP_PDUT_MODIFY_BSS_PFC_ACK = 0x55, |
| 48 | BSSGP_PDUT_DELETE_BSS_PFC = 0x56, |
| 49 | BSSGP_PDUT_DELETE_BSS_PFC_ACK = 0x57, |
| 50 | }; |
| 51 | |
| 52 | /* Section 10.2.1 and 10.2.2 */ |
| 53 | struct bssgp_ud_hdr { |
Harald Welte | eaa614c | 2010-05-02 11:26:34 +0200 | [diff] [blame] | 54 | uint8_t pdu_type; |
| 55 | uint32_t tlli; |
| 56 | uint8_t qos_profile[3]; |
| 57 | uint8_t data[0]; /* TLV's */ |
Harald Welte | 9b455bf | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 58 | } __attribute__((packed)); |
| 59 | |
| 60 | struct bssgp_normal_hdr { |
Harald Welte | eaa614c | 2010-05-02 11:26:34 +0200 | [diff] [blame] | 61 | uint8_t pdu_type; |
| 62 | uint8_t data[0]; /* TLV's */ |
Harald Welte | 9b455bf | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 63 | }; |
| 64 | |
| 65 | enum bssgp_iei_type { |
| 66 | BSSGP_IE_ALIGNMENT = 0x00, |
| 67 | BSSGP_IE_BMAX_DEFAULT_MS = 0x01, |
| 68 | BSSGP_IE_BSS_AREA_ID = 0x02, |
| 69 | BSSGP_IE_BUCKET_LEAK_RATE = 0x03, |
| 70 | BSSGP_IE_BVCI = 0x04, |
| 71 | BSSGP_IE_BVC_BUCKET_SIZE = 0x05, |
| 72 | BSSGP_IE_BVC_MEASUREMENT = 0x06, |
| 73 | BSSGP_IE_CAUSE = 0x07, |
| 74 | BSSGP_IE_CELL_ID = 0x08, |
| 75 | BSSGP_IE_CHAN_NEEDED = 0x09, |
| 76 | BSSGP_IE_DRX_PARAMS = 0x0a, |
| 77 | BSSGP_IE_EMLPP_PRIO = 0x0b, |
| 78 | BSSGP_IE_FLUSH_ACTION = 0x0c, |
| 79 | BSSGP_IE_IMSI = 0x0d, |
| 80 | BSSGP_IE_LLC_PDU = 0x0e, |
| 81 | BSSGP_IE_LLC_FRAMES_DISCARDED = 0x0f, |
| 82 | BSSGP_IE_LOCATION_AREA = 0x10, |
| 83 | BSSGP_IE_MOBILE_ID = 0x11, |
| 84 | BSSGP_IE_MS_BUCKET_SIZE = 0x12, |
| 85 | BSSGP_IE_MS_RADIO_ACCESS_CAP = 0x13, |
| 86 | BSSGP_IE_OMC_ID = 0x14, |
| 87 | BSSGP_IE_PDU_IN_ERROR = 0x15, |
| 88 | BSSGP_IE_PDU_LIFETIME = 0x16, |
| 89 | BSSGP_IE_PRIORITY = 0x17, |
| 90 | BSSGP_IE_QOS_PROFILE = 0x18, |
| 91 | BSSGP_IE_RADIO_CAUSE = 0x19, |
| 92 | BSSGP_IE_RA_CAP_UPD_CAUSE = 0x1a, |
| 93 | BSSGP_IE_ROUTEING_AREA = 0x1b, |
| 94 | BSSGP_IE_R_DEFAULT_MS = 0x1c, |
| 95 | BSSGP_IE_SUSPEND_REF_NR = 0x1d, |
| 96 | BSSGP_IE_TAG = 0x1e, |
| 97 | BSSGP_IE_TLLI = 0x1f, |
| 98 | BSSGP_IE_TMSI = 0x20, |
| 99 | BSSGP_IE_TRACE_REFERENC = 0x21, |
| 100 | BSSGP_IE_TRACE_TYPE = 0x22, |
| 101 | BSSGP_IE_TRANSACTION_ID = 0x23, |
| 102 | BSSGP_IE_TRIGGER_ID = 0x24, |
| 103 | BSSGP_IE_NUM_OCT_AFF = 0x25, |
| 104 | BSSGP_IE_LSA_ID_LIST = 0x26, |
| 105 | BSSGP_IE_LSA_INFORMATION = 0x27, |
| 106 | BSSGP_IE_PACKET_FLOW_ID = 0x28, |
| 107 | BSSGP_IE_PACKET_FLOW_TIMER = 0x29, |
| 108 | BSSGP_IE_AGG_BSS_QOS_PROFILE = 0x3a, |
| 109 | BSSGP_IE_FEATURE_BITMAP = 0x3b, |
| 110 | BSSGP_IE_BUCKET_FULL_RATIO = 0x3c, |
| 111 | BSSGP_IE_SERVICE_UTRAN_CCO = 0x3d, |
| 112 | }; |
| 113 | |
| 114 | /* Section 11.3.8 / Table 11.10: Cause coding */ |
| 115 | enum gprs_bssgp_cause { |
| 116 | BSSGP_CAUSE_PROC_OVERLOAD = 0x00, |
| 117 | BSSGP_CAUSE_EQUIP_FAIL = 0x01, |
| 118 | BSSGP_CAUSE_TRASIT_NET_FAIL = 0x02, |
| 119 | BSSGP_CAUSE_CAPA_GREATER_0KPBS = 0x03, |
| 120 | BSSGP_CAUSE_UNKNOWN_MS = 0x04, |
| 121 | BSSGP_CAUSE_UNKNOWN_BVCI = 0x05, |
| 122 | BSSGP_CAUSE_CELL_TRAF_CONG = 0x06, |
| 123 | BSSGP_CAUSE_SGSN_CONG = 0x07, |
| 124 | BSSGP_CAUSE_OML_INTERV = 0x08, |
| 125 | BSSGP_CAUSE_BVCI_BLOCKED = 0x09, |
| 126 | BSSGP_CAUSE_PFC_CREATE_FAIL = 0x0a, |
| 127 | BSSGP_CAUSE_SEM_INCORR_PDU = 0x20, |
| 128 | BSSGP_CAUSE_INV_MAND_INF = 0x21, |
| 129 | BSSGP_CAUSE_MISSING_MAND_IE = 0x22, |
| 130 | BSSGP_CAUSE_MISSING_COND_IE = 0x23, |
| 131 | BSSGP_CAUSE_UNEXP_COND_IE = 0x24, |
| 132 | BSSGP_CAUSE_COND_IE_ERR = 0x25, |
| 133 | BSSGP_CAUSE_PDU_INCOMP_STATE = 0x26, |
| 134 | BSSGP_CAUSE_PROTO_ERR_UNSPEC = 0x27, |
| 135 | BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28, |
| 136 | }; |
| 137 | |
Harald Welte | 9f75c35 | 2010-04-30 20:26:32 +0200 | [diff] [blame] | 138 | /* Our implementation */ |
| 139 | |
Harald Welte | 0a4050c | 2010-05-11 10:01:17 +0200 | [diff] [blame] | 140 | /* gprs_bssgp_util.c */ |
| 141 | extern struct gprs_ns_inst *bssgp_nsi; |
| 142 | struct msgb *bssgp_msgb_alloc(void); |
| 143 | const char *bssgp_cause_str(enum gprs_bssgp_cause cause); |
| 144 | /* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */ |
| 145 | int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei, |
| 146 | uint16_t bvci, uint16_t ns_bvci); |
| 147 | /* Chapter 10.4.14: Status */ |
| 148 | int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg); |
| 149 | |
| 150 | /* gprs_bssgp.c */ |
| 151 | |
Harald Welte | 5c90e5c | 2010-05-17 23:02:42 +0200 | [diff] [blame^] | 152 | #define BVC_S_BLOCKED 0x0001 |
| 153 | |
| 154 | /* The per-BTS context that we keep on the SGSN side of the BSSGP link */ |
| 155 | struct bssgp_bvc_ctx { |
| 156 | struct llist_head list; |
| 157 | |
| 158 | /* parsed RA ID and Cell ID of the remote BTS */ |
| 159 | struct gprs_ra_id ra_id; |
| 160 | uint16_t cell_id; |
| 161 | |
| 162 | /* NSEI and BVCI of underlying Gb link. Together they |
| 163 | * uniquely identify a link to a BTS (5.4.4) */ |
| 164 | uint16_t bvci; |
| 165 | uint16_t nsei; |
| 166 | |
| 167 | uint32_t state; |
| 168 | |
| 169 | struct rate_ctr_group *ctrg; |
| 170 | |
| 171 | /* we might want to add this as a shortcut later, avoiding the NSVC |
| 172 | * lookup for every packet, similar to a routing cache */ |
| 173 | //struct gprs_nsvc *nsvc; |
| 174 | }; |
| 175 | extern struct llist_head bssgp_bvc_ctxts; |
| 176 | /* Find a BTS Context based on parsed RA ID and Cell ID */ |
| 177 | struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t cid); |
| 178 | /* Find a BTS context based on BVCI+NSEI tuple */ |
| 179 | struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei); |
| 180 | |
Harald Welte | 9f75c35 | 2010-04-30 20:26:32 +0200 | [diff] [blame] | 181 | #include <osmocore/tlv.h> |
| 182 | |
Harald Welte | 4cc605a | 2010-05-13 19:25:59 +0200 | [diff] [blame] | 183 | /* BSSGP-UL-UNITDATA.ind */ |
| 184 | int gprs_bssgp_rcvmsg(struct msgb *msg); |
| 185 | |
| 186 | /* BSSGP-DL-UNITDATA.req */ |
| 187 | int gprs_bssgp_tx_dl_ud(struct msgb *msg); |
| 188 | |
Harald Welte | 11d7c10 | 2010-05-02 11:54:55 +0200 | [diff] [blame] | 189 | uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf); |
Harald Welte | 9b455bf | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 190 | |
Harald Welte | 9f75c35 | 2010-04-30 20:26:32 +0200 | [diff] [blame] | 191 | /* Wrapper around TLV parser to parse BSSGP IEs */ |
Harald Welte | eaa614c | 2010-05-02 11:26:34 +0200 | [diff] [blame] | 192 | static inline int bssgp_tlv_parse(struct tlv_parsed *tp, uint8_t *buf, int len) |
Harald Welte | 9f75c35 | 2010-04-30 20:26:32 +0200 | [diff] [blame] | 193 | { |
| 194 | return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0); |
| 195 | } |
| 196 | |
Harald Welte | 9b455bf | 2010-03-14 15:45:01 +0800 | [diff] [blame] | 197 | #endif /* _GPRS_BSSGP_H */ |