blob: 363b45766fbef33fc3a75d020e3a115cfe212c3c [file] [log] [blame]
Harald Welte9b455bf2010-03-14 15:45:01 +08001/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
2 * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
3
Harald Welteeb98c742015-08-16 17:11:32 +02004/* (C) 2009-2015 by Harald Welte <laforge@gnumonks.org>
Harald Weltec2e8cc42010-05-31 20:23:38 +02005 * (C) 2010 by On-Waves
Harald Welte9b455bf2010-03-14 15:45:01 +08006 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Harald Welte9b455bf2010-03-14 15:45:01 +080012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Harald Welte9af6ddf2011-01-01 15:25:50 +010017 * GNU Affero General Public License for more details.
Harald Welte9b455bf2010-03-14 15:45:01 +080018 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Harald Welte9b455bf2010-03-14 15:45:01 +080021 *
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
Harald Welteeaa614c2010-05-02 11:26:34 +020027#include <stdint.h>
Harald Welte9b455bf2010-03-14 15:45:01 +080028#include <errno.h>
Max82040102016-07-06 11:59:18 +020029#include <stdbool.h>
Harald Welte9b455bf2010-03-14 15:45:01 +080030#include <netinet/in.h>
Harald Welte421cba42010-05-02 23:11:50 +020031#include <arpa/inet.h>
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +080032#include <netdb.h>
Harald Welte9b455bf2010-03-14 15:45:01 +080033
Max4011e722016-07-05 15:19:12 +020034#include <openssl/rand.h>
35
Daniel Willmann6292c8d2016-05-21 17:35:57 +020036#include "bscconfig.h"
37
Harald Welte9b455bf2010-03-14 15:45:01 +080038#include <openbsc/db.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010039#include <osmocom/core/msgb.h>
Harald Welted36ff762011-03-23 18:26:56 +010040#include <osmocom/gsm/tlv.h>
41#include <osmocom/gsm/gsm_utils.h>
Pablo Neira Ayuso136f4532011-03-22 16:47:59 +010042#include <osmocom/core/signal.h>
43#include <osmocom/core/talloc.h>
44#include <osmocom/core/rate_ctr.h>
Daniel Willmann770f3e32016-05-21 00:31:12 +020045#include <osmocom/crypt/auth.h>
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +080046#include <osmocom/gsm/apn.h>
Harald Welte53373bc2016-04-20 17:11:43 +020047#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
Harald Welted6057092010-05-02 12:57:45 +020048
Harald Welteea34a4e2012-06-16 14:59:56 +080049#include <osmocom/gprs/gprs_bssgp.h>
50
Daniel Willmann6292c8d2016-05-21 17:35:57 +020051#ifdef BUILD_IU
52#include <osmocom/ranap/ranap_ies_defs.h>
Daniel Willmannaf241722016-05-21 00:35:41 +020053#include <osmocom/ranap/ranap_msg_factory.h>
Daniel Willmann6292c8d2016-05-21 17:35:57 +020054#endif
55
Harald Welte9b455bf2010-03-14 15:45:01 +080056#include <openbsc/debug.h>
57#include <openbsc/gsm_data.h>
Harald Welte9b455bf2010-03-14 15:45:01 +080058#include <openbsc/gsm_subscriber.h>
59#include <openbsc/gsm_04_08.h>
Harald Welte9b455bf2010-03-14 15:45:01 +080060#include <openbsc/paging.h>
Harald Welte9b455bf2010-03-14 15:45:01 +080061#include <openbsc/transaction.h>
62#include <openbsc/gprs_llc.h>
63#include <openbsc/gprs_sgsn.h>
Harald Welte6abf94e2010-05-18 10:35:06 +020064#include <openbsc/gprs_gmm.h>
Jacob Erlbeck8de9c482015-01-23 11:44:39 +010065#include <openbsc/gprs_utils.h>
Harald Welted193cb32010-05-17 22:58:03 +020066#include <openbsc/sgsn.h>
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +020067#include <openbsc/signal.h>
Daniel Willmann6292c8d2016-05-21 17:35:57 +020068#include <openbsc/iu.h>
Daniel Willmann6292c8d2016-05-21 17:35:57 +020069
Harald Welte6abf94e2010-05-18 10:35:06 +020070#include <pdp.h>
71
Harald Weltec2e8cc42010-05-31 20:23:38 +020072#define PTMSI_ALLOC
73
Harald Welted193cb32010-05-17 22:58:03 +020074extern struct sgsn_instance *sgsn;
Harald Welte9b455bf2010-03-14 15:45:01 +080075
Harald Welte588d44e2010-06-09 10:28:29 +020076static const struct tlv_definition gsm48_gmm_att_tlvdef = {
77 .def = {
Harald Welte4b6ac1e2010-07-03 11:09:06 +020078 [GSM48_IE_GMM_CIPH_CKSN] = { TLV_TYPE_FIXED, 1 },
Harald Welte588d44e2010-06-09 10:28:29 +020079 [GSM48_IE_GMM_TIMER_READY] = { TLV_TYPE_TV, 1 },
80 [GSM48_IE_GMM_ALLOC_PTMSI] = { TLV_TYPE_TLV, 0 },
Harald Welte4b6ac1e2010-07-03 11:09:06 +020081 [GSM48_IE_GMM_PTMSI_SIG] = { TLV_TYPE_FIXED, 3 },
82 [GSM48_IE_GMM_AUTH_RAND] = { TLV_TYPE_FIXED, 16 },
83 [GSM48_IE_GMM_AUTH_SRES] = { TLV_TYPE_FIXED, 4 },
Harald Welte588d44e2010-06-09 10:28:29 +020084 [GSM48_IE_GMM_IMEISV] = { TLV_TYPE_TLV, 0 },
Harald Welte4b6ac1e2010-07-03 11:09:06 +020085 [GSM48_IE_GMM_DRX_PARAM] = { TLV_TYPE_FIXED, 2 },
Harald Welte588d44e2010-06-09 10:28:29 +020086 [GSM48_IE_GMM_MS_NET_CAPA] = { TLV_TYPE_TLV, 0 },
87 [GSM48_IE_GMM_PDP_CTX_STATUS] = { TLV_TYPE_TLV, 0 },
88 [GSM48_IE_GMM_PS_LCS_CAPA] = { TLV_TYPE_TLV, 0 },
89 [GSM48_IE_GMM_GMM_MBMS_CTX_ST] = { TLV_TYPE_TLV, 0 },
90 },
91};
92
93static const struct tlv_definition gsm48_sm_att_tlvdef = {
94 .def = {
95 [GSM48_IE_GSM_APN] = { TLV_TYPE_TLV, 0 },
96 [GSM48_IE_GSM_PROTO_CONF_OPT] = { TLV_TYPE_TLV, 0 },
97 [GSM48_IE_GSM_PDP_ADDR] = { TLV_TYPE_TLV, 0 },
98 [GSM48_IE_GSM_AA_TMR] = { TLV_TYPE_TV, 1 },
99 [GSM48_IE_GSM_NAME_FULL] = { TLV_TYPE_TLV, 0 },
100 [GSM48_IE_GSM_NAME_SHORT] = { TLV_TYPE_TLV, 0 },
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200101 [GSM48_IE_GSM_TIMEZONE] = { TLV_TYPE_FIXED, 1 },
102 [GSM48_IE_GSM_UTC_AND_TZ] = { TLV_TYPE_FIXED, 7 },
Harald Welte588d44e2010-06-09 10:28:29 +0200103 [GSM48_IE_GSM_LSA_ID] = { TLV_TYPE_TLV, 0 },
104 },
105};
106
Jacob Erlbeck4adb1362014-12-02 09:47:26 +0100107static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx);
108
Daniel Willmann21b269f2016-05-11 12:43:47 +0200109static void mmctx_change_gtpu_endpoints_to_sgsn(struct sgsn_mm_ctx *mm_ctx)
110{
111 struct sgsn_pdp_ctx *pdp;
112 llist_for_each_entry(pdp, &mm_ctx->pdp_list, list) {
113 sgsn_pdp_upd_gtp_u(pdp,
114 &sgsn->cfg.gtp_listenaddr.sin_addr,
115 sizeof(sgsn->cfg.gtp_listenaddr.sin_addr));
116 }
117}
118
Daniel Willmannc17cdb42016-05-11 12:42:54 +0200119void mmctx_set_pmm_state(struct sgsn_mm_ctx *ctx, enum gprs_pmm_state state)
120{
121 if (ctx->pmm_state == state)
122 return;
123
124 LOGMMCTXP(LOGL_INFO, ctx, "Changing PMM state from %i to %i\n", ctx->pmm_state, state);
125
126 if (ctx->ran_type == MM_CTX_T_UTRAN_Iu)
127 {
128 switch (state) {
129 case PMM_IDLE:
Daniel Willmann21b269f2016-05-11 12:43:47 +0200130 /* TODO: start RA Upd timer */
131 mmctx_change_gtpu_endpoints_to_sgsn(ctx);
Daniel Willmannc17cdb42016-05-11 12:42:54 +0200132 break;
133 case PMM_CONNECTED:
134 break;
135 default:
136 break;
137 }
138 }
139
140 ctx->pmm_state = state;
141}
142
Daniel Willmann6292c8d2016-05-21 17:35:57 +0200143#ifdef BUILD_IU
144int sgsn_ranap_rab_ass_resp(struct sgsn_mm_ctx *ctx, RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies);
145int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, void *data)
146{
147 struct sgsn_mm_ctx *mm;
148 int rc = -1;
149
150 mm = sgsn_mm_ctx_by_ue_ctx(ctx);
151 if (!mm) {
152 LOGP(DRANAP, LOGL_NOTICE, "Cannot find mm ctx for IU event %i!\n", type);
153 return rc;
154 }
155
156 switch (type) {
157 case IU_EVENT_RAB_ASSIGN:
158 rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data);
159 break;
160 case IU_EVENT_IU_RELEASE:
161 /* fall thru */
162 case IU_EVENT_LINK_INVALIDATED:
163 /* Clean up ue_conn_ctx here */
164 LOGMMCTXP(LOGL_INFO, mm, "IU release for imsi %s\n", mm->imsi);
Daniel Willmann5b2363e2016-05-21 00:01:21 +0200165 if (mm->pmm_state == PMM_CONNECTED)
Daniel Willmannc17cdb42016-05-11 12:42:54 +0200166 mmctx_set_pmm_state(mm, PMM_IDLE);
Daniel Willmann6292c8d2016-05-21 17:35:57 +0200167 rc = 0;
168 break;
169 case IU_EVENT_SECURITY_MODE_COMPLETE:
170 /* Continue authentication here */
171 mm->iu.ue_ctx->integrity_active = 1;
172 rc = gsm48_gmm_authorize(mm);
173 break;
174 default:
175 LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type);
176 rc = -1;
177 break;
178 }
179 return rc;
180}
181#endif
182
183
Harald Welte2720e732010-05-17 00:44:57 +0200184/* Our implementation, should be kept in SGSN */
Harald Welte9b455bf2010-03-14 15:45:01 +0800185
Harald Weltec2e8cc42010-05-31 20:23:38 +0200186static void mmctx_timer_cb(void *_mm);
187
188static void mmctx_timer_start(struct sgsn_mm_ctx *mm, unsigned int T,
189 unsigned int seconds)
190{
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200191 if (osmo_timer_pending(&mm->timer))
Harald Welteeb98c742015-08-16 17:11:32 +0200192 LOGMMCTXP(LOGL_ERROR, mm, "Starting MM timer %u while old "
Harald Weltec2e8cc42010-05-31 20:23:38 +0200193 "timer %u pending\n", T, mm->T);
194 mm->T = T;
195 mm->num_T_exp = 0;
196
197 /* FIXME: we should do this only once ? */
198 mm->timer.data = mm;
199 mm->timer.cb = &mmctx_timer_cb;
200
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200201 osmo_timer_schedule(&mm->timer, seconds, 0);
Harald Weltec2e8cc42010-05-31 20:23:38 +0200202}
203
204static void mmctx_timer_stop(struct sgsn_mm_ctx *mm, unsigned int T)
205{
206 if (mm->T != T)
Harald Welteeb98c742015-08-16 17:11:32 +0200207 LOGMMCTXP(LOGL_ERROR, mm, "Stopping MM timer %u but "
Harald Weltec2e8cc42010-05-31 20:23:38 +0200208 "%u is running\n", T, mm->T);
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +0200209 osmo_timer_del(&mm->timer);
Harald Weltec2e8cc42010-05-31 20:23:38 +0200210}
211
Jacob Erlbeck81ffb742015-01-23 11:33:51 +0100212time_t gprs_max_time_to_idle(void)
213{
Harald Welte94508822015-08-15 19:08:21 +0200214 return sgsn->cfg.timers.T3314 + (sgsn->cfg.timers.T3312 + 4 * 60);
Jacob Erlbeck81ffb742015-01-23 11:33:51 +0100215}
216
Neels Hofmeyr723f7c72016-08-11 19:12:54 +0200217/* Send a message through the underlying layer.
218 * For param encryptable, see 3GPP TS 24.008 § 4.7.1.2 and
219 * gsm48_hdr_gmm_cipherable(). Pass false for not cipherable messages. */
Harald Welte8acd88f2010-05-18 10:57:45 +0200220static int gsm48_gmm_sendmsg(struct msgb *msg, int command,
Max82040102016-07-06 11:59:18 +0200221 struct sgsn_mm_ctx *mm, bool encryptable)
Harald Welte9b455bf2010-03-14 15:45:01 +0800222{
Daniel Willmann61329d42016-05-21 17:36:18 +0200223 if (mm) {
Harald Welte8acd88f2010-05-18 10:57:45 +0200224 rate_ctr_inc(&mm->ctrg->ctr[GMM_CTR_PKTS_SIG_OUT]);
Daniel Willmann61329d42016-05-21 17:36:18 +0200225#ifdef BUILD_IU
226 if (mm->ran_type == MM_CTX_T_UTRAN_Iu)
227 return iu_tx(msg, GPRS_SAPI_GMM);
228#endif
229 }
230
231#ifdef BUILD_IU
232 /* In Iu mode, msg->dst contains the ue_conn_ctx pointer, in Gb mode
233 * dst is empty. */
234 /* FIXME: have a more explicit indicator for Iu messages */
235 if (msg->dst)
236 return iu_tx(msg, GPRS_SAPI_GMM);
237#endif
Harald Welte8acd88f2010-05-18 10:57:45 +0200238
Harald Welte11d7c102010-05-02 11:54:55 +0200239 /* caller needs to provide TLLI, BVCI and NSEI */
Max82040102016-07-06 11:59:18 +0200240 return gprs_llc_tx_ui(msg, GPRS_SAPI_GMM, command, mm, encryptable);
Harald Welte9b455bf2010-03-14 15:45:01 +0800241}
242
Harald Welte11d7c102010-05-02 11:54:55 +0200243/* copy identifiers from old message to new message, this
244 * is required so lower layers can route it correctly */
245static void gmm_copy_id(struct msgb *msg, const struct msgb *old)
246{
247 msgb_tlli(msg) = msgb_tlli(old);
248 msgb_bvci(msg) = msgb_bvci(old);
249 msgb_nsei(msg) = msgb_nsei(old);
Daniel Willmannd75864f2016-05-21 00:11:39 +0200250 msg->dst = old->dst;
Harald Welte11d7c102010-05-02 11:54:55 +0200251}
252
Harald Welte6abf94e2010-05-18 10:35:06 +0200253/* Store BVCI/NSEI in MM context */
254static void msgid2mmctx(struct sgsn_mm_ctx *mm, const struct msgb *msg)
255{
Harald Weltef97ee042015-12-25 19:12:21 +0100256 mm->gb.bvci = msgb_bvci(msg);
257 mm->gb.nsei = msgb_nsei(msg);
Daniel Willmannd75864f2016-05-21 00:11:39 +0200258 /* In case a Iu connection is reconnected we need to update the ue ctx */
259 mm->iu.ue_ctx = msg->dst;
Harald Welte6abf94e2010-05-18 10:35:06 +0200260}
261
262/* Store BVCI/NSEI in MM context */
263static void mmctx2msgid(struct msgb *msg, const struct sgsn_mm_ctx *mm)
264{
Harald Weltef97ee042015-12-25 19:12:21 +0100265 msgb_tlli(msg) = mm->gb.tlli;
266 msgb_bvci(msg) = mm->gb.bvci;
267 msgb_nsei(msg) = mm->gb.nsei;
Daniel Willmannd75864f2016-05-21 00:11:39 +0200268 msg->dst = mm->iu.ue_ctx;
Harald Welte6abf94e2010-05-18 10:35:06 +0200269}
270
Jacob Erlbeck99985b52014-10-13 10:32:00 +0200271static void mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx, const char *log_text)
272{
Jacob Erlbecke671d252015-01-26 14:43:07 +0100273 LOGMMCTXP(LOGL_INFO, ctx, "Cleaning MM context due to %s\n", log_text);
Jacob Erlbeck99985b52014-10-13 10:32:00 +0200274
275 /* Mark MM state as deregistered */
276 ctx->mm_state = GMM_DEREGISTERED;
Daniel Willmannc17cdb42016-05-11 12:42:54 +0200277
278 mmctx_set_pmm_state(ctx, PMM_DETACHED);
Jacob Erlbeck99985b52014-10-13 10:32:00 +0200279
Jacob Erlbecke671d252015-01-26 14:43:07 +0100280 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck99985b52014-10-13 10:32:00 +0200281}
282
Harald Weltef54e7e22010-06-09 10:51:23 +0200283/* Chapter 9.4.18 */
284static int _tx_status(struct msgb *msg, uint8_t cause,
285 struct sgsn_mm_ctx *mmctx, int sm)
286{
287 struct gsm48_hdr *gh;
288
289 /* MMCTX might be NULL! */
290
291 DEBUGP(DMM, "<- GPRS MM STATUS (cause: %s)\n",
Jacob Erlbeckafcf2302015-01-05 17:30:02 +0100292 get_value_string(gsm48_gmm_cause_names, cause));
Harald Weltef54e7e22010-06-09 10:51:23 +0200293
294 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
295 if (sm) {
296 gh->proto_discr = GSM48_PDISC_SM_GPRS;
297 gh->msg_type = GSM48_MT_GSM_STATUS;
298 } else {
299 gh->proto_discr = GSM48_PDISC_MM_GPRS;
300 gh->msg_type = GSM48_MT_GMM_STATUS;
301 }
302 gh->data[0] = cause;
303
Max82040102016-07-06 11:59:18 +0200304 return gsm48_gmm_sendmsg(msg, 0, mmctx, true);
Harald Weltef54e7e22010-06-09 10:51:23 +0200305}
Jacob Erlbeck70671422014-10-29 22:57:30 +0100306
Harald Weltef54e7e22010-06-09 10:51:23 +0200307static int gsm48_tx_gmm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause)
308{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100309 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 GMM STATUS");
Harald Weltef54e7e22010-06-09 10:51:23 +0200310
311 mmctx2msgid(msg, mmctx);
312 return _tx_status(msg, cause, mmctx, 0);
Harald Weltef54e7e22010-06-09 10:51:23 +0200313}
Jacob Erlbeck70671422014-10-29 22:57:30 +0100314
Harald Weltef54e7e22010-06-09 10:51:23 +0200315static int gsm48_tx_sm_status(struct sgsn_mm_ctx *mmctx, uint8_t cause)
316{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100317 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SM STATUS");
Harald Weltef54e7e22010-06-09 10:51:23 +0200318
319 mmctx2msgid(msg, mmctx);
320 return _tx_status(msg, cause, mmctx, 1);
Harald Weltef54e7e22010-06-09 10:51:23 +0200321}
322
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +0200323static int _tx_detach_req(struct msgb *msg, uint8_t detach_type, uint8_t cause,
324 struct sgsn_mm_ctx *mmctx)
325{
326 struct gsm48_hdr *gh;
327
328 /* MMCTX might be NULL! */
329
330 DEBUGP(DMM, "<- GPRS MM DETACH REQ (type: %s, cause: %s)\n",
331 get_value_string(gprs_det_t_mt_strs, detach_type),
Jacob Erlbeckafcf2302015-01-05 17:30:02 +0100332 get_value_string(gsm48_gmm_cause_names, cause));
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +0200333
334 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
335
336 gh->proto_discr = GSM48_PDISC_MM_GPRS;
337 gh->msg_type = GSM48_MT_GMM_DETACH_REQ;
338 gh->data[0] = detach_type & 0x07;
339
340 msgb_tv_put(msg, GSM48_IE_GMM_CAUSE, cause);
341
Max82040102016-07-06 11:59:18 +0200342 return gsm48_gmm_sendmsg(msg, 0, mmctx, true);
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +0200343}
344
345static int gsm48_tx_gmm_detach_req(struct sgsn_mm_ctx *mmctx,
346 uint8_t detach_type, uint8_t cause)
347{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100348 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET REQ");
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +0200349
350 mmctx2msgid(msg, mmctx);
351 return _tx_detach_req(msg, detach_type, cause, mmctx);
352}
353
354static int gsm48_tx_gmm_detach_req_oldmsg(struct msgb *oldmsg,
355 uint8_t detach_type, uint8_t cause)
356{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100357 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET OLD");
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +0200358
359 gmm_copy_id(msg, oldmsg);
360 return _tx_detach_req(msg, detach_type, cause, NULL);
361}
Harald Weltef54e7e22010-06-09 10:51:23 +0200362
Harald Welte86fda902010-05-03 10:54:35 +0200363static struct gsm48_qos default_qos = {
364 .delay_class = 4, /* best effort */
365 .reliab_class = GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT,
366 .peak_tput = GSM48_QOS_PEAK_TPUT_32000bps,
367 .preced_class = GSM48_QOS_PC_NORMAL,
368 .mean_tput = GSM48_QOS_MEAN_TPUT_BEST_EFFORT,
369 .traf_class = GSM48_QOS_TC_INTERACTIVE,
370 .deliv_order = GSM48_QOS_DO_UNORDERED,
371 .deliv_err_sdu = GSM48_QOS_ERRSDU_YES,
372 .max_sdu_size = GSM48_QOS_MAXSDU_1520,
373 .max_bitrate_up = GSM48_QOS_MBRATE_63k,
374 .max_bitrate_down = GSM48_QOS_MBRATE_63k,
375 .resid_ber = GSM48_QOS_RBER_5e_2,
376 .sdu_err_ratio = GSM48_QOS_SERR_1e_2,
377 .handling_prio = 3,
378 .xfer_delay = 0x10, /* 200ms */
379 .guar_bitrate_up = GSM48_QOS_MBRATE_0k,
380 .guar_bitrate_down = GSM48_QOS_MBRATE_0k,
381 .sig_ind = 0, /* not optimised for signalling */
382 .max_bitrate_down_ext = 0, /* use octet 9 */
383 .guar_bitrate_down_ext = 0, /* use octet 13 */
384};
385
Harald Welte9b455bf2010-03-14 15:45:01 +0800386/* Chapter 9.4.2: Attach accept */
Harald Welte6463c072010-05-18 17:04:55 +0200387static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
Harald Welte9b455bf2010-03-14 15:45:01 +0800388{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100389 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT ACK");
Harald Welte9b455bf2010-03-14 15:45:01 +0800390 struct gsm48_hdr *gh;
391 struct gsm48_attach_ack *aa;
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +0200392 uint8_t *mid;
393#if 0
394 uint8_t *ptsig;
395#endif
Harald Welte9b455bf2010-03-14 15:45:01 +0800396
Daniel Willmann46553142014-09-03 17:46:44 +0200397 LOGMMCTXP(LOGL_INFO, mm, "<- GPRS ATTACH ACCEPT (new P-TMSI=0x%08x)\n", mm->p_tmsi);
Alexander Couzens14314bd2016-07-05 09:52:52 +0200398 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ATTACH_ACKED]);
Harald Welte9b455bf2010-03-14 15:45:01 +0800399
Harald Welte6463c072010-05-18 17:04:55 +0200400 mmctx2msgid(msg, mm);
Harald Welte9b455bf2010-03-14 15:45:01 +0800401
402 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
403 gh->proto_discr = GSM48_PDISC_MM_GPRS;
404 gh->msg_type = GSM48_MT_GMM_ATTACH_ACK;
405
406 aa = (struct gsm48_attach_ack *) msgb_put(msg, sizeof(*aa));
407 aa->force_stby = 0; /* not indicated */
408 aa->att_result = 1; /* GPRS only */
Harald Welte94508822015-08-15 19:08:21 +0200409 aa->ra_upd_timer = gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3312);
Harald Welte9b455bf2010-03-14 15:45:01 +0800410 aa->radio_prio = 4; /* lowest */
Harald Welte6463c072010-05-18 17:04:55 +0200411 gsm48_construct_ra(aa->ra_id.digits, &mm->ra);
Harald Welte9b455bf2010-03-14 15:45:01 +0800412
Harald Welteab1d5622010-05-18 19:58:38 +0200413#if 0
Harald Welte6463c072010-05-18 17:04:55 +0200414 /* Optional: P-TMSI signature */
415 msgb_v_put(msg, GSM48_IE_GMM_PTMSI_SIG);
416 ptsig = msgb_put(msg, 3);
417 ptsig[0] = mm->p_tmsi_sig >> 16;
418 ptsig[1] = mm->p_tmsi_sig >> 8;
419 ptsig[2] = mm->p_tmsi_sig & 0xff;
420
Harald Weltec2e8cc42010-05-31 20:23:38 +0200421#endif
Jacob Erlbeck8de9c482015-01-23 11:44:39 +0100422 /* Optional: Negotiated Ready timer value
423 * (fixed 44s, default value, GSM 04.08, table 11.4a) to safely limit
424 * the inactivity time READY->STANDBY.
425 */
426 msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY,
Harald Welte94508822015-08-15 19:08:21 +0200427 gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3314));
Harald Welte6463c072010-05-18 17:04:55 +0200428
Harald Weltec2e8cc42010-05-31 20:23:38 +0200429#ifdef PTMSI_ALLOC
Harald Welte6463c072010-05-18 17:04:55 +0200430 /* Optional: Allocated P-TMSI */
Harald Welte6463c072010-05-18 17:04:55 +0200431 mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
432 gsm48_generate_mid_from_tmsi(mid, mm->p_tmsi);
Harald Welteab1d5622010-05-18 19:58:38 +0200433 mid[0] = GSM48_IE_GMM_ALLOC_PTMSI;
434#endif
Harald Weltec2e8cc42010-05-31 20:23:38 +0200435
Harald Welte6463c072010-05-18 17:04:55 +0200436 /* Optional: MS-identity (combined attach) */
437 /* Optional: GMM cause (partial attach result for combined attach) */
438
Max82040102016-07-06 11:59:18 +0200439 return gsm48_gmm_sendmsg(msg, 0, mm, true);
Harald Welte9b455bf2010-03-14 15:45:01 +0800440}
441
442/* Chapter 9.4.5: Attach reject */
Harald Welteeb98c742015-08-16 17:11:32 +0200443static int _tx_gmm_att_rej(struct msgb *msg, uint8_t gmm_cause,
444 const struct sgsn_mm_ctx *mm)
Harald Welte9b455bf2010-03-14 15:45:01 +0800445{
Harald Welte9b455bf2010-03-14 15:45:01 +0800446 struct gsm48_hdr *gh;
447
Harald Welteeb98c742015-08-16 17:11:32 +0200448 LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS ATTACH REJECT: %s\n",
449 get_value_string(gsm48_gmm_cause_names, gmm_cause));
Alexander Couzens14314bd2016-07-05 09:52:52 +0200450 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ATTACH_REJECTED]);
Harald Welte9b455bf2010-03-14 15:45:01 +0800451
Harald Welte9b455bf2010-03-14 15:45:01 +0800452 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
453 gh->proto_discr = GSM48_PDISC_MM_GPRS;
454 gh->msg_type = GSM48_MT_GMM_ATTACH_REJ;
455 gh->data[0] = gmm_cause;
456
Max82040102016-07-06 11:59:18 +0200457 return gsm48_gmm_sendmsg(msg, 0, NULL, false);
Harald Welte9b455bf2010-03-14 15:45:01 +0800458}
Harald Welte6463c072010-05-18 17:04:55 +0200459static int gsm48_tx_gmm_att_rej_oldmsg(const struct msgb *old_msg,
460 uint8_t gmm_cause)
461{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100462 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT REJ OLD");
Harald Welte6463c072010-05-18 17:04:55 +0200463 gmm_copy_id(msg, old_msg);
Harald Welteeb98c742015-08-16 17:11:32 +0200464 return _tx_gmm_att_rej(msg, gmm_cause, NULL);
Harald Welte6463c072010-05-18 17:04:55 +0200465}
466static int gsm48_tx_gmm_att_rej(struct sgsn_mm_ctx *mm,
467 uint8_t gmm_cause)
468{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100469 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ATT REJ");
Harald Welte6463c072010-05-18 17:04:55 +0200470 mmctx2msgid(msg, mm);
Harald Welteeb98c742015-08-16 17:11:32 +0200471 return _tx_gmm_att_rej(msg, gmm_cause, mm);
Harald Welte6463c072010-05-18 17:04:55 +0200472}
Harald Welte9b455bf2010-03-14 15:45:01 +0800473
Harald Welte2720e732010-05-17 00:44:57 +0200474/* Chapter 9.4.6.2 Detach accept */
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200475static int _tx_detach_ack(struct msgb *msg, uint8_t force_stby,
476 struct sgsn_mm_ctx *mm)
Harald Welte2720e732010-05-17 00:44:57 +0200477{
Harald Welte2720e732010-05-17 00:44:57 +0200478 struct gsm48_hdr *gh;
479
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200480 /* MMCTX might be NULL! */
Harald Welte2720e732010-05-17 00:44:57 +0200481
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200482 DEBUGP(DMM, "<- GPRS MM DETACH ACC (force-standby: %d)\n", force_stby);
Alexander Couzens14314bd2016-07-05 09:52:52 +0200483 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_DETACH_ACKED]);
Harald Welte6463c072010-05-18 17:04:55 +0200484
Harald Welte2720e732010-05-17 00:44:57 +0200485 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
486 gh->proto_discr = GSM48_PDISC_MM_GPRS;
487 gh->msg_type = GSM48_MT_GMM_DETACH_ACK;
488 gh->data[0] = force_stby;
489
Max82040102016-07-06 11:59:18 +0200490 return gsm48_gmm_sendmsg(msg, 0, mm, true);
Harald Welte2720e732010-05-17 00:44:57 +0200491}
492
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200493static int gsm48_tx_gmm_det_ack(struct sgsn_mm_ctx *mm, uint8_t force_stby)
494{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100495 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACK");
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200496
497 mmctx2msgid(msg, mm);
498 return _tx_detach_ack(msg, force_stby, mm);
499}
500
501static int gsm48_tx_gmm_det_ack_oldmsg(struct msgb *oldmsg, uint8_t force_stby)
502{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100503 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACK OLD");
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200504
505 gmm_copy_id(msg, oldmsg);
506 return _tx_detach_ack(msg, force_stby, NULL);
507}
508
Harald Welte9b455bf2010-03-14 15:45:01 +0800509/* Transmit Chapter 9.4.12 Identity Request */
Harald Welte6463c072010-05-18 17:04:55 +0200510static int gsm48_tx_gmm_id_req(struct sgsn_mm_ctx *mm, uint8_t id_type)
Harald Welte9b455bf2010-03-14 15:45:01 +0800511{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100512 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ");
Harald Welte9b455bf2010-03-14 15:45:01 +0800513 struct gsm48_hdr *gh;
514
Harald Welteb9845f92015-08-16 18:07:48 +0200515 LOGMMCTXP(LOGL_DEBUG, mm, "<- GPRS IDENTITY REQUEST: mi_type=%s\n",
516 gsm48_mi_type_name(id_type));
Harald Welte9b455bf2010-03-14 15:45:01 +0800517
Harald Welte6463c072010-05-18 17:04:55 +0200518 mmctx2msgid(msg, mm);
Harald Welte9b455bf2010-03-14 15:45:01 +0800519
520 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
521 gh->proto_discr = GSM48_PDISC_MM_GPRS;
522 gh->msg_type = GSM48_MT_GMM_ID_REQ;
523 /* 10.5.5.9 ID type 2 + identity type and 10.5.5.7 'force to standby' IE */
524 gh->data[0] = id_type & 0xf;
525
Max82040102016-07-06 11:59:18 +0200526 return gsm48_gmm_sendmsg(msg, 1, mm, false);
Harald Welte9b455bf2010-03-14 15:45:01 +0800527}
528
Maxb997f842016-07-06 15:57:01 +0200529/* 3GPP TS 24.008 Section 9.4.9: Authentication and Ciphering Request */
Max4011e722016-07-05 15:19:12 +0200530static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm, uint8_t *rnd,
Maxb997f842016-07-06 15:57:01 +0200531 uint8_t key_seq, bool force_standby)
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200532{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100533 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH CIPH REQ");
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200534 struct gsm48_hdr *gh;
535 struct gsm48_auth_ciph_req *acreq;
Max4011e722016-07-05 15:19:12 +0200536 uint8_t *m_rand, *m_cksn, rbyte;
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200537
Daniel Willmann46553142014-09-03 17:46:44 +0200538 LOGMMCTXP(LOGL_INFO, mm, "<- GPRS AUTH AND CIPHERING REQ (rand = %s)\n",
Max4011e722016-07-05 15:19:12 +0200539 osmo_hexdump(rnd, 16));
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200540
541 mmctx2msgid(msg, mm);
542
543 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
544 gh->proto_discr = GSM48_PDISC_MM_GPRS;
545 gh->msg_type = GSM48_MT_GMM_AUTH_CIPH_REQ;
546
547 acreq = (struct gsm48_auth_ciph_req *) msgb_put(msg, sizeof(*acreq));
Maxb997f842016-07-06 15:57:01 +0200548 acreq->ciph_alg = mm->ciph_algo & 0xf;
549 /* § 10.5.5.10: */
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200550 acreq->imeisv_req = 0x1;
Maxb997f842016-07-06 15:57:01 +0200551 /* § 10.5.5.7: */
552 acreq->force_stby = force_standby;
Max4011e722016-07-05 15:19:12 +0200553 /* 3GPP TS 24.008 § 10.5.5.19: */
554 if (RAND_bytes(&rbyte, 1) != 1) {
555 LOGP(DMM, LOGL_NOTICE, "RAND_bytes failed for A&C ref, falling "
556 "back to rand()\n");
557 acreq->ac_ref_nr = rand();
558 } else
559 acreq->ac_ref_nr = rbyte;
560 mm->ac_ref_nr_used = acreq->ac_ref_nr;
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200561
562 /* Only if authentication is requested we need to set RAND + CKSN */
Max4011e722016-07-05 15:19:12 +0200563 if (rnd) {
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200564 m_rand = msgb_put(msg, 16+1);
565 m_rand[0] = GSM48_IE_GMM_AUTH_RAND;
Max4011e722016-07-05 15:19:12 +0200566 memcpy(m_rand + 1, rnd, 16);
Maxb997f842016-07-06 15:57:01 +0200567 /* § 10.5.1.2: */
Jacob Erlbeck65d82732014-12-01 10:36:17 +0100568 m_cksn = msgb_put(msg, 1);
569 m_cksn[0] = (GSM48_IE_GMM_CIPH_CKSN << 4) | (key_seq & 0x07);
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200570 }
Maxb997f842016-07-06 15:57:01 +0200571 /* FIXME: add AUTN for 3g auth according to 3GPP TS 24.008 § 10.5.3.1.1 */
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200572 /* FIXME: make sure we don't send any other messages to the MS */
573
Max82040102016-07-06 11:59:18 +0200574 return gsm48_gmm_sendmsg(msg, 1, mm, false);
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200575}
576
577/* Section 9.4.11: Authentication and Ciphering Reject */
578static int gsm48_tx_gmm_auth_ciph_rej(struct sgsn_mm_ctx *mm)
579{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +0100580 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 AUTH CIPH REJ");
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200581 struct gsm48_hdr *gh;
582
Daniel Willmann46553142014-09-03 17:46:44 +0200583 LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS AUTH AND CIPH REJECT\n");
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200584
585 mmctx2msgid(msg, mm);
586
587 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
588 gh->proto_discr = GSM48_PDISC_MM_GPRS;
589 gh->msg_type = GSM48_MT_GMM_AUTH_CIPH_REJ;
590
Max82040102016-07-06 11:59:18 +0200591 return gsm48_gmm_sendmsg(msg, 0, mm, false);
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200592}
593
594/* Section 9.4.10: Authentication and Ciphering Response */
595static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx,
596 struct msgb *msg)
597{
598 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
599 struct gsm48_auth_ciph_resp *acr = (struct gsm48_auth_ciph_resp *)gh->data;
600 struct tlv_parsed tp;
Jacob Erlbeck8ff3fb02014-12-01 12:44:24 +0100601 struct gsm_auth_tuple *at;
602 int rc;
603
604 LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS AUTH AND CIPH RESPONSE\n");
605
606 if (ctx->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) {
607 LOGMMCTXP(LOGL_NOTICE, ctx,
608 "Unexpected Auth & Ciph Response (ignored)\n");
609 return 0;
610 }
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200611
Max4011e722016-07-05 15:19:12 +0200612 if (acr->ac_ref_nr != ctx->ac_ref_nr_used) {
613 LOGMMCTXP(LOGL_NOTICE, ctx, "Reference mismatch for Auth & Ciph"
614 " Response: %u received, %u expected\n",
615 acr->ac_ref_nr, ctx->ac_ref_nr_used);
616 return 0;
617 }
618
Jacob Erlbeckbd0cf112014-12-01 12:33:33 +0100619 /* Stop T3360 */
620 mmctx_timer_stop(ctx, 3360);
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200621
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +0200622 tlv_parse(&tp, &gsm48_gmm_att_tlvdef, acr->data,
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200623 (msg->data + msg->len) - acr->data, 0, 0);
624
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200625 if (!TLVP_PRESENT(&tp, GSM48_IE_GMM_AUTH_SRES) ||
626 !TLVP_PRESENT(&tp, GSM48_IE_GMM_IMEISV)) {
Jacob Erlbeck8ff3fb02014-12-01 12:44:24 +0100627 /* TODO: missing mandatory IE, return STATUS or REJ? */
628 LOGMMCTXP(LOGL_ERROR, ctx, "Missing mandantory IE\n");
629 return -EINVAL;
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200630 }
631
Jacob Erlbeck8ff3fb02014-12-01 12:44:24 +0100632 /* Compare SRES with what we expected */
633 LOGMMCTXP(LOGL_DEBUG, ctx, "checking received auth info, SRES = %s\n",
634 osmo_hexdump(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES),
635 TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES)));
636
637 at = &ctx->auth_triplet;
638
Harald Welte121e9a42016-04-20 13:13:19 +0200639 if (TLVP_LEN(&tp, GSM48_IE_GMM_AUTH_SRES) != sizeof(at->vec.sres) ||
640 memcmp(TLVP_VAL(&tp, GSM48_IE_GMM_AUTH_SRES), at->vec.sres,
641 sizeof(at->vec.sres)) != 0) {
Jacob Erlbeck8ff3fb02014-12-01 12:44:24 +0100642
643 LOGMMCTXP(LOGL_NOTICE, ctx, "Received SRES doesn't match\n");
644 rc = gsm48_tx_gmm_auth_ciph_rej(ctx);
645 mm_ctx_cleanup_free(ctx, "GPRS AUTH AND CIPH REJECT");
646 return rc;
647 }
648
649 ctx->is_authenticated = 1;
650
Daniel Willmann3ecfbbb2016-05-21 00:16:55 +0200651 if (ctx->ran_type == MM_CTX_T_UTRAN_Iu)
652 ctx->iu.new_key = 1;
653
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200654 /* FIXME: enable LLC cipheirng */
Jacob Erlbeck4adb1362014-12-02 09:47:26 +0100655
656 /* Check if we can let the mobile station enter */
657 return gsm48_gmm_authorize(ctx);
Harald Welte4b6ac1e2010-07-03 11:09:06 +0200658}
659
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +0200660static void extract_subscr_msisdn(struct sgsn_mm_ctx *ctx)
661{
662 struct gsm_mncc_number called;
663 uint8_t msisdn[sizeof(ctx->subscr->sgsn_data->msisdn) + 1];
664
665 /* Convert MSISDN from encoded to string.. */
666 if (!ctx->subscr)
667 return;
668
669 if (ctx->subscr->sgsn_data->msisdn_len < 1)
670 return;
671
672 /* prepare the data for the decoder */
673 memset(&called, 0, sizeof(called));
674 msisdn[0] = ctx->subscr->sgsn_data->msisdn_len;
675 memcpy(&msisdn[1], ctx->subscr->sgsn_data->msisdn,
676 ctx->subscr->sgsn_data->msisdn_len);
677
678 /* decode the string now */
679 gsm48_decode_called(&called, msisdn);
680
681 /* Prepend a '+' for international numbers */
682 if (called.plan == 1 && called.type == 1) {
683 ctx->msisdn[0] = '+';
684 strncpy(&ctx->msisdn[1], called.number,
685 sizeof(ctx->msisdn) - 1);
686 } else {
687 strncpy(&ctx->msisdn[0], called.number,
688 sizeof(ctx->msisdn) - 1);
689 }
690}
691
Holger Hans Peter Freyther8ee13e22015-05-18 10:00:03 +0200692static void extract_subscr_hlr(struct sgsn_mm_ctx *ctx)
693{
694 struct gsm_mncc_number called;
695 uint8_t hlr_number[sizeof(ctx->subscr->sgsn_data->hlr) + 1];
696
697 if (!ctx->subscr)
698 return;
699
700 if (ctx->subscr->sgsn_data->hlr_len < 1)
701 return;
702
703 /* prepare the data for the decoder */
704 memset(&called, 0, sizeof(called));
705 hlr_number[0] = ctx->subscr->sgsn_data->hlr_len;
706 memcpy(&hlr_number[1], ctx->subscr->sgsn_data->hlr,
707 ctx->subscr->sgsn_data->hlr_len);
708
709 /* decode the string now */
710 gsm48_decode_called(&called, hlr_number);
711
712 if (called.plan != 1) {
713 LOGMMCTXP(LOGL_ERROR, ctx,
714 "Numbering plan(%d) not allowed\n",
715 called.plan);
716 return;
717 }
718
719 if (called.type != 1) {
720 LOGMMCTXP(LOGL_ERROR, ctx,
721 "Numbering type(%d) not allowed\n",
722 called.type);
723 return;
724 }
725
726 strncpy(&ctx->hlr[0], called.number, sizeof(ctx->hlr) - 1);
727}
728
Daniel Willmann1dee2b62016-05-21 00:15:29 +0200729#ifdef BUILD_IU
730/* Chapter 9.4.21: Service accept */
731static int gsm48_tx_gmm_service_ack(struct sgsn_mm_ctx *mm)
732{
733 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE ACK");
734 struct gsm48_hdr *gh;
735
736 LOGMMCTXP(LOGL_INFO, mm, "<- GPRS SERVICE ACCEPT (P-TMSI=0x%08x)\n", mm->p_tmsi);
737
738 mmctx2msgid(msg, mm);
739
740 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
741 gh->proto_discr = GSM48_PDISC_MM_GPRS;
742 gh->msg_type = GSM48_MT_GMM_SERVICE_ACK;
743
744 /* Optional: PDP context status */
745 /* Optional: MBMS context status */
746
747 return gsm48_gmm_sendmsg(msg, 0, mm, false);
748}
749#endif
750
751/* Chapter 9.4.22: Service reject */
752static int _tx_gmm_service_rej(struct msgb *msg, uint8_t gmm_cause,
753 const struct sgsn_mm_ctx *mm)
754{
755 struct gsm48_hdr *gh;
756
757 LOGMMCTXP(LOGL_NOTICE, mm, "<- GPRS SERVICE REJECT: %s\n",
758 get_value_string(gsm48_gmm_cause_names, gmm_cause));
759
760 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
761 gh->proto_discr = GSM48_PDISC_MM_GPRS;
762 gh->msg_type = GSM48_MT_GMM_SERVICE_REJ;
763 gh->data[0] = gmm_cause;
764
765 return gsm48_gmm_sendmsg(msg, 0, NULL, true);
766}
767static int gsm48_tx_gmm_service_rej_oldmsg(const struct msgb *old_msg,
768 uint8_t gmm_cause)
769{
770 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ OLD");
771 gmm_copy_id(msg, old_msg);
772 return _tx_gmm_service_rej(msg, gmm_cause, NULL);
773}
774#if 0
775-- currently unused --
776static int gsm48_tx_gmm_service_rej(struct sgsn_mm_ctx *mm,
777 uint8_t gmm_cause)
778{
779 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERVICE REJ");
780 mmctx2msgid(msg, mm);
781 return _tx_gmm_service_rej(msg, gmm_cause, mm);
782}
783#endif
784
785static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm);
786
787#ifdef BUILD_IU
788void activate_pdp_rabs(struct sgsn_mm_ctx *ctx)
789{
790 /* Send RAB activation requests for all PDP contexts */
791 struct sgsn_pdp_ctx *pdp;
792 llist_for_each_entry(pdp, &ctx->pdp_list, list) {
793 iu_rab_act_ps(pdp->nsapi, pdp, 1);
794 }
795}
796#endif
797
Harald Welte9b455bf2010-03-14 15:45:01 +0800798/* Check if we can already authorize a subscriber */
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100799static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
Harald Welte9b455bf2010-03-14 15:45:01 +0800800{
Daniel Willmann3ecfbbb2016-05-21 00:16:55 +0200801#ifdef BUILD_IU
802 int rc;
803#endif
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +0200804#ifndef PTMSI_ALLOC
805 struct sgsn_signal_data sig_data;
806#endif
807
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100808 /* Request IMSI and IMEI from the MS if they are unknown */
Harald Weltec2e8cc42010-05-31 20:23:38 +0200809 if (!strlen(ctx->imei)) {
Harald Weltec2e8cc42010-05-31 20:23:38 +0200810 ctx->t3370_id_type = GSM_MI_TYPE_IMEI;
Harald Welte94508822015-08-15 19:08:21 +0200811 mmctx_timer_start(ctx, 3370, sgsn->cfg.timers.T3370);
Harald Welte6463c072010-05-18 17:04:55 +0200812 return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMEI);
Harald Weltec2e8cc42010-05-31 20:23:38 +0200813 }
Harald Weltec2e8cc42010-05-31 20:23:38 +0200814 if (!strlen(ctx->imsi)) {
Harald Weltec2e8cc42010-05-31 20:23:38 +0200815 ctx->t3370_id_type = GSM_MI_TYPE_IMSI;
Harald Welte94508822015-08-15 19:08:21 +0200816 mmctx_timer_start(ctx, 3370, sgsn->cfg.timers.T3370);
Harald Welte6463c072010-05-18 17:04:55 +0200817 return gsm48_tx_gmm_id_req(ctx, GSM_MI_TYPE_IMSI);
Harald Weltec2e8cc42010-05-31 20:23:38 +0200818 }
Harald Welte9b455bf2010-03-14 15:45:01 +0800819
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100820 /* All information required for authentication is available */
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100821 ctx->t3370_id_type = GSM_MI_TYPE_NONE;
822
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200823 if (ctx->auth_state == SGSN_AUTH_UNKNOWN) {
824 /* Request authorization, this leads to a call to
Jacob Erlbeckf951a012014-11-07 14:17:44 +0100825 * sgsn_auth_update which in turn calls
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200826 * gsm0408_gprs_access_granted or gsm0408_gprs_access_denied */
827
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +0100828 sgsn_auth_request(ctx);
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200829 /* Note that gsm48_gmm_authorize can be called recursively via
830 * sgsn_auth_request iff ctx->auth_info changes to AUTH_ACCEPTED
831 */
832 return 0;
833 }
834
Jacob Erlbeck4adb1362014-12-02 09:47:26 +0100835 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && !ctx->is_authenticated) {
836 struct gsm_auth_tuple *at = &ctx->auth_triplet;
837
Harald Welte94508822015-08-15 19:08:21 +0200838 mmctx_timer_start(ctx, 3360, sgsn->cfg.timers.T3360);
Harald Welte121e9a42016-04-20 13:13:19 +0200839 return gsm48_tx_gmm_auth_ciph_req(ctx, at->vec.rand,
Maxb997f842016-07-06 15:57:01 +0200840 at->key_seq, false);
Jacob Erlbeck4adb1362014-12-02 09:47:26 +0100841 }
842
843 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && ctx->is_authenticated &&
844 ctx->auth_triplet.key_seq != GSM_KEY_SEQ_INVAL) {
845 /* Check again for authorization */
846 sgsn_auth_request(ctx);
847 return 0;
848 }
849
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200850 if (ctx->auth_state != SGSN_AUTH_ACCEPTED) {
851 LOGMMCTXP(LOGL_NOTICE, ctx,
852 "authorization is denied, aborting procedure\n");
853 return -EACCES;
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100854 }
855
856 /* The MS is authorized */
Daniel Willmann3ecfbbb2016-05-21 00:16:55 +0200857#ifdef BUILD_IU
858 if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && !ctx->iu.ue_ctx->integrity_active) {
859 rc = iu_tx_sec_mode_cmd(ctx->iu.ue_ctx, &ctx->auth_triplet, 0, ctx->iu.new_key);
860 ctx->iu.new_key = 0;
861 return rc;
862 }
863#endif
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100864
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100865 switch (ctx->pending_req) {
866 case 0:
867 LOGMMCTXP(LOGL_INFO, ctx,
868 "no pending request, authorization completed\n");
869 break;
870 case GSM48_MT_GMM_ATTACH_REQ:
Daniel Willmannfac97582016-05-21 00:21:15 +0200871 ctx->pending_req = 0;
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +0200872
873 extract_subscr_msisdn(ctx);
Holger Hans Peter Freyther8ee13e22015-05-18 10:00:03 +0200874 extract_subscr_hlr(ctx);
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100875#ifdef PTMSI_ALLOC
876 /* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */
Harald Welte94508822015-08-15 19:08:21 +0200877 mmctx_timer_start(ctx, 3350, sgsn->cfg.timers.T3350);
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100878 ctx->t3350_mode = GMM_T3350_MODE_ATT;
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100879#else
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +0200880 memset(&sig_data, 0, sizeof(sig_data));
881 sig_data.mm = mmctx;
882 osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data);
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100883 ctx->mm_state = GMM_REGISTERED_NORMAL;
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100884#endif
885
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100886 return gsm48_tx_gmm_att_ack(ctx);
Daniel Willmann1dee2b62016-05-21 00:15:29 +0200887#ifdef BUILD_IU
888 case GSM48_MT_GMM_SERVICE_REQ:
Daniel Willmann1dee2b62016-05-21 00:15:29 +0200889 ctx->pending_req = 0;
Daniel Willmannc17cdb42016-05-11 12:42:54 +0200890 mmctx_set_pmm_state(ctx, PMM_CONNECTED);
Daniel Willmann1dee2b62016-05-21 00:15:29 +0200891 rc = gsm48_tx_gmm_service_ack(ctx);
892
Daniel Willmannaf241722016-05-21 00:35:41 +0200893 if (ctx->iu.service.type != GPRS_SERVICE_T_SIGNALLING)
Daniel Willmann1dee2b62016-05-21 00:15:29 +0200894 activate_pdp_rabs(ctx);
Daniel Willmann1dee2b62016-05-21 00:15:29 +0200895
896 return rc;
897#endif
898 case GSM48_MT_GMM_RA_UPD_REQ:
899 ctx->pending_req = 0;
900 /* Send RA UPDATE ACCEPT */
901 return gsm48_tx_gmm_ra_upd_ack(ctx);
902
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +0100903 default:
904 LOGMMCTXP(LOGL_ERROR, ctx,
905 "only Attach Request is supported yet, "
906 "got request type %u\n", ctx->pending_req);
907 break;
908 }
909
Harald Welte9b455bf2010-03-14 15:45:01 +0800910 return 0;
911}
912
Jacob Erlbeck4adb1362014-12-02 09:47:26 +0100913void gsm0408_gprs_authenticate(struct sgsn_mm_ctx *ctx)
914{
915 ctx->is_authenticated = 0;
916
917 gsm48_gmm_authorize(ctx);
918}
919
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200920void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *ctx)
921{
922 switch (ctx->mm_state) {
923 case GMM_COMMON_PROC_INIT:
Harald Welteeb98c742015-08-16 17:11:32 +0200924 LOGMMCTXP(LOGL_NOTICE, ctx,
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200925 "Authorized, continuing procedure, IMSI=%s\n",
926 ctx->imsi);
927 /* Continue with the authorization */
928 gsm48_gmm_authorize(ctx);
929 break;
930 default:
Harald Welteeb98c742015-08-16 17:11:32 +0200931 LOGMMCTXP(LOGL_INFO, ctx,
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200932 "Authorized, ignored, IMSI=%s\n",
933 ctx->imsi);
934 }
935}
936
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +0100937void gsm0408_gprs_access_denied(struct sgsn_mm_ctx *ctx, int gmm_cause)
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200938{
Jacob Erlbeckd6267d12015-01-19 11:10:04 +0100939 if (gmm_cause == SGSN_ERROR_CAUSE_NONE)
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +0100940 gmm_cause = GMM_CAUSE_GPRS_NOTALLOWED;
941
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200942 switch (ctx->mm_state) {
943 case GMM_COMMON_PROC_INIT:
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +0100944 LOGMMCTXP(LOGL_NOTICE, ctx,
945 "Not authorized, rejecting ATTACH REQUEST "
946 "with cause '%s' (%d)\n",
947 get_value_string(gsm48_gmm_cause_names, gmm_cause),
948 gmm_cause);
949 gsm48_tx_gmm_att_rej(ctx, gmm_cause);
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200950 mm_ctx_cleanup_free(ctx, "GPRS ATTACH REJECT");
951 break;
952 case GMM_REGISTERED_NORMAL:
953 case GMM_REGISTERED_SUSPENDED:
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +0100954 LOGMMCTXP(LOGL_NOTICE, ctx,
955 "Authorization lost, detaching "
956 "with cause '%s' (%d)\n",
957 get_value_string(gsm48_gmm_cause_names, gmm_cause),
958 gmm_cause);
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200959 gsm48_tx_gmm_detach_req(
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +0100960 ctx, GPRS_DET_T_MT_REATT_NOTREQ, gmm_cause);
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200961
962 mm_ctx_cleanup_free(ctx, "auth lost");
963 break;
964 default:
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +0100965 LOGMMCTXP(LOGL_INFO, ctx,
966 "Authorization lost, cause is '%s' (%d)\n",
967 get_value_string(gsm48_gmm_cause_names, gmm_cause),
968 gmm_cause);
969 mm_ctx_cleanup_free(ctx, "auth lost");
Jacob Erlbeck423f8bf2014-10-24 18:09:54 +0200970 }
971}
972
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +0100973void gsm0408_gprs_access_cancelled(struct sgsn_mm_ctx *ctx, int gmm_cause)
Jacob Erlbeck98647ca2014-11-11 14:47:38 +0100974{
Jacob Erlbeckd6267d12015-01-19 11:10:04 +0100975 if (gmm_cause != SGSN_ERROR_CAUSE_NONE) {
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +0100976 LOGMMCTXP(LOGL_INFO, ctx,
977 "Cancelled with cause '%s' (%d), deleting context\n",
978 get_value_string(gsm48_gmm_cause_names, gmm_cause),
979 gmm_cause);
980 gsm0408_gprs_access_denied(ctx, gmm_cause);
981 return;
Jacob Erlbeck98647ca2014-11-11 14:47:38 +0100982 }
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +0100983
984 LOGMMCTXP(LOGL_INFO, ctx, "Cancelled, deleting context silently\n");
Jacob Erlbeck98647ca2014-11-11 14:47:38 +0100985 mm_ctx_cleanup_free(ctx, "access cancelled");
986}
987
Harald Welte9b455bf2010-03-14 15:45:01 +0800988/* Parse Chapter 9.4.13 Identity Response */
Harald Welted193cb32010-05-17 22:58:03 +0200989static int gsm48_rx_gmm_id_resp(struct sgsn_mm_ctx *ctx, struct msgb *msg)
Harald Welte9b455bf2010-03-14 15:45:01 +0800990{
Harald Welte943c5bc2010-04-30 16:33:12 +0200991 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Harald Welteeaa614c2010-05-02 11:26:34 +0200992 uint8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK;
Harald Welte9b455bf2010-03-14 15:45:01 +0800993 char mi_string[GSM48_MI_SIZE];
Harald Welte9b455bf2010-03-14 15:45:01 +0800994
995 gsm48_mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]);
Harald Welte9b455bf2010-03-14 15:45:01 +0800996 if (!ctx) {
Daniel Willmann46553142014-09-03 17:46:44 +0200997 DEBUGP(DMM, "from unknown TLLI 0x%08x?!? This should not happen\n", msgb_tlli(msg));
Harald Welte9b455bf2010-03-14 15:45:01 +0800998 return -EINVAL;
999 }
1000
Harald Welteb9845f92015-08-16 18:07:48 +02001001 LOGMMCTXP(LOGL_DEBUG, ctx, "-> GMM IDENTITY RESPONSE: MI(%s)=%s\n",
1002 gsm48_mi_type_name(mi_type), mi_string);
Daniel Willmannf8070f42014-09-23 18:48:44 +02001003
Jacob Erlbeckfb26c602014-10-22 12:20:26 +02001004 if (ctx->t3370_id_type == GSM_MI_TYPE_NONE) {
1005 LOGMMCTXP(LOGL_NOTICE, ctx,
Harald Welteb9845f92015-08-16 18:07:48 +02001006 "Got unexpected IDENTITY RESPONSE: MI(%s)=%s, "
Jacob Erlbeckfb26c602014-10-22 12:20:26 +02001007 "ignoring message\n",
Harald Welteb9845f92015-08-16 18:07:48 +02001008 gsm48_mi_type_name(mi_type), mi_string);
Jacob Erlbeckfb26c602014-10-22 12:20:26 +02001009 return -EINVAL;
1010 }
1011
Harald Weltec2e8cc42010-05-31 20:23:38 +02001012 if (mi_type == ctx->t3370_id_type)
1013 mmctx_timer_stop(ctx, 3370);
1014
Harald Welte9b455bf2010-03-14 15:45:01 +08001015 switch (mi_type) {
1016 case GSM_MI_TYPE_IMSI:
1017 /* we already have a mm context with current TLLI, but no
1018 * P-TMSI / IMSI yet. What we now need to do is to fill
1019 * this initial context with data from the HLR */
Harald Weltec728eea2010-12-24 23:07:18 +01001020 if (strlen(ctx->imsi) == 0) {
1021 /* Check if we already have a MM context for this IMSI */
1022 struct sgsn_mm_ctx *ictx;
1023 ictx = sgsn_mm_ctx_by_imsi(mi_string);
1024 if (ictx) {
Jacob Erlbeck99985b52014-10-13 10:32:00 +02001025 /* Handle it like in gsm48_rx_gmm_det_req,
1026 * except that no messages are sent to the BSS */
1027
Daniel Willmann46553142014-09-03 17:46:44 +02001028 LOGMMCTXP(LOGL_NOTICE, ctx, "Deleting old MM Context for same IMSI "
1029 "p_tmsi_old=0x%08x\n",
1030 ictx->p_tmsi);
Jacob Erlbeck99985b52014-10-13 10:32:00 +02001031
Jacob Erlbeck99985b52014-10-13 10:32:00 +02001032 mm_ctx_cleanup_free(ictx, "GPRS IMSI re-use");
Harald Weltec728eea2010-12-24 23:07:18 +01001033 }
1034 }
Jacob Erlbeck496aee72015-01-26 10:38:12 +01001035 strncpy(ctx->imsi, mi_string, sizeof(ctx->imsi) - 1);
Harald Welte9b455bf2010-03-14 15:45:01 +08001036 break;
1037 case GSM_MI_TYPE_IMEI:
Jacob Erlbeck496aee72015-01-26 10:38:12 +01001038 strncpy(ctx->imei, mi_string, sizeof(ctx->imei) - 1);
Harald Welte9b455bf2010-03-14 15:45:01 +08001039 break;
1040 case GSM_MI_TYPE_IMEISV:
1041 break;
1042 }
1043
Harald Welte9b455bf2010-03-14 15:45:01 +08001044 /* Check if we can let the mobile station enter */
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +01001045 return gsm48_gmm_authorize(ctx);
Harald Welte9b455bf2010-03-14 15:45:01 +08001046}
1047
1048/* Section 9.4.1 Attach request */
Harald Welte807a5d82010-06-01 11:53:01 +02001049static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
1050 struct gprs_llc_llme *llme)
Harald Welte9b455bf2010-03-14 15:45:01 +08001051{
Harald Welte943c5bc2010-04-30 16:33:12 +02001052 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +02001053 uint8_t *cur = gh->data, *msnc, *mi, *ms_ra_acc_cap;
Harald Welte56a01452010-05-31 22:12:30 +02001054 uint8_t msnc_len, att_type, mi_len, mi_type, ms_ra_acc_cap_len;
Harald Welteeaa614c2010-05-02 11:26:34 +02001055 uint16_t drx_par;
1056 uint32_t tmsi;
Harald Welte9b455bf2010-03-14 15:45:01 +08001057 char mi_string[GSM48_MI_SIZE];
1058 struct gprs_ra_id ra_id;
Daniel Willmann61329d42016-05-21 17:36:18 +02001059 uint16_t cid = 0;
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001060 enum gsm48_gmm_cause reject_cause;
1061 int rc;
Harald Welte9b455bf2010-03-14 15:45:01 +08001062
Harald Welteeb98c742015-08-16 17:11:32 +02001063 LOGMMCTXP(LOGL_INFO, ctx, "-> GMM ATTACH REQUEST ");
Alexander Couzens14314bd2016-07-05 09:52:52 +02001064 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ATTACH_REQUEST]);
Harald Welte9b455bf2010-03-14 15:45:01 +08001065
1066 /* As per TS 04.08 Chapter 4.7.1.4, the attach request arrives either
1067 * with a foreign TLLI (P-TMSI that was allocated to the MS before),
1068 * or with random TLLI. */
1069
Daniel Willmann61329d42016-05-21 17:36:18 +02001070 /* In Iu mode, msg->dst contains the ue_conn_ctx pointer, in Gb mode
1071 * dst is empty. */
1072 /* FIXME: have a more explicit indicator for Iu messages */
1073 if (!msg->dst) {
1074 /* Gb mode */
1075 cid = bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
Neels Hofmeyreb52aad2016-11-26 13:37:55 +01001076 } else
1077 ra_id = ((struct ue_conn_ctx*)msg->dst)->ra_id;
Harald Welte9b455bf2010-03-14 15:45:01 +08001078
1079 /* MS network capability 10.5.5.12 */
1080 msnc_len = *cur++;
1081 msnc = cur;
Alexander Chemeris84402c02013-07-03 10:12:23 +04001082 if (msnc_len > sizeof(ctx->ms_network_capa.buf))
Harald Welte9b455bf2010-03-14 15:45:01 +08001083 goto err_inval;
1084 cur += msnc_len;
1085
Daniel Willmann746c7892016-01-25 16:49:53 +01001086 /* TODO: In iu mode - handle follow-on request */
1087
Harald Welte9b455bf2010-03-14 15:45:01 +08001088 /* aTTACH Type 10.5.5.2 */
Daniel Willmann746c7892016-01-25 16:49:53 +01001089 att_type = *cur++ & 0x07;
Harald Welte9b455bf2010-03-14 15:45:01 +08001090
1091 /* DRX parameter 10.5.5.6 */
Harald Welte56a01452010-05-31 22:12:30 +02001092 drx_par = *cur++ << 8;
1093 drx_par |= *cur++;
Harald Welte9b455bf2010-03-14 15:45:01 +08001094
1095 /* Mobile Identity (P-TMSI or IMSI) 10.5.1.4 */
1096 mi_len = *cur++;
1097 mi = cur;
1098 if (mi_len > 8)
1099 goto err_inval;
1100 mi_type = *mi & GSM_MI_TYPE_MASK;
1101 cur += mi_len;
1102
1103 gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
1104
Harald Welte2720e732010-05-17 00:44:57 +02001105 DEBUGPC(DMM, "MI(%s) type=\"%s\" ", mi_string,
1106 get_value_string(gprs_att_t_strs, att_type));
Harald Welte9b455bf2010-03-14 15:45:01 +08001107
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +02001108 /* Old routing area identification 10.5.5.15. Skip it */
Harald Welte9b455bf2010-03-14 15:45:01 +08001109 cur += 6;
1110
1111 /* MS Radio Access Capability 10.5.5.12a */
Harald Welte56a01452010-05-31 22:12:30 +02001112 ms_ra_acc_cap_len = *cur++;
1113 ms_ra_acc_cap = cur;
Alexander Chemeris84402c02013-07-03 10:12:23 +04001114 if (ms_ra_acc_cap_len > sizeof(ctx->ms_radio_access_capa.buf))
Harald Weltec48ac472010-07-03 21:20:06 +02001115 goto err_inval;
Harald Welte4b2ed352011-07-27 23:35:38 +02001116 cur += ms_ra_acc_cap_len;
Harald Welte9b455bf2010-03-14 15:45:01 +08001117
Daniel Willmann46553142014-09-03 17:46:44 +02001118 LOGPC(DMM, LOGL_INFO, "\n");
1119
Harald Welte9b455bf2010-03-14 15:45:01 +08001120 /* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status */
1121
1122 switch (mi_type) {
1123 case GSM_MI_TYPE_IMSI:
1124 /* Try to find MM context based on IMSI */
Harald Welte807a5d82010-06-01 11:53:01 +02001125 if (!ctx)
1126 ctx = sgsn_mm_ctx_by_imsi(mi_string);
Harald Welte9b455bf2010-03-14 15:45:01 +08001127 if (!ctx) {
1128#if 0
1129 return gsm48_tx_gmm_att_rej(msg, GMM_CAUSE_IMSI_UNKNOWN);
1130#else
Daniel Willmann61329d42016-05-21 17:36:18 +02001131 if (msg->dst)
1132 ctx = sgsn_mm_ctx_alloc_iu(msg->dst);
1133 else
1134 ctx = sgsn_mm_ctx_alloc(0, &ra_id);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001135 if (!ctx) {
1136 reject_cause = GMM_CAUSE_NET_FAIL;
1137 goto rejected;
1138 }
Jacob Erlbeck496aee72015-01-26 10:38:12 +01001139 strncpy(ctx->imsi, mi_string, sizeof(ctx->imsi) - 1);
Harald Welte9b455bf2010-03-14 15:45:01 +08001140#endif
1141 }
Harald Weltedbc72b32015-12-25 22:23:27 +01001142 if (ctx->ran_type == MM_CTX_T_GERAN_Gb) {
1143 ctx->gb.tlli = msgb_tlli(msg);
1144 ctx->gb.llme = llme;
1145 }
Harald Welte68b99a42010-05-18 12:05:42 +02001146 msgid2mmctx(ctx, msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08001147 break;
1148 case GSM_MI_TYPE_TMSI:
Harald Welteab1d5622010-05-18 19:58:38 +02001149 memcpy(&tmsi, mi+1, 4);
1150 tmsi = ntohl(tmsi);
Harald Welte9b455bf2010-03-14 15:45:01 +08001151 /* Try to find MM context based on P-TMSI */
Harald Welte807a5d82010-06-01 11:53:01 +02001152 if (!ctx)
1153 ctx = sgsn_mm_ctx_by_ptmsi(tmsi);
Harald Welte9b455bf2010-03-14 15:45:01 +08001154 if (!ctx) {
Harald Weltec728eea2010-12-24 23:07:18 +01001155 /* Allocate a context as most of our code expects one.
1156 * Context will not have an IMSI ultil ID RESP is received */
Daniel Willmann61329d42016-05-21 17:36:18 +02001157 if (msg->dst)
1158 ctx = sgsn_mm_ctx_alloc_iu(msg->dst);
1159 else
1160 ctx = sgsn_mm_ctx_alloc(msgb_tlli(msg), &ra_id);
Harald Welte807a5d82010-06-01 11:53:01 +02001161 ctx->p_tmsi = tmsi;
Harald Welte9b455bf2010-03-14 15:45:01 +08001162 }
Harald Weltedbc72b32015-12-25 22:23:27 +01001163 if (ctx->ran_type == MM_CTX_T_GERAN_Gb) {
1164 ctx->gb.tlli = msgb_tlli(msg);
1165 ctx->gb.llme = llme;
1166 }
Harald Welte807a5d82010-06-01 11:53:01 +02001167 msgid2mmctx(ctx, msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08001168 break;
1169 default:
Harald Welteeb98c742015-08-16 17:11:32 +02001170 LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting ATTACH REQUEST with "
Harald Welteb9845f92015-08-16 18:07:48 +02001171 "MI type %s\n", gsm48_mi_type_name(mi_type));
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001172 reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED;
1173 goto rejected;
Harald Welte9b455bf2010-03-14 15:45:01 +08001174 }
Harald Welte9f1f3ad2010-05-02 12:56:57 +02001175 /* Update MM Context with currient RA and Cell ID */
1176 ctx->ra = ra_id;
Harald Weltedbc72b32015-12-25 22:23:27 +01001177 if (ctx->ran_type == MM_CTX_T_GERAN_Gb)
1178 ctx->gb.cell_id = cid;
Daniel Willmann770f3e32016-05-21 00:31:12 +02001179 else if (ctx->ran_type == MM_CTX_T_UTRAN_Iu) {
1180 /* DEVELOPMENT HACK: Our current HLR does not support 3G
1181 * authentication tokens. A new HLR/VLR implementation is being
1182 * developed. Until it is ready and actual milenage
1183 * authentication is properly supported, we are hardcoding a
1184 * fixed Ki and use 2G auth. */
1185 unsigned char tmp_rand[16];
1186 /* Ki 000102030405060708090a0b0c0d0e0f */
1187 struct osmo_sub_auth_data auth = {
1188 .type = OSMO_AUTH_TYPE_GSM,
1189 .algo = OSMO_AUTH_ALG_COMP128v1,
1190 .u.gsm.ki = {
1191 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1192 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
1193 0x0e, 0x0f
1194 },
1195 };
1196 /* XXX: Hack to make 3G auth work with special SIM card */
1197 ctx->auth_state = SGSN_AUTH_AUTHENTICATE;
1198
1199 RAND_bytes(tmp_rand, 16);
1200
1201 memset(&ctx->auth_triplet.vec, 0, sizeof(ctx->auth_triplet.vec));
1202 osmo_auth_gen_vec(&ctx->auth_triplet.vec, &auth, tmp_rand);
1203
1204 ctx->auth_triplet.key_seq = 0;
1205 }
1206
Harald Welte56a01452010-05-31 22:12:30 +02001207 /* Update MM Context with other data */
1208 ctx->drx_parms = drx_par;
Alexander Chemeris84402c02013-07-03 10:12:23 +04001209 ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len;
Harald Welte4b2ed352011-07-27 23:35:38 +02001210 memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap,
1211 ctx->ms_radio_access_capa.len);
Harald Welte56a01452010-05-31 22:12:30 +02001212 ctx->ms_network_capa.len = msnc_len;
1213 memcpy(ctx->ms_network_capa.buf, msnc, msnc_len);
Maxb997f842016-07-06 15:57:01 +02001214 if (!gprs_ms_net_cap_gea_supported(ctx->ms_network_capa.buf, msnc_len,
1215 ctx->ciph_algo)) {
1216 reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
1217 LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting ATTACH REQUEST with MI "
1218 "type %s because MS do not support required %s "
1219 "encryption\n", gsm48_mi_type_name(mi_type),
1220 get_value_string(gprs_cipher_names,ctx->ciph_algo));
1221 goto rejected;
1222 }
Harald Weltec2e8cc42010-05-31 20:23:38 +02001223#ifdef PTMSI_ALLOC
Harald Welte807a5d82010-06-01 11:53:01 +02001224 /* Allocate a new P-TMSI (+ P-TMSI signature) and update TLLI */
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001225 /* Don't change the P-TMSI if a P-TMSI re-assignment is under way */
1226 if (ctx->mm_state != GMM_COMMON_PROC_INIT) {
1227 ctx->p_tmsi_old = ctx->p_tmsi;
1228 ctx->p_tmsi = sgsn_alloc_ptmsi();
1229 }
Jacob Erlbeck0074a772014-10-28 16:23:46 +01001230 ctx->mm_state = GMM_COMMON_PROC_INIT;
Harald Welteab1d5622010-05-18 19:58:38 +02001231#endif
Harald Welte807a5d82010-06-01 11:53:01 +02001232
Harald Weltedbc72b32015-12-25 22:23:27 +01001233 if (ctx->ran_type == MM_CTX_T_GERAN_Gb) {
1234 /* Even if there is no P-TMSI allocated, the MS will
1235 * switch from foreign TLLI to local TLLI */
1236 ctx->gb.tlli_new = gprs_tmsi2tlli(ctx->p_tmsi, TLLI_LOCAL);
1237
1238 /* Inform LLC layer about new TLLI but keep old active */
Max5aa51962016-07-06 11:33:04 +02001239 if (ctx->is_authenticated)
1240 gprs_llme_copy_key(ctx, ctx->gb.llme);
1241
1242 gprs_llgmm_assign(ctx->gb.llme, ctx->gb.tlli, ctx->gb.tlli_new);
Harald Weltedbc72b32015-12-25 22:23:27 +01001243 }
Harald Welte9b455bf2010-03-14 15:45:01 +08001244
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +01001245 ctx->pending_req = GSM48_MT_GMM_ATTACH_REQ;
1246 return gsm48_gmm_authorize(ctx);
Harald Welte9b455bf2010-03-14 15:45:01 +08001247
1248err_inval:
Daniel Willmann46553142014-09-03 17:46:44 +02001249 LOGPC(DMM, LOGL_INFO, "\n");
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001250 reject_cause = GMM_CAUSE_SEM_INCORR_MSG;
1251
1252rejected:
1253 /* Send ATTACH REJECT */
1254 LOGMMCTXP(LOGL_NOTICE, ctx,
1255 "Rejecting Attach Request with cause '%s' (%d)\n",
Jacob Erlbeckafcf2302015-01-05 17:30:02 +01001256 get_value_string(gsm48_gmm_cause_names, reject_cause), reject_cause);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001257 rc = gsm48_tx_gmm_att_rej_oldmsg(msg, reject_cause);
1258 if (ctx)
1259 mm_ctx_cleanup_free(ctx, "GPRS ATTACH REJ");
1260 else
Max39550252016-06-28 17:39:20 +02001261 gprs_llgmm_unassign(llme);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001262
1263 return rc;
1264
Harald Welte9b455bf2010-03-14 15:45:01 +08001265}
1266
Harald Welte2720e732010-05-17 00:44:57 +02001267/* Section 4.7.4.1 / 9.4.5.2 MO Detach request */
Harald Welted193cb32010-05-17 22:58:03 +02001268static int gsm48_rx_gmm_det_req(struct sgsn_mm_ctx *ctx, struct msgb *msg)
Harald Welte2720e732010-05-17 00:44:57 +02001269{
1270 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Harald Welte2720e732010-05-17 00:44:57 +02001271 uint8_t detach_type, power_off;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001272 int rc = 0;
Harald Welte2720e732010-05-17 00:44:57 +02001273
1274 detach_type = gh->data[0] & 0x7;
1275 power_off = gh->data[0] & 0x8;
1276
1277 /* FIXME: In 24.008 there is an optional P-TMSI and P-TMSI signature IE */
Alexander Couzens14314bd2016-07-05 09:52:52 +02001278 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_DETACH_REQUEST]);
Daniel Willmann46553142014-09-03 17:46:44 +02001279 LOGMMCTXP(LOGL_INFO, ctx, "-> GMM DETACH REQUEST TLLI=0x%08x type=%s %s\n",
Harald Welte2720e732010-05-17 00:44:57 +02001280 msgb_tlli(msg), get_value_string(gprs_det_t_mo_strs, detach_type),
1281 power_off ? "Power-off" : "");
1282
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001283 /* Only send the Detach Accept (MO) if power off isn't indicated,
Jacob Erlbeckb9ab0d42014-10-21 09:52:05 +02001284 * see 04.08, 4.7.4.1.2/3 for details */
1285 if (!power_off) {
1286 /* force_stby = 0 */
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001287 if (ctx)
1288 rc = gsm48_tx_gmm_det_ack(ctx, 0);
1289 else
1290 rc = gsm48_tx_gmm_det_ack_oldmsg(msg, 0);
Jacob Erlbeckb9ab0d42014-10-21 09:52:05 +02001291 }
Harald Weltebd5c9122010-06-28 22:18:53 +02001292
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +02001293 if (ctx) {
1294 struct sgsn_signal_data sig_data;
1295 memset(&sig_data, 0, sizeof(sig_data));
1296 sig_data.mm = ctx;
1297 osmo_signal_dispatch(SS_SGSN, S_SGSN_DETACH, &sig_data);
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001298 mm_ctx_cleanup_free(ctx, "GPRS DETACH REQUEST");
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +02001299 }
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +02001300
Harald Weltebd5c9122010-06-28 22:18:53 +02001301 return rc;
Harald Welte2720e732010-05-17 00:44:57 +02001302}
1303
Harald Welte9b455bf2010-03-14 15:45:01 +08001304/* Chapter 9.4.15: Routing area update accept */
Harald Welte6463c072010-05-18 17:04:55 +02001305static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm)
Harald Welte9b455bf2010-03-14 15:45:01 +08001306{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +01001307 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 UPD ACK");
Harald Welte9b455bf2010-03-14 15:45:01 +08001308 struct gsm48_hdr *gh;
1309 struct gsm48_ra_upd_ack *rua;
Harald Weltec2e8cc42010-05-31 20:23:38 +02001310 uint8_t *mid;
Harald Welte9b455bf2010-03-14 15:45:01 +08001311
Alexander Couzens14314bd2016-07-05 09:52:52 +02001312 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_ACKED]);
Daniel Willmann46553142014-09-03 17:46:44 +02001313 LOGMMCTXP(LOGL_INFO, mm, "<- ROUTING AREA UPDATE ACCEPT\n");
Harald Welte9b455bf2010-03-14 15:45:01 +08001314
Harald Welte6463c072010-05-18 17:04:55 +02001315 mmctx2msgid(msg, mm);
Harald Welte9b455bf2010-03-14 15:45:01 +08001316
1317 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1318 gh->proto_discr = GSM48_PDISC_MM_GPRS;
1319 gh->msg_type = GSM48_MT_GMM_RA_UPD_ACK;
1320
1321 rua = (struct gsm48_ra_upd_ack *) msgb_put(msg, sizeof(*rua));
1322 rua->force_stby = 0; /* not indicated */
1323 rua->upd_result = 0; /* RA updated */
Harald Welte94508822015-08-15 19:08:21 +02001324 rua->ra_upd_timer = gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3312);
Harald Welte11d7c102010-05-02 11:54:55 +02001325
Harald Welte6463c072010-05-18 17:04:55 +02001326 gsm48_construct_ra(rua->ra_id.digits, &mm->ra);
Harald Welte9b455bf2010-03-14 15:45:01 +08001327
Harald Weltec2e8cc42010-05-31 20:23:38 +02001328#if 0
1329 /* Optional: P-TMSI signature */
1330 msgb_v_put(msg, GSM48_IE_GMM_PTMSI_SIG);
1331 ptsig = msgb_put(msg, 3);
1332 ptsig[0] = mm->p_tmsi_sig >> 16;
1333 ptsig[1] = mm->p_tmsi_sig >> 8;
1334 ptsig[2] = mm->p_tmsi_sig & 0xff;
1335#endif
1336
1337#ifdef PTMSI_ALLOC
1338 /* Optional: Allocated P-TMSI */
1339 mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
1340 gsm48_generate_mid_from_tmsi(mid, mm->p_tmsi);
1341 mid[0] = GSM48_IE_GMM_ALLOC_PTMSI;
1342#endif
1343
Jacob Erlbeck8de9c482015-01-23 11:44:39 +01001344 /* Optional: Negotiated READY timer value */
1345 msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY,
Harald Welte94508822015-08-15 19:08:21 +02001346 gprs_secs_to_tmr_floor(sgsn->cfg.timers.T3314));
Jacob Erlbeck8de9c482015-01-23 11:44:39 +01001347
Harald Weltec2e8cc42010-05-31 20:23:38 +02001348 /* Option: MS ID, ... */
Max82040102016-07-06 11:59:18 +02001349 return gsm48_gmm_sendmsg(msg, 0, mm, true);
Harald Welte9b455bf2010-03-14 15:45:01 +08001350}
1351
1352/* Chapter 9.4.17: Routing area update reject */
Harald Welteeaa614c2010-05-02 11:26:34 +02001353static int gsm48_tx_gmm_ra_upd_rej(struct msgb *old_msg, uint8_t cause)
Harald Welte9b455bf2010-03-14 15:45:01 +08001354{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +01001355 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RA UPD REJ");
Harald Welte9b455bf2010-03-14 15:45:01 +08001356 struct gsm48_hdr *gh;
1357
Daniel Willmann46553142014-09-03 17:46:44 +02001358 LOGP(DMM, LOGL_NOTICE, "<- ROUTING AREA UPDATE REJECT\n");
Alexander Couzens14314bd2016-07-05 09:52:52 +02001359 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_REJECT]);
Harald Welte9b455bf2010-03-14 15:45:01 +08001360
Harald Welte11d7c102010-05-02 11:54:55 +02001361 gmm_copy_id(msg, old_msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08001362
1363 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 2);
1364 gh->proto_discr = GSM48_PDISC_MM_GPRS;
1365 gh->msg_type = GSM48_MT_GMM_RA_UPD_REJ;
1366 gh->data[0] = cause;
1367 gh->data[1] = 0; /* ? */
1368
1369 /* Option: P-TMSI signature, allocated P-TMSI, MS ID, ... */
Max82040102016-07-06 11:59:18 +02001370 return gsm48_gmm_sendmsg(msg, 0, NULL, false);
Harald Welte9b455bf2010-03-14 15:45:01 +08001371}
1372
Harald Welte588d44e2010-06-09 10:28:29 +02001373static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx,
Holger Hans Peter Freyther2b174542011-10-14 23:31:34 +02001374 const uint8_t *pdp_status)
Harald Welte588d44e2010-06-09 10:28:29 +02001375{
1376 struct sgsn_pdp_ctx *pdp, *pdp2;
1377 /* 24.008 4.7.5.1.3: If the PDP context status information element is
1378 * included in ROUTING AREA UPDATE REQUEST message, then the network
1379 * shall deactivate all those PDP contexts locally (without peer to
1380 * peer signalling between the MS and the network), which are not in SM
1381 * state PDP-INACTIVE on network side but are indicated by the MS as
1382 * being in state PDP-INACTIVE. */
1383
1384 llist_for_each_entry_safe(pdp, pdp2, &mmctx->pdp_list, list) {
Harald Weltecdf76cf2011-08-05 21:23:46 +02001385 if (pdp->nsapi < 8) {
1386 if (!(pdp_status[0] & (1 << pdp->nsapi))) {
Daniel Willmann46553142014-09-03 17:46:44 +02001387 LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping PDP context for NSAPI=%u "
Harald Weltecdf76cf2011-08-05 21:23:46 +02001388 "due to PDP CTX STATUS IE= 0x%02x%02x\n",
1389 pdp->nsapi, pdp_status[1], pdp_status[0]);
1390 sgsn_delete_pdp_ctx(pdp);
1391 }
1392 } else {
1393 if (!(pdp_status[1] & (1 << (pdp->nsapi - 8)))) {
Daniel Willmann46553142014-09-03 17:46:44 +02001394 LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping PDP context for NSAPI=%u "
Harald Weltecdf76cf2011-08-05 21:23:46 +02001395 "due to PDP CTX STATUS IE= 0x%02x%02x\n",
1396 pdp->nsapi, pdp_status[1], pdp_status[0]);
1397 sgsn_delete_pdp_ctx(pdp);
1398 }
Harald Welte588d44e2010-06-09 10:28:29 +02001399 }
1400 }
1401}
1402
Harald Welte9b455bf2010-03-14 15:45:01 +08001403/* Chapter 9.4.14: Routing area update request */
Harald Welte807a5d82010-06-01 11:53:01 +02001404static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
1405 struct gprs_llc_llme *llme)
Harald Welte9b455bf2010-03-14 15:45:01 +08001406{
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +02001407#ifndef PTMSI_ALLOC
1408 struct sgsn_signal_data sig_data;
1409#endif
Harald Welte943c5bc2010-04-30 16:33:12 +02001410 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Harald Welteeaa614c2010-05-02 11:26:34 +02001411 uint8_t *cur = gh->data;
Harald Welte588d44e2010-06-09 10:28:29 +02001412 uint8_t ms_ra_acc_cap_len;
Harald Welte9b455bf2010-03-14 15:45:01 +08001413 struct gprs_ra_id old_ra_id;
Harald Welte588d44e2010-06-09 10:28:29 +02001414 struct tlv_parsed tp;
Harald Welteeaa614c2010-05-02 11:26:34 +02001415 uint8_t upd_type;
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001416 enum gsm48_gmm_cause reject_cause;
1417 int rc;
Harald Welte9b455bf2010-03-14 15:45:01 +08001418
Daniel Willmann746c7892016-01-25 16:49:53 +01001419 /* TODO: In iu mode - handle follow-on request */
1420
Harald Welte9b455bf2010-03-14 15:45:01 +08001421 /* Update Type 10.5.5.18 */
Daniel Willmann746c7892016-01-25 16:49:53 +01001422 upd_type = *cur++ & 0x07;
Harald Welte9b455bf2010-03-14 15:45:01 +08001423
Alexander Couzens14314bd2016-07-05 09:52:52 +02001424 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_GPRS_ROUTING_AREA_REQUEST]);
Daniel Willmann46553142014-09-03 17:46:44 +02001425 LOGP(DMM, LOGL_INFO, "-> GMM RA UPDATE REQUEST type=\"%s\"\n",
Harald Welte2720e732010-05-17 00:44:57 +02001426 get_value_string(gprs_upd_t_strs, upd_type));
Harald Welte9b455bf2010-03-14 15:45:01 +08001427
1428 /* Old routing area identification 10.5.5.15 */
1429 gsm48_parse_ra(&old_ra_id, cur);
1430 cur += 6;
1431
1432 /* MS Radio Access Capability 10.5.5.12a */
Harald Welte588d44e2010-06-09 10:28:29 +02001433 ms_ra_acc_cap_len = *cur++;
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001434 if (ms_ra_acc_cap_len > 52) {
1435 reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
1436 goto rejected;
1437 }
Harald Welte4b2ed352011-07-27 23:35:38 +02001438 cur += ms_ra_acc_cap_len;
Harald Welte9b455bf2010-03-14 15:45:01 +08001439
1440 /* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status,
1441 * DRX parameter, MS network capability */
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +02001442 tlv_parse(&tp, &gsm48_gmm_att_tlvdef, cur,
Harald Welte588d44e2010-06-09 10:28:29 +02001443 (msg->data + msg->len) - cur, 0, 0);
Harald Welte9b455bf2010-03-14 15:45:01 +08001444
1445 switch (upd_type) {
1446 case GPRS_UPD_T_RA_LA:
1447 case GPRS_UPD_T_RA_LA_IMSI_ATT:
Daniel Willmann46553142014-09-03 17:46:44 +02001448 LOGP(DMM, LOGL_NOTICE, "Update type %i unsupported in Mode III, is your SI13 corrupt?\n", upd_type);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001449 reject_cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
1450 goto rejected;
Harald Welte9b455bf2010-03-14 15:45:01 +08001451 case GPRS_UPD_T_RA:
1452 case GPRS_UPD_T_PERIODIC:
1453 break;
1454 }
1455
Jacob Erlbeckd35957a2016-01-04 18:43:36 +01001456 if (!mmctx) {
1457 /* BSSGP doesn't give us an mmctx */
1458
1459 /* TODO: Check if there is an MM CTX with old_ra_id and
1460 * the P-TMSI (if given, reguired for UMTS) or as last resort
1461 * if the TLLI matches foreign_tlli (P-TMSI). Note that this
1462 * is an optimization to avoid the RA reject (impl detached)
1463 * below, which will cause a new attach cycle. */
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01001464 /* Look-up the MM context based on old RA-ID and TLLI */
Daniel Willmann61329d42016-05-21 17:36:18 +02001465 /* In Iu mode, msg->dst contains the ue_conn_ctx pointer, in Gb
1466 * mode dst is empty. */
1467 /* FIXME: have a more explicit indicator for Iu messages */
1468 if (!msg->dst) {
1469 mmctx = sgsn_mm_ctx_by_tlli_and_ptmsi(msgb_tlli(msg), &old_ra_id);
1470 } else if (TLVP_PRESENT(&tp, GSM48_IE_GMM_ALLOC_PTMSI)) {
1471#ifdef BUILD_IU
1472 /* In Iu mode search only for ptmsi */
1473 char mi_string[GSM48_MI_SIZE];
1474 uint8_t mi_len = TLVP_LEN(&tp, GSM48_IE_GMM_ALLOC_PTMSI);
1475 uint8_t *mi = TLVP_VAL(&tp, GSM48_IE_GMM_ALLOC_PTMSI);
1476 uint8_t mi_type = *mi & GSM_MI_TYPE_MASK;
1477 uint32_t tmsi;
1478
1479 gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
1480
1481 if (mi_type == GSM_MI_TYPE_TMSI) {
1482 memcpy(&tmsi, mi+1, 4);
1483 tmsi = ntohl(tmsi);
1484 mmctx = sgsn_mm_ctx_by_ptmsi(tmsi);
1485 }
1486#else
1487 goto rejected;
1488#endif
1489 }
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01001490 if (mmctx) {
1491 LOGMMCTXP(LOGL_INFO, mmctx,
1492 "Looked up by matching TLLI and P_TMSI. "
1493 "BSSGP TLLI: %08x, P-TMSI: %08x (%08x), "
1494 "TLLI: %08x (%08x), RA: %d-%d-%d-%d\n",
1495 msgb_tlli(msg),
1496 mmctx->p_tmsi, mmctx->p_tmsi_old,
Harald Weltef97ee042015-12-25 19:12:21 +01001497 mmctx->gb.tlli, mmctx->gb.tlli_new,
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01001498 mmctx->ra.mcc, mmctx->ra.mnc,
1499 mmctx->ra.lac, mmctx->ra.rac);
Jacob Erlbeckd35957a2016-01-04 18:43:36 +01001500
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01001501 mmctx->mm_state = GMM_COMMON_PROC_INIT;
1502 }
1503 } else if (!gprs_ra_id_equals(&mmctx->ra, &old_ra_id) ||
Jacob Erlbeckd35957a2016-01-04 18:43:36 +01001504 mmctx->mm_state == GMM_DEREGISTERED)
1505 {
1506 /* We cannot use the mmctx */
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01001507 LOGMMCTXP(LOGL_INFO, mmctx,
1508 "The MM context cannot be used, RA: %d-%d-%d-%d\n",
1509 mmctx->ra.mcc, mmctx->ra.mnc,
1510 mmctx->ra.lac, mmctx->ra.rac);
1511 mmctx = NULL;
1512 }
Jacob Erlbeckd35957a2016-01-04 18:43:36 +01001513
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01001514 if (!mmctx) {
Harald Welte2b2429e2015-12-25 22:31:36 +01001515 if (llme) {
1516 /* send a XID reset to re-set all LLC sequence numbers
1517 * in the MS */
1518 LOGMMCTXP(LOGL_NOTICE, mmctx, "LLC XID RESET\n");
1519 gprs_llgmm_reset(llme);
1520 }
Harald Welte9b455bf2010-03-14 15:45:01 +08001521 /* The MS has to perform GPRS attach */
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001522 /* Device is still IMSI attached for CS but initiate GPRS ATTACH,
1523 * see GSM 04.08, 4.7.5.1.4 and G.6 */
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001524 reject_cause = GMM_CAUSE_IMPL_DETACHED;
1525 goto rejected;
Harald Welte9b455bf2010-03-14 15:45:01 +08001526 }
1527
Harald Weltef0901f02010-12-26 10:39:26 +01001528 /* Store new BVCI/NSEI in MM context (FIXME: delay until we ack?) */
1529 msgid2mmctx(mmctx, msg);
1530 /* Bump the statistics of received signalling msgs for this MM context */
1531 rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
1532
Harald Welte9f1f3ad2010-05-02 12:56:57 +02001533 /* Update the MM context with the new RA-ID */
Harald Weltedbc72b32015-12-25 22:23:27 +01001534 if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
Daniel Willmannf9f43872016-05-20 22:36:23 +02001535 bssgp_parse_cell_id(&mmctx->ra, msgb_bcid(msg));
Harald Weltedbc72b32015-12-25 22:23:27 +01001536 /* Update the MM context with the new (i.e. foreign) TLLI */
1537 mmctx->gb.tlli = msgb_tlli(msg);
1538 }
Harald Welte9b455bf2010-03-14 15:45:01 +08001539 /* FIXME: Update the MM context with the MS radio acc capabilities */
1540 /* FIXME: Update the MM context with the MS network capabilities */
1541
Harald Welte77289c22010-05-18 14:32:29 +02001542 rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_RA_UPDATE]);
1543
Harald Weltec2e8cc42010-05-31 20:23:38 +02001544#ifdef PTMSI_ALLOC
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001545 /* Don't change the P-TMSI if a P-TMSI re-assignment is under way */
1546 if (mmctx->mm_state != GMM_COMMON_PROC_INIT) {
1547 mmctx->p_tmsi_old = mmctx->p_tmsi;
1548 mmctx->p_tmsi = sgsn_alloc_ptmsi();
1549 }
Harald Weltec2e8cc42010-05-31 20:23:38 +02001550 /* Start T3350 and re-transmit up to 5 times until ATTACH COMPLETE */
1551 mmctx->t3350_mode = GMM_T3350_MODE_RAU;
Harald Welte94508822015-08-15 19:08:21 +02001552 mmctx_timer_start(mmctx, 3350, sgsn->cfg.timers.T3350);
Jacob Erlbeck0074a772014-10-28 16:23:46 +01001553
1554 mmctx->mm_state = GMM_COMMON_PROC_INIT;
1555#else
1556 /* Make sure we are NORMAL (i.e. not SUSPENDED anymore) */
1557 mmctx->mm_state = GMM_REGISTERED_NORMAL;
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +02001558
1559 memset(&sig_data, 0, sizeof(sig_data));
1560 sig_data.mm = mmctx;
1561 osmo_signal_dispatch(SS_SGSN, S_SGSN_UPDATE, &sig_data);
Harald Weltec2e8cc42010-05-31 20:23:38 +02001562#endif
Harald Weltedbc72b32015-12-25 22:23:27 +01001563 if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
1564 /* Even if there is no P-TMSI allocated, the MS will switch from
1565 * foreign TLLI to local TLLI */
1566 mmctx->gb.tlli_new = gprs_tmsi2tlli(mmctx->p_tmsi, TLLI_LOCAL);
Harald Weltec2e8cc42010-05-31 20:23:38 +02001567
Harald Weltedbc72b32015-12-25 22:23:27 +01001568 /* Inform LLC layer about new TLLI but keep old active */
1569 gprs_llgmm_assign(mmctx->gb.llme, mmctx->gb.tlli,
Max5aa51962016-07-06 11:33:04 +02001570 mmctx->gb.tlli_new);
Harald Weltedbc72b32015-12-25 22:23:27 +01001571 }
Harald Welte807a5d82010-06-01 11:53:01 +02001572
Harald Welte588d44e2010-06-09 10:28:29 +02001573 /* Look at PDP Context Status IE and see if MS's view of
1574 * activated/deactivated NSAPIs agrees with our view */
1575 if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) {
Holger Hans Peter Freyther2b174542011-10-14 23:31:34 +02001576 const uint8_t *pdp_status = TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS);
Harald Welte588d44e2010-06-09 10:28:29 +02001577 process_ms_ctx_status(mmctx, pdp_status);
1578 }
1579
Daniel Willmannaf241722016-05-21 00:35:41 +02001580 /* Send RA UPDATE ACCEPT. In Iu, the RA upd request can be called from
1581 * a new Iu connection, so we might need to re-authenticate the
1582 * connection as well as turn on integrity protection. */
1583 mmctx->pending_req = GSM48_MT_GMM_RA_UPD_REQ;
1584 return gsm48_gmm_authorize(mmctx);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001585
1586rejected:
1587 /* Send RA UPDATE REJECT */
1588 LOGMMCTXP(LOGL_NOTICE, mmctx,
1589 "Rejecting RA Update Request with cause '%s' (%d)\n",
Jacob Erlbeckafcf2302015-01-05 17:30:02 +01001590 get_value_string(gsm48_gmm_cause_names, reject_cause), reject_cause);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001591 rc = gsm48_tx_gmm_ra_upd_rej(msg, reject_cause);
1592 if (mmctx)
1593 mm_ctx_cleanup_free(mmctx, "GPRS RA UPDATE REJ");
Harald Weltedbc72b32015-12-25 22:23:27 +01001594 else {
Max39550252016-06-28 17:39:20 +02001595 if (llme)
1596 gprs_llgmm_unassign(llme);
Harald Weltedbc72b32015-12-25 22:23:27 +01001597 }
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001598
1599 return rc;
Harald Welte9b455bf2010-03-14 15:45:01 +08001600}
1601
Daniel Willmann1dee2b62016-05-21 00:15:29 +02001602/* 3GPP TS 24.008 Section 9.4.20 Service request.
1603 * In Iu, a UE in PMM-IDLE mode can use GSM48_MT_GMM_SERVICE_REQ to switch back
1604 * to PMM-CONNECTED mode. */
1605static int gsm48_rx_gmm_service_req(struct sgsn_mm_ctx *ctx, struct msgb *msg)
1606{
1607 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
1608 uint8_t *cur = gh->data, *mi;
1609 uint8_t ciph_seq_nr, service_type, mi_len, mi_type;
1610 uint32_t tmsi;
1611 struct tlv_parsed tp;
1612 char mi_string[GSM48_MI_SIZE];
1613 enum gsm48_gmm_cause reject_cause;
1614 int rc;
1615
1616 LOGMMCTXP(LOGL_INFO, ctx, "-> GMM SERVICE REQUEST ");
1617
1618 /* This message is only valid in Iu mode */
1619 if (!msg->dst) {
1620 LOGPC(DMM, LOGL_INFO, "Invalid if not in Iu mode\n");
1621 return -1;
1622 }
1623
1624 /* Skip Ciphering key sequence number 10.5.1.2 */
1625 ciph_seq_nr = *cur & 0x07;
1626
1627 /* Service type 10.5.5.20 */
1628 service_type = (*cur++ >> 4) & 0x07;
1629
1630 /* Mobile Identity (P-TMSI or IMSI) 10.5.1.4 */
1631 mi_len = *cur++;
1632 mi = cur;
1633 if (mi_len > 8)
1634 goto err_inval;
1635 mi_type = *mi & GSM_MI_TYPE_MASK;
1636 cur += mi_len;
1637
1638 gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
1639
1640 DEBUGPC(DMM, "MI(%s) type=\"%s\" ", mi_string,
1641 get_value_string(gprs_service_t_strs, service_type));
1642
1643 LOGPC(DMM, LOGL_INFO, "\n");
1644
1645 /* Optional: PDP context status, MBMS context status, Uplink data status, Device properties */
1646 tlv_parse(&tp, &gsm48_gmm_att_tlvdef, cur, (msg->data + msg->len) - cur, 0, 0);
1647
1648 switch (mi_type) {
1649 case GSM_MI_TYPE_IMSI:
1650 /* Try to find MM context based on IMSI */
1651 if (!ctx)
1652 ctx = sgsn_mm_ctx_by_imsi(mi_string);
1653 if (!ctx) {
1654 /* FIXME: We need to have a context for service request? */
1655 reject_cause = GMM_CAUSE_NET_FAIL;
1656 goto rejected;
1657 }
1658 msgid2mmctx(ctx, msg);
1659 break;
1660 case GSM_MI_TYPE_TMSI:
1661 memcpy(&tmsi, mi+1, 4);
1662 tmsi = ntohl(tmsi);
1663 /* Try to find MM context based on P-TMSI */
1664 if (!ctx)
1665 ctx = sgsn_mm_ctx_by_ptmsi(tmsi);
1666 if (!ctx) {
1667 /* FIXME: We need to have a context for service request? */
1668 reject_cause = GMM_CAUSE_NET_FAIL;
1669 goto rejected;
1670 }
1671 msgid2mmctx(ctx, msg);
1672 break;
1673 default:
1674 LOGMMCTXP(LOGL_NOTICE, ctx, "Rejecting SERVICE REQUEST with "
1675 "MI type %s\n", gsm48_mi_type_name(mi_type));
1676 reject_cause = GMM_CAUSE_MS_ID_NOT_DERIVED;
1677 goto rejected;
1678 }
1679
1680 ctx->mm_state = GMM_COMMON_PROC_INIT;
1681
1682 ctx->iu.service.type = service_type;
1683
1684 /* TODO: Handle those only in case of accept? */
1685 /* Look at PDP Context Status IE and see if MS's view of
1686 * activated/deactivated NSAPIs agrees with our view */
1687 if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PDP_CTX_STATUS)) {
1688 const uint8_t *pdp_status = TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS);
1689 process_ms_ctx_status(ctx, pdp_status);
1690 }
1691
1692
1693 ctx->pending_req = GSM48_MT_GMM_SERVICE_REQ;
1694 return gsm48_gmm_authorize(ctx);
1695
1696err_inval:
1697 LOGPC(DMM, LOGL_INFO, "\n");
1698 reject_cause = GMM_CAUSE_SEM_INCORR_MSG;
1699
1700rejected:
1701 /* Send SERVICE REJECT */
1702 LOGMMCTXP(LOGL_NOTICE, ctx,
1703 "Rejecting Service Request with cause '%s' (%d)\n",
1704 get_value_string(gsm48_gmm_cause_names, reject_cause), reject_cause);
1705 rc = gsm48_tx_gmm_service_rej_oldmsg(msg, reject_cause);
1706
1707 return rc;
1708
1709}
1710
1711
Harald Welted193cb32010-05-17 22:58:03 +02001712static int gsm48_rx_gmm_status(struct sgsn_mm_ctx *mmctx, struct msgb *msg)
Harald Welte9b455bf2010-03-14 15:45:01 +08001713{
1714 struct gsm48_hdr *gh = msgb_l3(msg);
1715
Daniel Willmann46553142014-09-03 17:46:44 +02001716 LOGMMCTXP(LOGL_INFO, mmctx, "-> GPRS MM STATUS (cause: %s)\n",
Jacob Erlbeckafcf2302015-01-05 17:30:02 +01001717 get_value_string(gsm48_gmm_cause_names, gh->data[0]));
Harald Welte9b455bf2010-03-14 15:45:01 +08001718
1719 return 0;
1720}
1721
1722/* GPRS Mobility Management */
Harald Welte807a5d82010-06-01 11:53:01 +02001723static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
Max82040102016-07-06 11:59:18 +02001724 struct gprs_llc_llme *llme, bool drop_cipherable)
Harald Welte9b455bf2010-03-14 15:45:01 +08001725{
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +02001726 struct sgsn_signal_data sig_data;
Harald Welte943c5bc2010-04-30 16:33:12 +02001727 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08001728 int rc;
1729
Harald Welte807a5d82010-06-01 11:53:01 +02001730 /* MMCTX can be NULL when called */
Max82040102016-07-06 11:59:18 +02001731 if (drop_cipherable && gsm48_hdr_gmm_cipherable(gh)) {
1732 LOGMMCTXP(LOGL_NOTICE, mmctx, "Dropping cleartext GMM %s which "
1733 "is expected to be encrypted for TLLI 0x%08x\n",
1734 get_value_string(gprs_msgt_gmm_names, gh->msg_type),
1735 llme->tlli);
1736 return -EBADMSG;
1737 }
Harald Welte807a5d82010-06-01 11:53:01 +02001738
Harald Welte2b2429e2015-12-25 22:31:36 +01001739 if (llme && !mmctx &&
Harald Welted193cb32010-05-17 22:58:03 +02001740 gh->msg_type != GSM48_MT_GMM_ATTACH_REQ &&
Harald Weltec2e8cc42010-05-31 20:23:38 +02001741 gh->msg_type != GSM48_MT_GMM_RA_UPD_REQ) {
Harald Welted193cb32010-05-17 22:58:03 +02001742 LOGP(DMM, LOGL_NOTICE, "Cannot handle GMM for unknown MM CTX\n");
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001743 /* 4.7.10 */
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001744 if (gh->msg_type == GSM48_MT_GMM_STATUS) {
1745 /* TLLI unassignment */
Max39550252016-06-28 17:39:20 +02001746 gprs_llgmm_unassign(llme);
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001747 return 0;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001748 }
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001749
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001750 /* Don't reply or establish a LLME on DETACH_ACK */
Max39550252016-06-28 17:39:20 +02001751 if (gh->msg_type == GSM48_MT_GMM_DETACH_ACK)
1752 return gprs_llgmm_unassign(llme);
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001753
Jacob Erlbeckc4f9bf32014-11-11 08:55:13 +01001754 gprs_llgmm_reset(llme);
1755
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001756 /* Don't force it into re-attachment */
1757 if (gh->msg_type == GSM48_MT_GMM_DETACH_REQ) {
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001758 /* Handle Detach Request */
1759 rc = gsm48_rx_gmm_det_req(NULL, msg);
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001760
1761 /* TLLI unassignment */
Max39550252016-06-28 17:39:20 +02001762 gprs_llgmm_unassign(llme);
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001763 return rc;
1764 }
1765
1766 /* Force the MS to re-attach */
Maxb997f842016-07-06 15:57:01 +02001767 rc = gsm0408_gprs_force_reattach_oldmsg(msg, llme);
Jacob Erlbeckb1c074f2014-10-31 12:27:11 +01001768
1769 /* TLLI unassignment */
Max39550252016-06-28 17:39:20 +02001770 gprs_llgmm_unassign(llme);
Jacob Erlbeckb1c074f2014-10-31 12:27:11 +01001771 return rc;
Harald Welted193cb32010-05-17 22:58:03 +02001772 }
1773
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001774 /*
1775 * For a few messages, mmctx may be NULL. For most, we want to ensure a
1776 * non-NULL mmctx. At the same time, we want to keep the message
1777 * validity check intact, so that all message types appear in the
1778 * switch statement and the default case thus means "unknown message".
1779 * If we split the switch in two parts to check non-NULL halfway, the
1780 * unknown-message check breaks, or we'd need to duplicate the switch
1781 * cases in both parts. Just keep one large switch and add some gotos.
1782 */
Harald Welte9b455bf2010-03-14 15:45:01 +08001783 switch (gh->msg_type) {
1784 case GSM48_MT_GMM_RA_UPD_REQ:
Harald Welte807a5d82010-06-01 11:53:01 +02001785 rc = gsm48_rx_gmm_ra_upd_req(mmctx, msg, llme);
Harald Welte9b455bf2010-03-14 15:45:01 +08001786 break;
1787 case GSM48_MT_GMM_ATTACH_REQ:
Harald Welte807a5d82010-06-01 11:53:01 +02001788 rc = gsm48_rx_gmm_att_req(mmctx, msg, llme);
Harald Welte9b455bf2010-03-14 15:45:01 +08001789 break;
Daniel Willmann1dee2b62016-05-21 00:15:29 +02001790 case GSM48_MT_GMM_SERVICE_REQ:
1791 rc = gsm48_rx_gmm_service_req(mmctx, msg);
1792 break;
Daniel Willmann46553142014-09-03 17:46:44 +02001793 /* For all the following types mmctx can not be NULL */
Harald Welte9b455bf2010-03-14 15:45:01 +08001794 case GSM48_MT_GMM_ID_RESP:
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001795 if (!mmctx)
1796 goto null_mmctx;
Harald Welted193cb32010-05-17 22:58:03 +02001797 rc = gsm48_rx_gmm_id_resp(mmctx, msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08001798 break;
1799 case GSM48_MT_GMM_STATUS:
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001800 if (!mmctx)
1801 goto null_mmctx;
Harald Welted193cb32010-05-17 22:58:03 +02001802 rc = gsm48_rx_gmm_status(mmctx, msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08001803 break;
Harald Welte2720e732010-05-17 00:44:57 +02001804 case GSM48_MT_GMM_DETACH_REQ:
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001805 if (!mmctx)
1806 goto null_mmctx;
Harald Welted193cb32010-05-17 22:58:03 +02001807 rc = gsm48_rx_gmm_det_req(mmctx, msg);
Harald Welte2720e732010-05-17 00:44:57 +02001808 break;
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001809 case GSM48_MT_GMM_DETACH_ACK:
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001810 if (!mmctx)
1811 goto null_mmctx;
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02001812 LOGMMCTXP(LOGL_INFO, mmctx, "-> DETACH ACK\n");
1813 mm_ctx_cleanup_free(mmctx, "GPRS DETACH ACK");
1814 rc = 0;
1815 break;
Harald Welte9b455bf2010-03-14 15:45:01 +08001816 case GSM48_MT_GMM_ATTACH_COMPL:
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001817 if (!mmctx)
1818 goto null_mmctx;
Harald Welte9b455bf2010-03-14 15:45:01 +08001819 /* only in case SGSN offered new P-TMSI */
Daniel Willmann46553142014-09-03 17:46:44 +02001820 LOGMMCTXP(LOGL_INFO, mmctx, "-> ATTACH COMPLETE\n");
Harald Weltec2e8cc42010-05-31 20:23:38 +02001821 mmctx_timer_stop(mmctx, 3350);
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +01001822 mmctx->t3350_mode = GMM_T3350_MODE_NONE;
Harald Weltec2e8cc42010-05-31 20:23:38 +02001823 mmctx->p_tmsi_old = 0;
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +01001824 mmctx->pending_req = 0;
Harald Weltedbc72b32015-12-25 22:23:27 +01001825 if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
1826 /* Unassign the old TLLI */
1827 mmctx->gb.tlli = mmctx->gb.tlli_new;
Max5aa51962016-07-06 11:33:04 +02001828 gprs_llme_copy_key(mmctx, mmctx->gb.llme);
Harald Weltedbc72b32015-12-25 22:23:27 +01001829 gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff,
Max5aa51962016-07-06 11:33:04 +02001830 mmctx->gb.tlli_new);
Harald Weltedbc72b32015-12-25 22:23:27 +01001831 }
Jacob Erlbeck0074a772014-10-28 16:23:46 +01001832 mmctx->mm_state = GMM_REGISTERED_NORMAL;
Daniel Willmannc17cdb42016-05-11 12:42:54 +02001833 mmctx_set_pmm_state(mmctx, PMM_CONNECTED);
Holger Hans Peter Freyther2b174542011-10-14 23:31:34 +02001834 rc = 0;
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +02001835
1836 memset(&sig_data, 0, sizeof(sig_data));
1837 sig_data.mm = mmctx;
1838 osmo_signal_dispatch(SS_SGSN, S_SGSN_ATTACH, &sig_data);
Harald Weltec2e8cc42010-05-31 20:23:38 +02001839 break;
Harald Welteab1d5622010-05-18 19:58:38 +02001840 case GSM48_MT_GMM_RA_UPD_COMPL:
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001841 if (!mmctx)
1842 goto null_mmctx;
Harald Welteab1d5622010-05-18 19:58:38 +02001843 /* only in case SGSN offered new P-TMSI */
Harald Welteecff2422015-08-16 18:14:33 +02001844 LOGMMCTXP(LOGL_INFO, mmctx, "-> ROUTING AREA UPDATE COMPLETE\n");
Harald Weltec2e8cc42010-05-31 20:23:38 +02001845 mmctx_timer_stop(mmctx, 3350);
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +01001846 mmctx->t3350_mode = GMM_T3350_MODE_NONE;
Harald Weltec2e8cc42010-05-31 20:23:38 +02001847 mmctx->p_tmsi_old = 0;
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +01001848 mmctx->pending_req = 0;
Harald Weltedbc72b32015-12-25 22:23:27 +01001849 if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
1850 /* Unassign the old TLLI */
1851 mmctx->gb.tlli = mmctx->gb.tlli_new;
Max5aa51962016-07-06 11:33:04 +02001852 gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff,
1853 mmctx->gb.tlli_new);
Harald Weltedbc72b32015-12-25 22:23:27 +01001854 }
Jacob Erlbeck0074a772014-10-28 16:23:46 +01001855 mmctx->mm_state = GMM_REGISTERED_NORMAL;
Daniel Willmannc17cdb42016-05-11 12:42:54 +02001856 mmctx_set_pmm_state(mmctx, PMM_CONNECTED);
Holger Hans Peter Freyther2b174542011-10-14 23:31:34 +02001857 rc = 0;
Holger Hans Peter Freytherb1008952015-05-02 19:55:38 +02001858
1859 memset(&sig_data, 0, sizeof(sig_data));
1860 sig_data.mm = mmctx;
1861 osmo_signal_dispatch(SS_SGSN, S_SGSN_UPDATE, &sig_data);
Harald Weltec2e8cc42010-05-31 20:23:38 +02001862 break;
Harald Welte9b455bf2010-03-14 15:45:01 +08001863 case GSM48_MT_GMM_PTMSI_REALL_COMPL:
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001864 if (!mmctx)
1865 goto null_mmctx;
Daniel Willmann46553142014-09-03 17:46:44 +02001866 LOGMMCTXP(LOGL_INFO, mmctx, "-> PTMSI REALLLICATION COMPLETE\n");
Harald Weltec2e8cc42010-05-31 20:23:38 +02001867 mmctx_timer_stop(mmctx, 3350);
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +01001868 mmctx->t3350_mode = GMM_T3350_MODE_NONE;
Harald Weltec2e8cc42010-05-31 20:23:38 +02001869 mmctx->p_tmsi_old = 0;
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +01001870 mmctx->pending_req = 0;
Harald Weltedbc72b32015-12-25 22:23:27 +01001871 if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) {
1872 /* Unassign the old TLLI */
1873 mmctx->gb.tlli = mmctx->gb.tlli_new;
1874 //gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff, mmctx->gb.tlli_new, GPRS_ALGO_GEA0, NULL);
1875 }
Holger Hans Peter Freyther2b174542011-10-14 23:31:34 +02001876 rc = 0;
Harald Weltec2e8cc42010-05-31 20:23:38 +02001877 break;
Harald Welte9b455bf2010-03-14 15:45:01 +08001878 case GSM48_MT_GMM_AUTH_CIPH_RESP:
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001879 if (!mmctx)
1880 goto null_mmctx;
Harald Welte4b6ac1e2010-07-03 11:09:06 +02001881 rc = gsm48_rx_gmm_auth_ciph_resp(mmctx, msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08001882 break;
1883 default:
Daniel Willmann46553142014-09-03 17:46:44 +02001884 LOGMMCTXP(LOGL_NOTICE, mmctx, "Unknown GSM 04.08 GMM msg type 0x%02x\n",
Harald Welte9b455bf2010-03-14 15:45:01 +08001885 gh->msg_type);
Neels Hofmeyr9329e6f2016-06-03 00:44:23 +02001886 if (mmctx)
1887 rc = gsm48_tx_gmm_status(mmctx, GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
1888 else
1889 rc = -EINVAL;
Harald Welte9b455bf2010-03-14 15:45:01 +08001890 break;
1891 }
1892
1893 return rc;
Neels Hofmeyre98ba822016-05-22 14:28:19 +02001894
1895null_mmctx:
1896 LOGP(DMM, LOGL_ERROR,
1897 "Received GSM 04.08 message type 0x%02x,"
1898 " but no MM context available\n",
1899 gh->msg_type);
1900 return -EINVAL;
Harald Welte9b455bf2010-03-14 15:45:01 +08001901}
1902
Harald Weltec2e8cc42010-05-31 20:23:38 +02001903static void mmctx_timer_cb(void *_mm)
1904{
1905 struct sgsn_mm_ctx *mm = _mm;
Jacob Erlbeckbd0cf112014-12-01 12:33:33 +01001906 struct gsm_auth_tuple *at;
Harald Weltec2e8cc42010-05-31 20:23:38 +02001907
1908 mm->num_T_exp++;
1909
1910 switch (mm->T) {
1911 case 3350: /* waiting for ATTACH COMPLETE */
1912 if (mm->num_T_exp >= 5) {
Daniel Willmann46553142014-09-03 17:46:44 +02001913 LOGMMCTXP(LOGL_NOTICE, mm, "T3350 expired >= 5 times\n");
Jacob Erlbecka7904562014-11-03 10:12:52 +01001914 mm_ctx_cleanup_free(mm, "T3350");
Harald Weltec2e8cc42010-05-31 20:23:38 +02001915 /* FIXME: should we return some error? */
1916 break;
1917 }
1918 /* re-transmit the respective msg and re-start timer */
1919 switch (mm->t3350_mode) {
1920 case GMM_T3350_MODE_ATT:
1921 gsm48_tx_gmm_att_ack(mm);
1922 break;
1923 case GMM_T3350_MODE_RAU:
1924 gsm48_tx_gmm_ra_upd_ack(mm);
1925 break;
1926 case GMM_T3350_MODE_PTMSI_REALL:
1927 /* FIXME */
1928 break;
Jacob Erlbeck93eae8e2014-10-28 12:23:29 +01001929 case GMM_T3350_MODE_NONE:
1930 LOGMMCTXP(LOGL_NOTICE, mm,
1931 "T3350 mode wasn't set, ignoring timeout\n");
1932 break;
Harald Weltec2e8cc42010-05-31 20:23:38 +02001933 }
Harald Welte94508822015-08-15 19:08:21 +02001934 osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3350, 0);
Harald Weltec2e8cc42010-05-31 20:23:38 +02001935 break;
Harald Welte4b6ac1e2010-07-03 11:09:06 +02001936 case 3360: /* waiting for AUTH AND CIPH RESP */
1937 if (mm->num_T_exp >= 5) {
Daniel Willmann46553142014-09-03 17:46:44 +02001938 LOGMMCTXP(LOGL_NOTICE, mm, "T3360 expired >= 5 times\n");
Jacob Erlbecka7904562014-11-03 10:12:52 +01001939 mm_ctx_cleanup_free(mm, "T3360");
Harald Welte4b6ac1e2010-07-03 11:09:06 +02001940 break;
1941 }
Jacob Erlbeckbd0cf112014-12-01 12:33:33 +01001942 /* Re-transmit the respective msg and re-start timer */
1943 if (mm->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) {
1944 LOGMMCTXP(LOGL_ERROR, mm,
1945 "timeout: invalid auth triplet reference\n");
1946 mm_ctx_cleanup_free(mm, "T3360");
1947 break;
1948 }
1949 at = &mm->auth_triplet;
1950
Maxb997f842016-07-06 15:57:01 +02001951 gsm48_tx_gmm_auth_ciph_req(mm, at->vec.rand, at->key_seq, false);
Harald Welte94508822015-08-15 19:08:21 +02001952 osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3360, 0);
Harald Welte4b6ac1e2010-07-03 11:09:06 +02001953 break;
Harald Weltec2e8cc42010-05-31 20:23:38 +02001954 case 3370: /* waiting for IDENTITY RESPONSE */
1955 if (mm->num_T_exp >= 5) {
Daniel Willmann46553142014-09-03 17:46:44 +02001956 LOGMMCTXP(LOGL_NOTICE, mm, "T3370 expired >= 5 times\n");
Harald Weltec2e8cc42010-05-31 20:23:38 +02001957 gsm48_tx_gmm_att_rej(mm, GMM_CAUSE_MS_ID_NOT_DERIVED);
Jacob Erlbecka7904562014-11-03 10:12:52 +01001958 mm_ctx_cleanup_free(mm, "GPRS ATTACH REJECT (T3370)");
Harald Weltec2e8cc42010-05-31 20:23:38 +02001959 break;
1960 }
1961 /* re-tranmit IDENTITY REQUEST and re-start timer */
1962 gsm48_tx_gmm_id_req(mm, mm->t3370_id_type);
Harald Welte94508822015-08-15 19:08:21 +02001963 osmo_timer_schedule(&mm->timer, sgsn->cfg.timers.T3370, 0);
Harald Weltec2e8cc42010-05-31 20:23:38 +02001964 break;
1965 default:
Daniel Willmann46553142014-09-03 17:46:44 +02001966 LOGMMCTXP(LOGL_ERROR, mm, "timer expired in unknown mode %u\n",
Harald Weltec2e8cc42010-05-31 20:23:38 +02001967 mm->T);
1968 }
1969}
1970
1971/* GPRS SESSION MANAGEMENT */
1972
Harald Weltea9b473a2010-12-24 21:13:26 +01001973static void pdpctx_timer_cb(void *_mm);
1974
1975static void pdpctx_timer_start(struct sgsn_pdp_ctx *pdp, unsigned int T,
1976 unsigned int seconds)
1977{
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001978 if (osmo_timer_pending(&pdp->timer))
Pravin Kumarvel26f6ced2016-11-17 12:19:01 +05301979 LOGPDPCTXP(LOGL_ERROR, pdp, "Starting PDP timer %u while old "
Harald Weltea9b473a2010-12-24 21:13:26 +01001980 "timer %u pending\n", T, pdp->T);
1981 pdp->T = T;
1982 pdp->num_T_exp = 0;
1983
1984 /* FIXME: we should do this only once ? */
1985 pdp->timer.data = pdp;
1986 pdp->timer.cb = &pdpctx_timer_cb;
1987
Pablo Neira Ayusobf540cb2011-05-06 12:11:06 +02001988 osmo_timer_schedule(&pdp->timer, seconds, 0);
Harald Weltea9b473a2010-12-24 21:13:26 +01001989}
1990
Pravin Kumarvel16606c92016-11-17 12:20:01 +05301991static void pdpctx_timer_stop(struct sgsn_pdp_ctx *pdp, unsigned int T)
1992{
1993 if (pdp->T != T)
1994 LOGPDPCTXP(LOGL_ERROR, pdp, "Stopping PDP timer %u but "
1995 "%u is running\n", T, pdp->T);
1996 osmo_timer_del(&pdp->timer);
1997}
1998
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +02001999#if 0
Harald Welte421cba42010-05-02 23:11:50 +02002000static void msgb_put_pdp_addr_ipv4(struct msgb *msg, uint32_t ipaddr)
2001{
2002 uint8_t v[6];
2003
2004 v[0] = PDP_TYPE_ORG_IETF;
2005 v[1] = PDP_TYPE_N_IETF_IPv4;
2006 *(uint32_t *)(v+2) = htonl(ipaddr);
2007
2008 msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v);
2009}
2010
2011static void msgb_put_pdp_addr_ppp(struct msgb *msg)
2012{
2013 uint8_t v[2];
2014
2015 v[0] = PDP_TYPE_ORG_ETSI;
2016 v[1] = PDP_TYPE_N_ETSI_PPP;
2017
2018 msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR, sizeof(v), v);
2019}
Holger Hans Peter Freyther1768a572014-04-04 12:40:34 +02002020#endif
Harald Welte421cba42010-05-02 23:11:50 +02002021
Alexander Couzens14314bd2016-07-05 09:52:52 +02002022/* Section 9.5.2: Activate PDP Context Accept */
Harald Welte6abf94e2010-05-18 10:35:06 +02002023int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp)
Harald Welte9b455bf2010-03-14 15:45:01 +08002024{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +01002025 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP ACC");
Harald Welte9b455bf2010-03-14 15:45:01 +08002026 struct gsm48_hdr *gh;
Harald Welte6abf94e2010-05-18 10:35:06 +02002027 uint8_t transaction_id = pdp->ti ^ 0x8; /* flip */
Harald Welte9b455bf2010-03-14 15:45:01 +08002028
Daniel Willmann46553142014-09-03 17:46:44 +02002029 LOGPDPCTXP(LOGL_INFO, pdp, "<- ACTIVATE PDP CONTEXT ACK\n");
Alexander Couzens14314bd2016-07-05 09:52:52 +02002030 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_ACCEPT]);
Harald Welte9b455bf2010-03-14 15:45:01 +08002031
Harald Welte6abf94e2010-05-18 10:35:06 +02002032 mmctx2msgid(msg, pdp->mm);
Harald Welte9b455bf2010-03-14 15:45:01 +08002033
2034 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2035 gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
2036 gh->msg_type = GSM48_MT_GSM_ACT_PDP_ACK;
Harald Welte421cba42010-05-02 23:11:50 +02002037
2038 /* Negotiated LLC SAPI */
Harald Welte6abf94e2010-05-18 10:35:06 +02002039 msgb_v_put(msg, pdp->sapi);
Harald Welte4e38ac72010-05-18 14:51:18 +02002040
Harald Welte55e0df72010-05-18 13:20:08 +02002041 /* FIXME: copy QoS parameters from original request */
2042 //msgb_lv_put(msg, pdp->lib->qos_neg.l, pdp->lib->qos_neg.v);
2043 msgb_lv_put(msg, sizeof(default_qos), (uint8_t *)&default_qos);
Harald Welte4e38ac72010-05-18 14:51:18 +02002044
Harald Welte421cba42010-05-02 23:11:50 +02002045 /* Radio priority 10.5.7.2 */
Harald Welte6abf94e2010-05-18 10:35:06 +02002046 msgb_v_put(msg, pdp->lib->radio_pri);
Harald Welte4e38ac72010-05-18 14:51:18 +02002047
Harald Welte421cba42010-05-02 23:11:50 +02002048 /* PDP address */
Harald Welte4e38ac72010-05-18 14:51:18 +02002049 /* Highest 4 bits of first byte need to be set to 1, otherwise
2050 * the IE is identical with the 04.08 PDP Address IE */
2051 pdp->lib->eua.v[0] &= ~0xf0;
Harald Welte6abf94e2010-05-18 10:35:06 +02002052 msgb_tlv_put(msg, GSM48_IE_GSM_PDP_ADDR,
2053 pdp->lib->eua.l, pdp->lib->eua.v);
Harald Welte4e38ac72010-05-18 14:51:18 +02002054 pdp->lib->eua.v[0] |= 0xf0;
2055
Harald Welte77289c22010-05-18 14:32:29 +02002056 /* Optional: Protocol configuration options (FIXME: why 'req') */
Holger Hans Peter Freytherd2195072014-04-04 11:55:21 +02002057 if (pdp->lib->pco_req.l)
Harald Welte6abf94e2010-05-18 10:35:06 +02002058 msgb_tlv_put(msg, GSM48_IE_GSM_PROTO_CONF_OPT,
Harald Welte3c0b9b92010-05-18 14:36:11 +02002059 pdp->lib->pco_req.l, pdp->lib->pco_req.v);
Harald Welte4e38ac72010-05-18 14:51:18 +02002060
Harald Welte421cba42010-05-02 23:11:50 +02002061 /* Optional: Packet Flow Identifier */
Harald Welte9b455bf2010-03-14 15:45:01 +08002062
Max82040102016-07-06 11:59:18 +02002063 return gsm48_gmm_sendmsg(msg, 0, pdp->mm, true);
Harald Welte9b455bf2010-03-14 15:45:01 +08002064}
2065
Harald Welte6abf94e2010-05-18 10:35:06 +02002066/* Section 9.5.3: Activate PDP Context reject */
2067int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
2068 uint8_t cause, uint8_t pco_len, uint8_t *pco_v)
2069{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +01002070 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP REJ");
Harald Welte6abf94e2010-05-18 10:35:06 +02002071 struct gsm48_hdr *gh;
2072 uint8_t transaction_id = tid ^ 0x8; /* flip */
2073
Daniel Willmann46553142014-09-03 17:46:44 +02002074 LOGMMCTXP(LOGL_NOTICE, mm, "<- ACTIVATE PDP CONTEXT REJ(cause=%u)\n", cause);
Alexander Couzens14314bd2016-07-05 09:52:52 +02002075 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_REJECT]);
Harald Welte6abf94e2010-05-18 10:35:06 +02002076
2077 mmctx2msgid(msg, mm);
2078
2079 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2080 gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
2081 gh->msg_type = GSM48_MT_GSM_ACT_PDP_REJ;
2082
2083 msgb_v_put(msg, cause);
2084 if (pco_len && pco_v)
2085 msgb_tlv_put(msg, GSM48_IE_GSM_PROTO_CONF_OPT, pco_len, pco_v);
2086
Max82040102016-07-06 11:59:18 +02002087 return gsm48_gmm_sendmsg(msg, 0, mm, true);
Harald Welte6abf94e2010-05-18 10:35:06 +02002088}
2089
Harald Weltea9b473a2010-12-24 21:13:26 +01002090/* Section 9.5.8: Deactivate PDP Context Request */
2091static int _gsm48_tx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, uint8_t tid,
2092 uint8_t sm_cause)
2093{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +01002094 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET REQ");
Harald Weltea9b473a2010-12-24 21:13:26 +01002095 struct gsm48_hdr *gh;
2096 uint8_t transaction_id = tid ^ 0x8; /* flip */
2097
Daniel Willmann46553142014-09-03 17:46:44 +02002098 LOGMMCTXP(LOGL_INFO, mm, "<- DEACTIVATE PDP CONTEXT REQ\n");
Alexander Couzens14314bd2016-07-05 09:52:52 +02002099 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_DL_DEACTIVATE_REQUEST]);
Harald Weltea9b473a2010-12-24 21:13:26 +01002100
2101 mmctx2msgid(msg, mm);
2102
2103 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2104 gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
2105 gh->msg_type = GSM48_MT_GSM_DEACT_PDP_REQ;
2106
2107 msgb_v_put(msg, sm_cause);
2108
Max82040102016-07-06 11:59:18 +02002109 return gsm48_gmm_sendmsg(msg, 0, mm, true);
Harald Weltea9b473a2010-12-24 21:13:26 +01002110}
2111int gsm48_tx_gsm_deact_pdp_req(struct sgsn_pdp_ctx *pdp, uint8_t sm_cause)
2112{
Harald Welte94508822015-08-15 19:08:21 +02002113 pdpctx_timer_start(pdp, 3395, sgsn->cfg.timers.T3395);
Harald Weltea9b473a2010-12-24 21:13:26 +01002114
2115 return _gsm48_tx_gsm_deact_pdp_req(pdp->mm, pdp->ti, sm_cause);
2116}
2117
Harald Welte9b455bf2010-03-14 15:45:01 +08002118/* Section 9.5.9: Deactivate PDP Context Accept */
Harald Welte60ebc022010-06-08 18:08:59 +02002119static int _gsm48_tx_gsm_deact_pdp_acc(struct sgsn_mm_ctx *mm, uint8_t tid)
Harald Welte9b455bf2010-03-14 15:45:01 +08002120{
Holger Hans Peter Freyther8239e062016-01-25 22:03:25 +01002121 struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 PDP DET ACC");
Harald Welte9b455bf2010-03-14 15:45:01 +08002122 struct gsm48_hdr *gh;
Harald Welte60ebc022010-06-08 18:08:59 +02002123 uint8_t transaction_id = tid ^ 0x8; /* flip */
Harald Welte9b455bf2010-03-14 15:45:01 +08002124
Daniel Willmann46553142014-09-03 17:46:44 +02002125 LOGMMCTXP(LOGL_INFO, mm, "<- DEACTIVATE PDP CONTEXT ACK\n");
Alexander Couzens14314bd2016-07-05 09:52:52 +02002126 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_DL_DEACTIVATE_ACCEPT]);
Harald Welte9b455bf2010-03-14 15:45:01 +08002127
Harald Welte60ebc022010-06-08 18:08:59 +02002128 mmctx2msgid(msg, mm);
Harald Welte9b455bf2010-03-14 15:45:01 +08002129
2130 gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
2131 gh->proto_discr = GSM48_PDISC_SM_GPRS | (transaction_id << 4);
2132 gh->msg_type = GSM48_MT_GSM_DEACT_PDP_ACK;
2133
Max82040102016-07-06 11:59:18 +02002134 return gsm48_gmm_sendmsg(msg, 0, mm, true);
Harald Welte60ebc022010-06-08 18:08:59 +02002135}
2136int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp)
2137{
2138 return _gsm48_tx_gsm_deact_pdp_acc(pdp->mm, pdp->ti);
Harald Welte9b455bf2010-03-14 15:45:01 +08002139}
2140
Holger Hans Peter Freyther7605bdc2015-05-24 12:42:26 +08002141static int activate_ggsn(struct sgsn_mm_ctx *mmctx,
2142 struct sgsn_ggsn_ctx *ggsn, const uint8_t transaction_id,
2143 const uint8_t req_nsapi, const uint8_t req_llc_sapi,
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002144 struct tlv_parsed *tp, int destroy_ggsn)
Holger Hans Peter Freyther7605bdc2015-05-24 12:42:26 +08002145{
2146 struct sgsn_pdp_ctx *pdp;
2147
Holger Hans Peter Freytherb7ae0b32015-05-29 15:11:55 +02002148 LOGMMCTXP(LOGL_DEBUG, mmctx, "Using GGSN %u\n", ggsn->id);
Holger Hans Peter Freyther7605bdc2015-05-24 12:42:26 +08002149 ggsn->gsn = sgsn->gsn;
2150 pdp = sgsn_create_pdp_ctx(ggsn, mmctx, req_nsapi, tp);
2151 if (!pdp)
2152 return -1;
2153
2154 /* Store SAPI and Transaction Identifier */
2155 pdp->sapi = req_llc_sapi;
2156 pdp->ti = transaction_id;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002157 pdp->destroy_ggsn = destroy_ggsn;
Holger Hans Peter Freyther7605bdc2015-05-24 12:42:26 +08002158
2159 return 0;
2160}
2161
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002162static void ggsn_lookup_cb(void *arg, int status, int timeouts, struct hostent *hostent)
2163{
2164 struct sgsn_ggsn_ctx *ggsn;
2165 struct sgsn_ggsn_lookup *lookup = arg;
2166 struct in_addr *addr = NULL;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002167
2168 /* The context is gone while we made a request */
2169 if (!lookup->mmctx) {
2170 talloc_free(lookup);
2171 return;
2172 }
2173
2174 if (status != ARES_SUCCESS) {
2175 struct sgsn_mm_ctx *mmctx = lookup->mmctx;
2176
2177 LOGMMCTXP(LOGL_ERROR, mmctx, "DNS query failed.\n");
2178
2179 /* Need to try with three digits now */
2180 if (lookup->state == SGSN_GGSN_2DIGIT) {
2181 char *hostname;
2182 int rc;
2183
2184 lookup->state = SGSN_GGSN_3DIGIT;
2185 hostname = osmo_apn_qualify_from_imsi(mmctx->imsi,
2186 lookup->apn_str, 1);
2187 LOGMMCTXP(LOGL_DEBUG, mmctx,
2188 "Going to query %s\n", hostname);
2189 rc = sgsn_ares_query(sgsn, hostname,
2190 ggsn_lookup_cb, lookup);
2191 if (rc != 0) {
Harald Welte601cf122015-08-16 17:16:28 +02002192 LOGMMCTXP(LOGL_ERROR, mmctx, "Couldn't start GGSN\n");
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002193 goto reject_due_failure;
2194 }
2195 return;
2196 }
2197
2198 LOGMMCTXP(LOGL_ERROR, mmctx, "Couldn't resolve GGSN\n");
2199 goto reject_due_failure;
2200 }
2201
2202 if (hostent->h_length != sizeof(struct in_addr)) {
2203 LOGMMCTXP(LOGL_ERROR, lookup->mmctx,
Harald Welte6b39fee2015-08-16 17:16:57 +02002204 "Wrong addr size(%zu)\n", sizeof(struct in_addr));
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002205 goto reject_due_failure;
2206 }
2207
Holger Hans Peter Freyther09589382015-06-02 09:38:41 +02002208 /* Get the first addr from the list */
2209 addr = (struct in_addr *) hostent->h_addr_list[0];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002210 if (!addr) {
2211 LOGMMCTXP(LOGL_ERROR, lookup->mmctx, "No host address.\n");
2212 goto reject_due_failure;
2213 }
2214
2215 ggsn = sgsn_ggsn_ctx_alloc(UINT32_MAX);
2216 if (!ggsn) {
2217 LOGMMCTXP(LOGL_ERROR, lookup->mmctx, "Failed to create ggsn.\n");
2218 goto reject_due_failure;
2219 }
2220 ggsn->remote_addr = *addr;
2221 LOGMMCTXP(LOGL_NOTICE, lookup->mmctx,
2222 "Selected %s as GGSN.\n", inet_ntoa(*addr));
2223
2224 /* forget about the ggsn look-up */
2225 lookup->mmctx->ggsn_lookup = NULL;
2226
2227 activate_ggsn(lookup->mmctx, ggsn, lookup->ti, lookup->nsapi,
2228 lookup->sapi, &lookup->tp, 1);
2229
2230 /* Now free it */
2231 talloc_free(lookup);
2232 return;
2233
2234reject_due_failure:
2235 gsm48_tx_gsm_act_pdp_rej(lookup->mmctx, lookup->ti,
2236 GMM_CAUSE_NET_FAIL, 0, NULL);
2237 lookup->mmctx->ggsn_lookup = NULL;
2238 talloc_free(lookup);
2239}
Holger Hans Peter Freytherccd23122015-05-24 16:48:22 +08002240
2241static int do_act_pdp_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg)
Harald Welte9b455bf2010-03-14 15:45:01 +08002242{
Harald Welte943c5bc2010-04-30 16:33:12 +02002243 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08002244 struct gsm48_act_pdp_ctx_req *act_req = (struct gsm48_act_pdp_ctx_req *) gh->data;
Harald Welte0c3eae02010-05-02 21:07:14 +02002245 uint8_t req_qos_len, req_pdpa_len;
2246 uint8_t *req_qos, *req_pdpa;
2247 struct tlv_parsed tp;
Neels Hofmeyr961bd0b2016-03-14 16:13:25 +01002248 uint8_t transaction_id = gsm48_hdr_trans_id(gh);
Harald Welte11ff3e82010-07-02 10:17:24 +02002249 struct sgsn_ggsn_ctx *ggsn;
Harald Welte6abf94e2010-05-18 10:35:06 +02002250 struct sgsn_pdp_ctx *pdp;
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002251 enum gsm48_gsm_cause gsm_cause;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002252 char apn_str[GSM_APN_LENGTH] = { 0, };
2253 char *hostname;
2254 int rc;
Harald Welte9b455bf2010-03-14 15:45:01 +08002255
Daniel Willmann46553142014-09-03 17:46:44 +02002256 LOGMMCTXP(LOGL_INFO, mmctx, "-> ACTIVATE PDP CONTEXT REQ: SAPI=%u NSAPI=%u ",
Harald Welte6abf94e2010-05-18 10:35:06 +02002257 act_req->req_llc_sapi, act_req->req_nsapi);
Harald Welte8acd88f2010-05-18 10:57:45 +02002258
Harald Welte23c13762010-07-02 22:52:04 +02002259 /* FIXME: length checks! */
Harald Welte0c3eae02010-05-02 21:07:14 +02002260 req_qos_len = act_req->data[0];
2261 req_qos = act_req->data + 1; /* 10.5.6.5 */
2262 req_pdpa_len = act_req->data[1 + req_qos_len];
2263 req_pdpa = act_req->data + 1 + req_qos_len + 1; /* 10.5.6.4 */
Harald Welte9b455bf2010-03-14 15:45:01 +08002264
Harald Welte0c3eae02010-05-02 21:07:14 +02002265 switch (req_pdpa[0] & 0xf) {
2266 case 0x0:
2267 DEBUGPC(DMM, "ETSI ");
2268 break;
2269 case 0x1:
2270 DEBUGPC(DMM, "IETF ");
2271 break;
2272 case 0xf:
2273 DEBUGPC(DMM, "Empty ");
2274 break;
2275 }
2276
2277 switch (req_pdpa[1]) {
2278 case 0x21:
2279 DEBUGPC(DMM, "IPv4 ");
2280 if (req_pdpa_len >= 6) {
2281 struct in_addr ia;
2282 ia.s_addr = ntohl(*((uint32_t *) (req_pdpa+2)));
2283 DEBUGPC(DMM, "%s ", inet_ntoa(ia));
2284 }
2285 break;
2286 case 0x57:
2287 DEBUGPC(DMM, "IPv6 ");
2288 if (req_pdpa_len >= 18) {
2289 /* FIXME: print IPv6 address */
2290 }
2291 break;
2292 default:
2293 DEBUGPC(DMM, "0x%02x ", req_pdpa[1]);
2294 break;
2295 }
2296
Daniel Willmann46553142014-09-03 17:46:44 +02002297 LOGPC(DMM, LOGL_INFO, "\n");
Harald Welte77289c22010-05-18 14:32:29 +02002298
Harald Welte6abf94e2010-05-18 10:35:06 +02002299 /* Check if NSAPI is out of range (TS 04.65 / 7.2) */
2300 if (act_req->req_nsapi < 5 || act_req->req_nsapi > 15) {
2301 /* Send reject with GSM_CAUSE_INV_MAND_INFO */
2302 return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
2303 GSM_CAUSE_INV_MAND_INFO,
2304 0, NULL);
2305 }
2306
Holger Hans Peter Freyther7605bdc2015-05-24 12:42:26 +08002307 /* Optional: Access Point Name, Protocol Config Options */
2308 if (req_pdpa + req_pdpa_len < msg->data + msg->len)
2309 tlv_parse(&tp, &gsm48_sm_att_tlvdef, req_pdpa + req_pdpa_len,
2310 (msg->data + msg->len) - (req_pdpa + req_pdpa_len), 0, 0);
2311 else
2312 memset(&tp, 0, sizeof(tp));
2313
2314
2315 /* put the non-TLV elements in the TLV parser structure to
2316 * pass them on to the SGSN / GTP code */
2317 tp.lv[OSMO_IE_GSM_REQ_QOS].len = req_qos_len;
2318 tp.lv[OSMO_IE_GSM_REQ_QOS].val = req_qos;
2319 tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].len = req_pdpa_len;
2320 tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].val = req_pdpa;
2321
Harald Welte6abf94e2010-05-18 10:35:06 +02002322 /* Check if NSAPI is already in use */
Harald Welteb37515e2010-07-02 10:12:58 +02002323 pdp = sgsn_pdp_ctx_by_nsapi(mmctx, act_req->req_nsapi);
2324 if (pdp) {
2325 /* We already have a PDP context for this TLLI + NSAPI tuple */
2326 if (pdp->sapi == act_req->req_llc_sapi &&
2327 pdp->ti == transaction_id) {
2328 /* This apparently is a re-transmission of a PDP CTX
2329 * ACT REQ (our ACT ACK must have got dropped) */
2330 return gsm48_tx_gsm_act_pdp_acc(pdp);
2331 }
2332
2333 /* Send reject with GSM_CAUSE_NSAPI_IN_USE */
Harald Welte6abf94e2010-05-18 10:35:06 +02002334 return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
2335 GSM_CAUSE_NSAPI_IN_USE,
2336 0, NULL);
2337 }
Harald Welte9b455bf2010-03-14 15:45:01 +08002338
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002339 if (mmctx->ggsn_lookup) {
2340 if (mmctx->ggsn_lookup->sapi == act_req->req_llc_sapi &&
2341 mmctx->ggsn_lookup->ti == transaction_id) {
2342 LOGMMCTXP(LOGL_NOTICE, mmctx,
2343 "Re-transmission while doing look-up. Ignoring.\n");
2344 return 0;
2345 }
2346 }
2347
Harald Welte19f9e302010-07-02 10:15:49 +02002348 /* Only increment counter for a real activation, after we checked
2349 * for re-transmissions */
2350 rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PDP_CTX_ACT]);
2351
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002352 /* Determine GGSN based on APN and subscription options */
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002353 ggsn = sgsn_mm_ctx_find_ggsn_ctx(mmctx, &tp, &gsm_cause, apn_str);
2354 if (ggsn)
2355 return activate_ggsn(mmctx, ggsn, transaction_id,
2356 act_req->req_nsapi, act_req->req_llc_sapi,
2357 &tp, 0);
2358
2359 if (strlen(apn_str) == 0)
2360 goto no_context;
2361 if (!sgsn->cfg.dynamic_lookup)
2362 goto no_context;
2363
2364 /* schedule a dynamic look-up */
2365 mmctx->ggsn_lookup = talloc_zero(tall_bsc_ctx, struct sgsn_ggsn_lookup);
2366 if (!mmctx->ggsn_lookup)
2367 goto no_context;
2368
2369 mmctx->ggsn_lookup->state = SGSN_GGSN_2DIGIT;
2370 mmctx->ggsn_lookup->mmctx = mmctx;
2371 strcpy(mmctx->ggsn_lookup->apn_str, apn_str);
2372
2373 mmctx->ggsn_lookup->orig_msg = msg;
2374 mmctx->ggsn_lookup->tp = tp;
2375
2376 mmctx->ggsn_lookup->ti = transaction_id;
2377 mmctx->ggsn_lookup->nsapi = act_req->req_nsapi;
2378 mmctx->ggsn_lookup->sapi = act_req->req_llc_sapi;
2379
2380 hostname = osmo_apn_qualify_from_imsi(mmctx->imsi,
2381 mmctx->ggsn_lookup->apn_str, 0);
2382
2383 LOGMMCTXP(LOGL_DEBUG, mmctx, "Going to query %s\n", hostname);
2384 rc = sgsn_ares_query(sgsn, hostname,
2385 ggsn_lookup_cb, mmctx->ggsn_lookup);
2386 if (rc != 0) {
2387 LOGMMCTXP(LOGL_ERROR, mmctx, "Failed to start ares query.\n");
2388 goto no_context;
Harald Welted193cb32010-05-17 22:58:03 +02002389 }
Harald Welte11ff3e82010-07-02 10:17:24 +02002390
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002391 return 0;
2392
2393no_context:
Harald Welte601cf122015-08-16 17:16:28 +02002394 LOGMMCTXP(LOGL_ERROR, mmctx, "No GGSN context found!\n");
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002395 return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
2396 gsm_cause, 0, NULL);
Harald Welte9b455bf2010-03-14 15:45:01 +08002397}
2398
Holger Hans Peter Freytherccd23122015-05-24 16:48:22 +08002399/* Section 9.5.1: Activate PDP Context Request */
2400static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx,
2401 struct msgb *_msg)
2402{
2403 struct msgb *msg;
2404 int rc;
2405
Alexander Couzens14314bd2016-07-05 09:52:52 +02002406 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_ACTIVATE_REQUEST]);
2407
Holger Hans Peter Freytherccd23122015-05-24 16:48:22 +08002408 /*
2409 * This is painful. We might not have a static GGSN
2410 * configuration and then would need to copy the msg
2411 * and re-do most of this routine (or call it again
2412 * and make sure it only goes through the dynamic
2413 * resolving. The question is what to optimize for
2414 * and the dynamic resolution will be the right thing
2415 * in the long run.
2416 */
2417 msg = gprs_msgb_copy(_msg, __func__);
2418 if (!msg) {
2419 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(_msg);
Neels Hofmeyr961bd0b2016-03-14 16:13:25 +01002420 uint8_t transaction_id = gsm48_hdr_trans_id(gh);
Holger Hans Peter Freytherccd23122015-05-24 16:48:22 +08002421
2422 LOGMMCTXP(LOGL_ERROR, mmctx, "-> ACTIVATE PDP CONTEXT REQ failed copy.\n");
2423 /* Send reject with GSM_CAUSE_INV_MAND_INFO */
2424 return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id,
2425 GSM_CAUSE_NET_FAIL,
2426 0, NULL);
2427 }
2428
2429 rc = do_act_pdp_req(mmctx, _msg);
2430 msgb_free(msg);
2431 return rc;
2432}
2433
Harald Welte9b455bf2010-03-14 15:45:01 +08002434/* Section 9.5.8: Deactivate PDP Context Request */
Harald Welte77289c22010-05-18 14:32:29 +02002435static int gsm48_rx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, struct msgb *msg)
Harald Welte9b455bf2010-03-14 15:45:01 +08002436{
Harald Welte943c5bc2010-04-30 16:33:12 +02002437 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Neels Hofmeyr961bd0b2016-03-14 16:13:25 +01002438 uint8_t transaction_id = gsm48_hdr_trans_id(gh);
Harald Welte77289c22010-05-18 14:32:29 +02002439 struct sgsn_pdp_ctx *pdp;
Harald Welte9b455bf2010-03-14 15:45:01 +08002440
Daniel Willmann46553142014-09-03 17:46:44 +02002441 LOGMMCTXP(LOGL_INFO, mm, "-> DEACTIVATE PDP CONTEXT REQ (cause: %s)\n",
Jacob Erlbeckafcf2302015-01-05 17:30:02 +01002442 get_value_string(gsm48_gsm_cause_names, gh->data[0]));
Alexander Couzens14314bd2016-07-05 09:52:52 +02002443 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_UL_DEACTIVATE_REQUEST]);
Harald Welte9b455bf2010-03-14 15:45:01 +08002444
Harald Welte77289c22010-05-18 14:32:29 +02002445 pdp = sgsn_pdp_ctx_by_tid(mm, transaction_id);
2446 if (!pdp) {
Daniel Willmann46553142014-09-03 17:46:44 +02002447 LOGMMCTXP(LOGL_NOTICE, mm, "Deactivate PDP Context Request for "
Harald Welte77289c22010-05-18 14:32:29 +02002448 "non-existing PDP Context (IMSI=%s, TI=%u)\n",
2449 mm->imsi, transaction_id);
Harald Welte60ebc022010-06-08 18:08:59 +02002450 return _gsm48_tx_gsm_deact_pdp_acc(mm, transaction_id);
Harald Welte77289c22010-05-18 14:32:29 +02002451 }
2452
2453 return sgsn_delete_pdp_ctx(pdp);
Harald Welte9b455bf2010-03-14 15:45:01 +08002454}
2455
Harald Weltea9b473a2010-12-24 21:13:26 +01002456/* Section 9.5.9: Deactivate PDP Context Accept */
2457static int gsm48_rx_gsm_deact_pdp_ack(struct sgsn_mm_ctx *mm, struct msgb *msg)
2458{
2459 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Neels Hofmeyr961bd0b2016-03-14 16:13:25 +01002460 uint8_t transaction_id = gsm48_hdr_trans_id(gh);
Harald Weltea9b473a2010-12-24 21:13:26 +01002461 struct sgsn_pdp_ctx *pdp;
2462
Daniel Willmann46553142014-09-03 17:46:44 +02002463 LOGMMCTXP(LOGL_INFO, mm, "-> DEACTIVATE PDP CONTEXT ACK\n");
Alexander Couzens14314bd2016-07-05 09:52:52 +02002464 rate_ctr_inc(&sgsn->rate_ctrs->ctr[CTR_PDP_UL_DEACTIVATE_ACCEPT]);
Harald Weltea9b473a2010-12-24 21:13:26 +01002465
2466 pdp = sgsn_pdp_ctx_by_tid(mm, transaction_id);
2467 if (!pdp) {
Daniel Willmann46553142014-09-03 17:46:44 +02002468 LOGMMCTXP(LOGL_NOTICE, mm, "Deactivate PDP Context Accept for "
Harald Weltea9b473a2010-12-24 21:13:26 +01002469 "non-existing PDP Context (IMSI=%s, TI=%u)\n",
2470 mm->imsi, transaction_id);
2471 return 0;
2472 }
Pravin Kumarvel16606c92016-11-17 12:20:01 +05302473 /* stop timer 3395 */
2474 pdpctx_timer_stop(pdp, 3395);
Harald Weltea9b473a2010-12-24 21:13:26 +01002475 return sgsn_delete_pdp_ctx(pdp);
2476}
2477
Harald Welted193cb32010-05-17 22:58:03 +02002478static int gsm48_rx_gsm_status(struct sgsn_mm_ctx *ctx, struct msgb *msg)
Harald Welte9b455bf2010-03-14 15:45:01 +08002479{
2480 struct gsm48_hdr *gh = msgb_l3(msg);
2481
Daniel Willmann46553142014-09-03 17:46:44 +02002482 LOGMMCTXP(LOGL_INFO, ctx, "-> GPRS SM STATUS (cause: %s)\n",
Jacob Erlbeckafcf2302015-01-05 17:30:02 +01002483 get_value_string(gsm48_gsm_cause_names, gh->data[0]));
Harald Welte9b455bf2010-03-14 15:45:01 +08002484
2485 return 0;
2486}
2487
Harald Weltea9b473a2010-12-24 21:13:26 +01002488static void pdpctx_timer_cb(void *_pdp)
2489{
2490 struct sgsn_pdp_ctx *pdp = _pdp;
2491
2492 pdp->num_T_exp++;
2493
2494 switch (pdp->T) {
2495 case 3395: /* waiting for PDP CTX DEACT ACK */
2496 if (pdp->num_T_exp >= 4) {
Daniel Willmann46553142014-09-03 17:46:44 +02002497 LOGPDPCTXP(LOGL_NOTICE, pdp, "T3395 expired >= 5 times\n");
Harald Weltea9b473a2010-12-24 21:13:26 +01002498 pdp->state = PDP_STATE_INACTIVE;
2499 sgsn_delete_pdp_ctx(pdp);
2500 break;
2501 }
Alexander Couzens15fcd102016-07-19 15:14:03 +02002502 gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL);
Harald Weltea9b473a2010-12-24 21:13:26 +01002503 break;
2504 default:
Daniel Willmann46553142014-09-03 17:46:44 +02002505 LOGPDPCTXP(LOGL_ERROR, pdp, "timer expired in unknown mode %u\n",
Harald Weltea9b473a2010-12-24 21:13:26 +01002506 pdp->T);
2507 }
2508}
2509
2510
Harald Welte9b455bf2010-03-14 15:45:01 +08002511/* GPRS Session Management */
Harald Welte807a5d82010-06-01 11:53:01 +02002512static int gsm0408_rcv_gsm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
2513 struct gprs_llc_llme *llme)
Harald Welte9b455bf2010-03-14 15:45:01 +08002514{
Harald Welte943c5bc2010-04-30 16:33:12 +02002515 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08002516 int rc;
2517
Harald Welte807a5d82010-06-01 11:53:01 +02002518 /* MMCTX can be NULL when called */
2519
Harald Welted193cb32010-05-17 22:58:03 +02002520 if (!mmctx) {
2521 LOGP(DMM, LOGL_NOTICE, "Cannot handle SM for unknown MM CTX\n");
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02002522 /* 6.1.3.6 */
2523 if (gh->msg_type == GSM48_MT_GSM_STATUS)
2524 return 0;
2525
Maxb997f842016-07-06 15:57:01 +02002526 return gsm0408_gprs_force_reattach_oldmsg(msg, llme);
Harald Welted193cb32010-05-17 22:58:03 +02002527 }
2528
Harald Welte9b455bf2010-03-14 15:45:01 +08002529 switch (gh->msg_type) {
2530 case GSM48_MT_GSM_ACT_PDP_REQ:
Harald Welted193cb32010-05-17 22:58:03 +02002531 rc = gsm48_rx_gsm_act_pdp_req(mmctx, msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08002532 break;
2533 case GSM48_MT_GSM_DEACT_PDP_REQ:
Harald Welted193cb32010-05-17 22:58:03 +02002534 rc = gsm48_rx_gsm_deact_pdp_req(mmctx, msg);
Harald Welte77289c22010-05-18 14:32:29 +02002535 break;
Harald Weltea9b473a2010-12-24 21:13:26 +01002536 case GSM48_MT_GSM_DEACT_PDP_ACK:
2537 rc = gsm48_rx_gsm_deact_pdp_ack(mmctx, msg);
2538 break;
Harald Welte9b455bf2010-03-14 15:45:01 +08002539 case GSM48_MT_GSM_STATUS:
Harald Welted193cb32010-05-17 22:58:03 +02002540 rc = gsm48_rx_gsm_status(mmctx, msg);
Harald Welte9b455bf2010-03-14 15:45:01 +08002541 break;
2542 case GSM48_MT_GSM_REQ_PDP_ACT_REJ:
2543 case GSM48_MT_GSM_ACT_AA_PDP_REQ:
2544 case GSM48_MT_GSM_DEACT_AA_PDP_REQ:
Harald Welte6a19dd02015-08-16 12:18:13 +02002545 LOGMMCTXP(LOGL_NOTICE, mmctx, "Unimplemented GSM 04.08 GSM msg type 0x%02x: %s\n",
2546 gh->msg_type, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
Harald Weltef54e7e22010-06-09 10:51:23 +02002547 rc = gsm48_tx_sm_status(mmctx, GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
Harald Welte9b455bf2010-03-14 15:45:01 +08002548 break;
2549 default:
Harald Welte6a19dd02015-08-16 12:18:13 +02002550 LOGMMCTXP(LOGL_NOTICE, mmctx, "Unknown GSM 04.08 GSM msg type 0x%02x: %s\n",
2551 gh->msg_type, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
Harald Weltef54e7e22010-06-09 10:51:23 +02002552 rc = gsm48_tx_sm_status(mmctx, GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
Harald Welte9b455bf2010-03-14 15:45:01 +08002553 break;
2554
2555 }
2556
2557 return rc;
2558}
2559
Maxb997f842016-07-06 15:57:01 +02002560int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg,
2561 struct gprs_llc_llme *llme)
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02002562{
Jacob Erlbeckabdf02b2014-10-31 12:20:49 +01002563 int rc;
Alexander Couzensa1735662016-08-30 18:50:58 +02002564 if (llme)
2565 gprs_llgmm_reset_oldmsg(msg, GPRS_SAPI_GMM, llme);
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02002566
Jacob Erlbeckabdf02b2014-10-31 12:20:49 +01002567 rc = gsm48_tx_gmm_detach_req_oldmsg(
2568 msg, GPRS_DET_T_MT_REATT_REQ, GMM_CAUSE_IMPL_DETACHED);
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02002569
Jacob Erlbeckabdf02b2014-10-31 12:20:49 +01002570 return rc;
2571}
2572
2573int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx)
2574{
2575 int rc;
Harald Weltedbc72b32015-12-25 22:23:27 +01002576 if (mmctx->ran_type == MM_CTX_T_GERAN_Gb)
2577 gprs_llgmm_reset(mmctx->gb.llme);
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02002578
Jacob Erlbeckb1c074f2014-10-31 12:27:11 +01002579 rc = gsm48_tx_gmm_detach_req(
2580 mmctx, GPRS_DET_T_MT_REATT_REQ, GMM_CAUSE_IMPL_DETACHED);
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02002581
Jacob Erlbeckb1c074f2014-10-31 12:27:11 +01002582 mm_ctx_cleanup_free(mmctx, "forced reattach");
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02002583
Jacob Erlbeckb1c074f2014-10-31 12:27:11 +01002584 return rc;
Jacob Erlbeck78ecaf02014-09-05 14:32:36 +02002585}
2586
Daniel Willmann6292c8d2016-05-21 17:35:57 +02002587/* Main entry point for incoming 04.08 GPRS messages from Iu */
2588int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
2589 uint16_t *sai)
2590{
2591 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
2592 uint8_t pdisc = gsm48_hdr_pdisc(gh);
2593 struct sgsn_mm_ctx *mmctx;
2594 int rc = -EINVAL;
2595
2596 mmctx = sgsn_mm_ctx_by_ue_ctx(msg->dst);
2597 if (mmctx) {
2598 rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
2599 if (ra_id)
2600 memcpy(&mmctx->ra, ra_id, sizeof(mmctx->ra));
2601 }
2602
2603 /* MMCTX can be NULL */
2604
2605 switch (pdisc) {
2606 case GSM48_PDISC_MM_GPRS:
2607 rc = gsm0408_rcv_gmm(mmctx, msg, NULL, false);
2608#warning "set drop_cipherable arg for gsm0408_rcv_gmm() from IuPS?"
2609 break;
2610 case GSM48_PDISC_SM_GPRS:
2611 rc = gsm0408_rcv_gsm(mmctx, msg, NULL);
2612 break;
2613 default:
2614 LOGMMCTXP(LOGL_NOTICE, mmctx,
2615 "Unknown GSM 04.08 discriminator 0x%02x: %s\n",
2616 pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
2617 /* FIXME: return status message */
2618 break;
2619 }
2620
2621 /* MMCTX can be invalid */
2622
2623 return rc;
2624}
2625
Harald Welte49393e12015-12-25 19:14:57 +01002626/* Main entry point for incoming 04.08 GPRS messages from Gb */
Max82040102016-07-06 11:59:18 +02002627int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme,
2628 bool drop_cipherable)
Harald Welte9b455bf2010-03-14 15:45:01 +08002629{
Harald Welte943c5bc2010-04-30 16:33:12 +02002630 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
Neels Hofmeyr531734a2016-03-14 16:13:24 +01002631 uint8_t pdisc = gsm48_hdr_pdisc(gh);
Harald Welted193cb32010-05-17 22:58:03 +02002632 struct sgsn_mm_ctx *mmctx;
2633 struct gprs_ra_id ra_id;
Harald Welte9b455bf2010-03-14 15:45:01 +08002634 int rc = -EINVAL;
2635
Harald Welted193cb32010-05-17 22:58:03 +02002636 bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
2637 mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id);
Harald Welte8acd88f2010-05-18 10:57:45 +02002638 if (mmctx) {
Harald Welte6abf94e2010-05-18 10:35:06 +02002639 msgid2mmctx(mmctx, msg);
Harald Welte8acd88f2010-05-18 10:57:45 +02002640 rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
Harald Weltef97ee042015-12-25 19:12:21 +01002641 mmctx->gb.llme = llme;
Harald Welte8acd88f2010-05-18 10:57:45 +02002642 }
Harald Welted193cb32010-05-17 22:58:03 +02002643
2644 /* MMCTX can be NULL */
2645
Harald Welte9b455bf2010-03-14 15:45:01 +08002646 switch (pdisc) {
2647 case GSM48_PDISC_MM_GPRS:
Max82040102016-07-06 11:59:18 +02002648 rc = gsm0408_rcv_gmm(mmctx, msg, llme, drop_cipherable);
Harald Welte9b455bf2010-03-14 15:45:01 +08002649 break;
2650 case GSM48_PDISC_SM_GPRS:
Harald Welte807a5d82010-06-01 11:53:01 +02002651 rc = gsm0408_rcv_gsm(mmctx, msg, llme);
Harald Welte9b455bf2010-03-14 15:45:01 +08002652 break;
2653 default:
Harald Welteeb98c742015-08-16 17:11:32 +02002654 LOGMMCTXP(LOGL_NOTICE, mmctx,
2655 "Unknown GSM 04.08 discriminator 0x%02x: %s\n",
Harald Welte6a19dd02015-08-16 12:18:13 +02002656 pdisc, osmo_hexdump((uint8_t *)gh, msgb_l3len(msg)));
Harald Welte6abf94e2010-05-18 10:35:06 +02002657 /* FIXME: return status message */
Harald Welte9b455bf2010-03-14 15:45:01 +08002658 break;
2659 }
2660
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +02002661 /* MMCTX can be invalid */
2662
Harald Welte9b455bf2010-03-14 15:45:01 +08002663 return rc;
2664}
Harald Welte5bfe4992010-06-09 11:22:47 +02002665
2666int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli)
2667{
2668 struct sgsn_mm_ctx *mmctx;
2669
2670 mmctx = sgsn_mm_ctx_by_tlli(tlli, raid);
2671 if (!mmctx) {
2672 LOGP(DMM, LOGL_NOTICE, "SUSPEND request for unknown "
2673 "TLLI=%08x\n", tlli);
2674 return -EINVAL;
2675 }
2676
Jacob Erlbeck7dba11f2014-12-22 17:58:18 +01002677 if (mmctx->mm_state != GMM_REGISTERED_NORMAL &&
2678 mmctx->mm_state != GMM_REGISTERED_SUSPENDED) {
Daniel Willmann46553142014-09-03 17:46:44 +02002679 LOGMMCTXP(LOGL_NOTICE, mmctx, "SUSPEND request while state "
Harald Welte5bfe4992010-06-09 11:22:47 +02002680 "!= REGISTERED (TLLI=%08x)\n", tlli);
2681 return -EINVAL;
2682 }
2683
2684 /* Transition from REGISTERED_NORMAL to REGISTERED_SUSPENDED */
2685 mmctx->mm_state = GMM_REGISTERED_SUSPENDED;
2686 return 0;
2687}
2688
2689int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
2690 uint8_t suspend_ref)
2691{
2692 struct sgsn_mm_ctx *mmctx;
2693
2694 /* FIXME: make use of suspend reference? */
2695
2696 mmctx = sgsn_mm_ctx_by_tlli(tlli, raid);
2697 if (!mmctx) {
2698 LOGP(DMM, LOGL_NOTICE, "RESUME request for unknown "
2699 "TLLI=%08x\n", tlli);
2700 return -EINVAL;
2701 }
2702
Jacob Erlbeck7dba11f2014-12-22 17:58:18 +01002703 if (mmctx->mm_state != GMM_REGISTERED_NORMAL &&
2704 mmctx->mm_state != GMM_REGISTERED_SUSPENDED) {
Daniel Willmann46553142014-09-03 17:46:44 +02002705 LOGMMCTXP(LOGL_NOTICE, mmctx, "RESUME request while state "
Harald Welte5bfe4992010-06-09 11:22:47 +02002706 "!= SUSPENDED (TLLI=%08x)\n", tlli);
2707 /* FIXME: should we not simply ignore it? */
2708 return -EINVAL;
2709 }
2710
2711 /* Transition from SUSPENDED to NORMAL */
2712 mmctx->mm_state = GMM_REGISTERED_NORMAL;
2713 return 0;
2714}
Daniel Willmann6b7b3192016-05-21 00:53:42 +02002715
2716#ifdef BUILD_IU
2717int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp, bool use_x213_nsap)
2718{
2719 struct msgb *msg;
2720 struct sgsn_mm_ctx *mm = pdp->mm;
2721 struct ue_conn_ctx *uectx;
2722 uint32_t ggsn_ip;
2723
2724 uectx = mm->iu.ue_ctx;
2725
2726 /* Get the IP address for ggsn user plane */
2727 memcpy(&ggsn_ip, pdp->lib->gsnru.v, pdp->lib->gsnru.l);
2728 ggsn_ip = htonl(ggsn_ip);
2729
2730 LOGP(DRANAP, LOGL_DEBUG, "Assigning RAB: rab_id=%d, ggsn_ip=%x,"
2731 " teid_gn=%x, use_x213_nsap=%d\n",
2732 rab_id, ggsn_ip, pdp->lib->teid_gn, use_x213_nsap);
2733
2734 msg = ranap_new_msg_rab_assign_data(rab_id, ggsn_ip,
2735 pdp->lib->teid_gn, use_x213_nsap);
2736 msg->l2h = msg->data;
2737 return iu_rab_act(uectx, msg);
2738}
2739#endif