blob: 4be7b1f1844cf4e6307ca8b4ac5c9e93f68dc209 [file] [log] [blame]
Harald Welte9b455bf2010-03-14 15:45:01 +08001#ifndef _GPRS_LLC_H
2#define _GPRS_LLC_H
3
Harald Welteeaa614c2010-05-02 11:26:34 +02004#include <stdint.h>
Harald Welte807a5d82010-06-01 11:53:01 +02005#include <openbsc/gprs_sgsn.h>
Harald Welteeaa614c2010-05-02 11:26:34 +02006
Harald Welte9b455bf2010-03-14 15:45:01 +08007/* Section 4.7 LLC Layer Structure */
8enum gprs_llc_sapi {
9 GPRS_SAPI_GMM = 1,
10 GPRS_SAPI_TOM2 = 2,
11 GPRS_SAPI_SNDCP3 = 3,
12 GPRS_SAPI_SNDCP5 = 5,
13 GPRS_SAPI_SMS = 7,
14 GPRS_SAPI_TOM8 = 8,
15 GPRS_SAPI_SNDCP9 = 9,
16 GPRS_SAPI_SNDCP11 = 11,
17};
18
Harald Welte10997d02010-05-03 12:28:12 +020019/* Section 6.4 Commands and Responses */
20enum gprs_llc_u_cmd {
21 GPRS_LLC_U_DM_RESP = 0x01,
22 GPRS_LLC_U_DISC_CMD = 0x04,
23 GPRS_LLC_U_UA_RESP = 0x06,
24 GPRS_LLC_U_SABM_CMD = 0x07,
25 GPRS_LLC_U_FRMR_RESP = 0x08,
26 GPRS_LLC_U_XID = 0x0b,
27 GPRS_LLC_U_NULL_CMD = 0x00,
28};
Harald Welte9b455bf2010-03-14 15:45:01 +080029
Harald Welte0c1a3032011-10-16 18:49:05 +020030/* Section 6.4.1.6 / Table 6 */
31enum gprs_llc_xid_type {
32 GPRS_LLC_XID_T_VERSION = 0,
33 GPRS_LLC_XID_T_IOV_UI = 1,
34 GPRS_LLC_XID_T_IOV_I = 2,
35 GPRS_LLC_XID_T_T200 = 3,
36 GPRS_LLC_XID_T_N200 = 4,
37 GPRS_LLC_XID_T_N201_U = 5,
38 GPRS_LLC_XID_T_N201_I = 6,
39 GPRS_LLC_XID_T_mD = 7,
40 GPRS_LLC_XID_T_mU = 8,
41 GPRS_LLC_XID_T_kD = 9,
42 GPRS_LLC_XID_T_kU = 10,
43 GPRS_LLC_XID_T_L3_PAR = 11,
44 GPRS_LLC_XID_T_RESET = 12,
45};
46
Harald Welte1ae09c72010-05-13 19:22:55 +020047/* TS 04.64 Section 7.1.2 Table 7: LLC layer primitives (GMM/SNDCP/SMS/TOM) */
48/* TS 04.65 Section 5.1.2 Table 2: Service primitives used by SNDCP */
49enum gprs_llc_primitive {
50 /* GMM <-> LLME */
51 LLGMM_ASSIGN_REQ, /* GMM tells us new TLLI: TLLI old, TLLI new, Kc, CiphAlg */
52 LLGMM_RESET_REQ, /* GMM tells us to perform XID negotiation: TLLI */
53 LLGMM_RESET_CNF, /* LLC informs GMM that XID has completed: TLLI */
54 LLGMM_SUSPEND_REQ, /* GMM tells us MS has suspended: TLLI, Page */
55 LLGMM_RESUME_REQ, /* GMM tells us MS has resumed: TLLI */
56 LLGMM_PAGE_IND, /* LLC asks GMM to page MS: TLLI */
57 LLGMM_IOV_REQ, /* GMM tells us to perform XID: TLLI */
58 LLGMM_STATUS_IND, /* LLC informs GMM about error: TLLI, Cause */
59 /* LLE <-> (GMM/SNDCP/SMS/TOM) */
60 LL_RESET_IND, /* TLLI */
61 LL_ESTABLISH_REQ, /* TLLI, XID Req */
62 LL_ESTABLISH_IND, /* TLLI, XID Req, N201-I, N201-U */
63 LL_ESTABLISH_RESP, /* TLLI, XID Negotiated */
64 LL_ESTABLISH_CONF, /* TLLI, XID Neg, N201-i, N201-U */
65 LL_RELEASE_REQ, /* TLLI, Local */
66 LL_RELEASE_IND, /* TLLI, Cause */
67 LL_RELEASE_CONF, /* TLLI */
68 LL_XID_REQ, /* TLLI, XID Requested */
69 LL_XID_IND, /* TLLI, XID Req, N201-I, N201-U */
70 LL_XID_RESP, /* TLLI, XID Negotiated */
71 LL_XID_CONF, /* TLLI, XID Neg, N201-I, N201-U */
72 LL_DATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */
73 LL_DATA_IND, /* TLLI, SN-PDU */
74 LL_DATA_CONF, /* TLLI, Ref */
75 LL_UNITDATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */
76 LL_UNITDATA_IND, /* TLLI, SN-PDU */
77 LL_STATUS_IND, /* TLLI, Cause */
78};
79
Harald Welte2e918a82010-05-18 12:20:12 +020080/* Section 4.5.2 Logical Link States + Annex C.2 */
Harald Welte807a5d82010-06-01 11:53:01 +020081enum gprs_llc_lle_state {
82 GPRS_LLES_UNASSIGNED = 1, /* No TLLI yet */
83 GPRS_LLES_ASSIGNED_ADM = 2, /* TLLI assigned */
84 GPRS_LLES_LOCAL_EST = 3, /* Local Establishment */
85 GPRS_LLES_REMOTE_EST = 4, /* Remote Establishment */
86 GPRS_LLES_ABM = 5,
87 GPRS_LLES_LOCAL_REL = 6, /* Local Release */
88 GPRS_LLES_TIMER_REC = 7, /* Timer Recovery */
89};
90
91enum gprs_llc_llme_state {
92 GPRS_LLMS_UNASSIGNED = 1, /* No TLLI yet */
93 GPRS_LLMS_ASSIGNED = 2, /* TLLI assigned */
Harald Welte2e918a82010-05-18 12:20:12 +020094};
95
Harald Welte1d9d9442010-06-03 07:11:04 +020096/* Section 8.9.9 LLC layer parameter default values */
97struct gprs_llc_params {
98 uint16_t iov_i_exp;
99 uint16_t t200_201;
100 uint16_t n200;
101 uint16_t n201_u;
102 uint16_t n201_i;
103 uint16_t mD;
104 uint16_t mU;
105 uint16_t kD;
106 uint16_t kU;
107};
108
Harald Welte2e918a82010-05-18 12:20:12 +0200109/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */
110struct gprs_llc_lle {
111 struct llist_head list;
112
Harald Welte807a5d82010-06-01 11:53:01 +0200113 uint32_t sapi;
114
115 struct gprs_llc_llme *llme;
116
117 enum gprs_llc_lle_state state;
118
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200119 struct osmo_timer_list t200;
120 struct osmo_timer_list t201; /* wait for acknowledgement */
Harald Welte2e918a82010-05-18 12:20:12 +0200121
Harald Welte6bdee6a2010-05-30 21:51:58 +0200122 uint16_t v_sent;
123 uint16_t v_ack;
124 uint16_t v_recv;
125
126 uint16_t vu_send;
127 uint16_t vu_recv;
Harald Welte2e918a82010-05-18 12:20:12 +0200128
Harald Welteabadd542013-06-21 14:06:18 +0200129 /* non-standard LLC state */
130 uint16_t vu_recv_last;
131 uint16_t vu_recv_duplicates;
132
Harald Welted07b4f92010-06-30 23:07:59 +0200133 /* Overflow Counter for ABM */
134 uint32_t oc_i_send;
135 uint32_t oc_i_recv;
136
137 /* Overflow Counter for unconfirmed transfer */
138 uint32_t oc_ui_send;
139 uint32_t oc_ui_recv;
140
Harald Welte2e918a82010-05-18 12:20:12 +0200141 unsigned int retrans_ctr;
Harald Welte1d9d9442010-06-03 07:11:04 +0200142
143 struct gprs_llc_params params;
Harald Welte807a5d82010-06-01 11:53:01 +0200144};
145
146#define NUM_SAPIS 16
147
148struct gprs_llc_llme {
149 struct llist_head list;
150
151 enum gprs_llc_llme_state state;
152
153 uint32_t tlli;
154 uint32_t old_tlli;
Harald Welte2e918a82010-05-18 12:20:12 +0200155
Harald Welted07b4f92010-06-30 23:07:59 +0200156 /* Crypto parameters */
157 enum gprs_ciph_algo algo;
158 uint8_t kc[8];
159
Harald Welte2e918a82010-05-18 12:20:12 +0200160 /* over which BSSGP BTS ctx do we need to transmit */
161 uint16_t bvci;
162 uint16_t nsei;
Harald Welte807a5d82010-06-01 11:53:01 +0200163 struct gprs_llc_lle lle[NUM_SAPIS];
Harald Welte2e918a82010-05-18 12:20:12 +0200164};
165
Harald Welte807a5d82010-06-01 11:53:01 +0200166extern struct llist_head gprs_llc_llmes;
Harald Welte2e918a82010-05-18 12:20:12 +0200167
Harald Welte1ae09c72010-05-13 19:22:55 +0200168/* BSSGP-UL-UNITDATA.ind */
Harald Welte9b455bf2010-03-14 15:45:01 +0800169int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv);
Harald Welte1ae09c72010-05-13 19:22:55 +0200170
171/* LL-UNITDATA.req */
Harald Welte56a01452010-05-31 22:12:30 +0200172int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
173 void *mmctx);
Harald Welte9b455bf2010-03-14 15:45:01 +0800174
Harald Welte0c1a3032011-10-16 18:49:05 +0200175/* Chapter 7.2.1.2 LLGMM-RESET.req */
176int gprs_llgmm_reset(struct gprs_llc_llme *llme);
177
Harald Welte807a5d82010-06-01 11:53:01 +0200178/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */
179int gprs_llgmm_assign(struct gprs_llc_llme *llme,
180 uint32_t old_tlli, uint32_t new_tlli,
181 enum gprs_ciph_algo alg, const uint8_t *kc);
182
Harald Welte496aee42010-06-30 19:59:55 +0200183int gprs_llc_init(const char *cipher_plugin_path);
Harald Welte2e918a82010-05-18 12:20:12 +0200184int gprs_llc_vty_init(void);
185
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -0400186/**
187 * \short Check if N(U) should be considered a retransmit
188 *
189 * Implements the range check as of GSM 04.64 8.4.2
190 * Receipt of unacknowledged information.
191 *
192 * @returns Returns 1 if (V(UR)-32) <= N(U) < V(UR)
193 * @param nu N(U) unconfirmed sequence number of the UI frame
194 * @param vur V(UR) unconfirmend received state variable
195 */
196static inline int gprs_llc_is_retransmit(uint16_t nu, uint16_t vur)
197{
198 int delta = (vur - nu) & 0x1ff;
199 return 0 < delta && delta < 32;
200}
201
Harald Welte9b455bf2010-03-14 15:45:01 +0800202#endif