2 * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 /* allocate GSM 04.08 mobility management message (betreen MM and RR) */
27 static struct msgb *gsm48_mm_msgb_alloc(void)
31 msg = msgb_alloc_headroom(GSM48_MM_ALLOC_SIZE, GSM48_MM_ALLOC_HEADROOM,
43 /* Set new MM state, also new substate in case of MM IDLE state. */
44 static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate)
46 DEBUGP(DMM, "(ms %s) new state %s", mm->ms, mm_state_names[mm->state]);
47 if (mm->state == GSM48_MM_ST_MM_ILDE)
48 DEBUGP(DMM, " substate %s", mm_substate_names[mm->substate]);
49 DEBUGP(DMM, "-> %s", mm_state_names[state]);
50 if (state == GSM48_MM_ST_MM_ILDE)
51 DEBUGP(DMM, " substate %s", mm_substate_names[substate]);
55 mm->substate = substate;
58 /* 4.2.3 when returning to MM IDLE state, this function is called */
59 static int gsm48_mm_return_idle(struct osmocom_ms *ms)
61 struct gsm_subscriber *subsr = &ms->subscr;
62 struct gsm48_mmlayer *mm == &ms->mmlayer;
63 struct gsm322_cellsel *cs = &ms->cellsel;
66 if (!subscr->sim_valid) {
67 DEBUGP(DMM, "(ms %s) SIM invalid as returning to IDLE",
69 /* imsi detach due to power off */
70 if (ms->mm->power_off) {
73 nmsg = gsm48_mm_msgb_alloc(GSM48_MM_EVENT_POWER_OFF);
76 gsm48_mm_sendevent(ms, nmsg);
79 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_NO_IMSI);
85 if (cs->state != GSM_C3_CAMPED_NORMALLY
86 && cs->state != GSM_C7_CAMPED_ANY_CELL) {
87 DEBUGP(DMM, "(ms %s) No cell found as returning to IDLE",
89 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_PLMN_SEARCH);
94 /* return from location update with "Roaming not allowed" */
95 if (mm->state == GSM48_MM_ST_LOC_UPD_REJ && mm->lupd_rej_cause == 13) {
96 DEBUGP(DMM, "(ms %s) Roaming not allowed as returning to IDLE",
98 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_PLMN_SEARCH);
103 /* selected cell equals the registered LAI */
104 if (subscr->plmn_valid && cs->mcc == subscr->plmn_mcc
105 && cs->mnc == subscr->plmn_mnc && cs->lac == subscr->plmn_lac) {
106 DEBUGP(DMM, "(ms %s) We are in registered LAI as returning to IDLE",
109 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_NORMAL_SERVICE);
114 /* location update allowed */
115 ** is it enough to use the CAMPED_NORMALLY state to check if location update is allowed
116 if (cs->state == GSM_C3_CAMPED_NORMALLY)
117 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_LOC_UPD_NEEDED);
119 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_LIMITED_SERVICE);
128 /* sending MM STATUS message */
129 static int gsm48_mm_tx_mm_status(struct osmocom_ms *ms, u_int8_t reject)
132 struct gsm48_hdr *ngh;
133 u_int8_t *reject_cause;
135 nmsg = gsm48_mm_msgb_alloc();
138 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
139 reject_cause = msgb_put(nmsg, 1);
141 gh->proto_discr = GSM48_PDISC_MM;
142 gh->msg_type = GSM48_MT_MM_STATUS;
143 *reject_cause = reject;
145 return gsm48_mm_sendmsg(ms, nmsg);
148 /* 4.3.1.2 sending TMSI REALLOCATION COMPLETE message */
149 static int gsm48_mm_tx_tmsi_reall_cpl(struct osmocom_ms *ms)
152 struct gsm48_hdr *ngh;
154 nmsg = gsm48_mm_msgb_alloc();
157 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
159 gh->proto_discr = GSM48_PDISC_MM;
160 gh->msg_type = GSM48_MT_MM_TMSI_REALL_COMPL;
162 return gsm48_mm_sendmsg(ms, nmsg);
165 /* 4.3.1 TMSI REALLOCATION COMMAND is received */
166 static int gsm48_mm_rx_tmsi_realloc_cmd(struct osmocom_ms *ms, struct msgb *msg)
168 struct gsm_subscriber *subscr = &ms->subscr;
169 struct gsm48_hdr *gh = msgb_l3(msg);
170 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
171 struct gsm48_loc_area_id *lai = gh->data;
173 char *str_cur = string;
176 if (payload_len < sizeof(struct gsm48_loc_area_id) + 2) {
178 DEBUGP(DMM, "Short read of TMSI reallocation command accept message error.\n");
182 decode_lai(lai, &subscr->tmsi_mcc, &subscr->tmsi_mnc, &subscr->tmsi_lac);
184 mi = gh->data + sizeof(struct gsm48_loc_area_id);
185 mi_type = mi[1] & GSM_MI_TYPE_MASK;
187 case GSM_MI_TYPE_TMSI:
188 if (gh->data + sizeof(struct gsm48_loc_area_id) < 6
191 memcpy(&tmsi, mi+2, 4);
192 subscr->tmsi = ntohl(tmsi);
193 subscr->tmsi_valid = 1;
194 DEBUGP(DMM, "TMSI 0x%08x assigned.\n", subscr->tmsi);
195 gsm48_mm_tx_tmsi_reall_cpl(ms);
197 case GSM_MI_TYPE_IMSI:
198 subscr->tmsi_valid = 0;
199 DEBUGP(DMM, "TMSI removed.\n");
200 gsm48_mm_tx_tmsi_reall_cpl(ms);
203 DEBUGP(DMM, "TMSI reallocation with unknown MI type %d.\n", mi_type);
204 gsm48_mm_tx_mm_status(ms, GSM48_REJECT_INCORRECT_MESSAGE);
206 return 0; /* don't store in SIM */
210 store / remove from sim
216 /* 4.3.2.2 AUTHENTICATION REQUEST is received */
217 static int gsm48_mm_rx_auth_req(struct osmocom_ms *ms, struct msgb *msg)
219 struct gsm_subscriber *subscr = &ms->subscr;
220 struct gsm48_hdr *gh = msgb_l3(msg);
221 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
222 struct gsm48_auth_req *ar = gh->data;
224 if (payload_len < sizeof(struct gsm48_auth_req)) {
225 DEBUGP(DMM, "Short read of authentication request message error.\n");
229 /* SIM is not available */
230 if (!subscr->sim_valid)
231 return gsm48_mm_tx_mm_status(ms,
232 GSM48_REJECT_MSG_NOT_COMPATIBLE);
234 /* key_seq and random */
237 (..., ar->key_seq, ar->rand);
240 /* wait for auth response event from SIM */
244 /* 4.3.2.2 sending AUTHENTICATION RESPONSE */
245 static int gsm48_mm_tx_auth_rsp(struct osmocom_ms *ms, struct gsm48_mmevent *ev)
247 struct msgb *msg = gsm48_mm_msgb_alloc();
248 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
249 struct gsm_mmevent *mmevent = arg;
250 u_int8_t *sres = msgb_put(msg, 4);
252 gh->proto_discr = GSM48_PDISC_MM;
253 gh->msg_type = GSM48_MT_MM_AUTH_RSP;
256 memcpy(sres, ev->sres, 4);
258 return gsm48_mm_sendmsg(ms, nmsg);
261 /* 4.3.2.5 AUTHENTICATION REJECT is received */
262 static int gsm48_mm_rx_auth_rej(struct osmocom_ms *ms, struct msgb *msg)
264 struct gsm_subscriber *subscr = &ms->subscr;
267 subscr->sim_valid = 0;
269 /* TMSI and LAI invalid */
270 subscr->tmsi_valid = 0;
276 new_sim_ustate(ms, GSM_MMUSTATE_U3_ROAMING_NA);
280 sim: delete key seq number
281 sim: set update status
284 /* abort IMSI detach procedure */
285 if (mm->state == GSM48_MM_ST_IMSI_DETACH_INIT) {
286 /* send abort to RR */
287 todo gsm48_sendrr(sm, abort, RR_ABORT_REQ);
289 /* return to MM IDLE / No SIM */
290 gsm48_mm_return_idle(ms);
297 /* 4.3.3.1 IDENTITY REQUEST is received */
298 static int gsm48_mm_rx_id_req(struct osmocom_ms *ms, struct msgb *msg)
300 struct gsm48_hdr *gh = msgb_l3(msg);
301 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
304 if (payload_len < 1) {
305 DEBUGP(DMM, "Short read of identity request message error.\n");
311 /* check if request can be fulfilled */
312 if (!subscr->sim_valid)
313 return gsm48_mm_tx_mm_status(ms,
314 GSM48_REJECT_MSG_NOT_COMPATIBLE);
315 if (mi_type == GSM_MI_TYPE_TMSI && !subscr->tmsi_valid)
316 return gsm48_mm_tx_mm_status(ms,
317 GSM48_REJECT_MSG_NOT_COMPATIBLE);
319 gsm48_mm_tx_id_rsp(ms, mi_type);
322 /* send IDENTITY RESPONSE message */
323 static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, u_int8_t mi_type)
325 struct gsm_subscriber *subscr = &ms->subscr;
327 struct gsm48_hdr *ngh;
328 u_int8_t buf[11]; /* 1+9 should be enough, but it is not really clear */
331 nmsg = gsm48_mm_msgb_alloc();
334 ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
336 ngh->proto_discr = GSM48_PDISC_MM;
337 ngh->msg_type = GSM48_MT_MM_ID_RSP;
341 case GSM_MI_TYPE_TMSI:
342 gsm48_generate_mid_from_tmsi(buf, subscr->tmsi);
344 case GSM_MI_TYPE_IMSI:
345 gsm48_generate_mid_from_imsi(buf, subscr->imsi);
347 case GSM_MI_TYPE_IMEI:
348 case GSM_MI_TYPE_IMEISV:
349 gsm48_generate_mid_from_imsi(buf, subscr->imeisv);
351 case GSM_MI_TYPE_NONE:
353 buf[0] = GSM48_IE_MOBILE_ID;
355 buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
359 ie = msgb_put(nmsg, 1 + buf[1]);
360 memcpy(ie, buf + 1, 1 + buf[1]);
362 return gsm48_mm_sendmsg(ms, nmsg);
368 the process above is complete
369 ------------------------------------------------------------------------------
373 /* initialize Mobility Management process */
374 int gsm48_init(struct osmocom_ms *ms)
376 struct gsm48_mmlayer *mm == &ms->mmlayer;
378 memset(mm, 0, sizeof(*mm));
381 mm->state = GSM48_MM_ST_MM_ILDE;
382 mm->sstate = GSM48_MM_SST_PLMN_SEARCH;
385 INIT_LLIST_HEAD(&mm->up_queue);
391 static void new_sim_ustate(struct gsm_subscriber *subscr, int state)
393 DEBUGP(DMM, "(ms %s) new state %s -> %s\n", subscr->ms,
394 subscr_ustate_names[subscr->ustate], subscr_ustate_names[state]);
396 subscr->ustate = state;
399 /* IMSI detach indication message from upper layer */
400 static int gsm48_mm_tx_imsi_detach_ind(struct osmocom_ms *ms, void *arg)
402 struct msgb *msg = gsm48_mm_msgb_alloc();
403 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
404 struct gsm48_classmark1 *classmark1 = msgb_put(msg, sizeof(struct gsm48_classmark1));
405 u_int8_t buf[11]; /* 1+9 should be enough, but it is not really clear */
409 gh->proto_discr = GSM48_PDISC_MM;
410 gh->msg_type = GSM48_MT_MM_IMSI_DETACH_IND;
412 while(translist not empty)
414 todo: release trans must send a release to it's application entitity
417 gsm48_start_mm_timer(mm, 0x3220, GSM48_T3220_MS);
419 new_mm_state(mm, GSM48_MM_ST_IMSI_DETACH_INIT, 0);
422 memcpy(classmark1, , sizeof(struct gsm48_classmark1));
425 case GSM_MI_TYPE_TMSI:
426 gsm48_generate_mid_from_tmsi(buf, tmsi);
428 case GSM_MI_TYPE_IMSI:
429 gsm48_generate_mid_from_imsi(buf, imsi);
431 case GSM_MI_TYPE_IMEI:
432 case GSM_MI_TYPE_IMEISV:
433 gsm48_generate_mid_from_imsi(buf, imeisv);
435 case GSM_MI_TYPE_NONE:
437 buf[0] = GSM48_IE_MOBILE_ID;
439 buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
443 ie = msgb_put(msg, 1 + buf[1]);
444 memcpy(ie, buf + 1, 1 + buf[1]);
446 return gsm48_mm_sendmsg(ms, nmsg);
448 oops: this must be wrong return gsm48_mm_return_idle(ms);
455 static int gsm48_mm_imsi_detach_no_rr(struct osmocom_ms *ms, void *arg)
459 new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_IMSI_D, 0);
463 /* cm reestablish request message from upper layer */
464 static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, void *arg)
466 struct msgb *msg = gsm48_mm_msgb_alloc();
467 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
468 struct gsm48_service_request *serv_req = msgb_put(msg, 1 + 1 + sizeof(struct gsm48_classmark2));
469 u_int8_t *classmark2 = ((u_int8_t *)serv_req) + 1;
474 gh->proto_discr = GSM48_PDISC_MM;
475 gh->msg_type = GSM48_MT_MM_CM_SERV_REQ;
478 serv_req->cm_service_type =
479 serv_req->cypher_key_seq =
481 classmark2[0] = sizeof(struct gsm48_classmark2);
482 memcpy(classmark2+1, , sizeof(struct gsm48_classmark2));
485 case GSM_MI_TYPE_TMSI:
486 gsm48_generate_mid_from_tmsi(buf, tmsi);
488 case GSM_MI_TYPE_IMSI:
489 gsm48_generate_mid_from_imsi(buf, imsi);
491 case GSM_MI_TYPE_IMEI:
492 case GSM_MI_TYPE_IMEISV:
493 gsm48_generate_mid_from_imsi(buf, imeisv);
495 case GSM_MI_TYPE_NONE:
497 buf[0] = GSM48_IE_MOBILE_ID;
499 buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
503 ie = msgb_put(msg, 1 + buf[1]);
504 memcpy(ie, buf + 1, 1 + buf[1]);
505 /* prio is optional for eMLPP */
507 return gsm48_mm_sendmsg(ms, nmsg);
510 /* cm service abort message from upper layer */
511 static int gsm48_mm_tx_cm_service_abort(struct osmocom_ms *ms, void *arg)
513 struct msgb *msg = gsm48_mm_msgb_alloc();
514 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
517 gh->proto_discr = GSM48_PDISC_MM;
518 gh->msg_type = GSM48_MT_MM_CM_SERV_ABORT;
520 return gsm48_mm_sendmsg(ms, nmsg);
523 /* cm reestablish request message from upper layer */
524 static int gsm48_mm_tx_cm_reest_req(struct osmocom_ms *ms, void *arg)
526 struct msgb *msg = gsm48_mm_msgb_alloc();
527 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
528 u_int8_t *key_seq = msgb_put(msg, 1);
529 u_int8_t *classmark2 = msgb_put(msg, 1 + sizeof(struct gsm48_classmark2));
534 gh->proto_discr = GSM48_PDISC_MM;
535 gh->msg_type = GSM48_MT_MM_CM_REEST_REQ;
540 classmark2[0] = sizeof(struct gsm48_classmark2);
541 memcpy(classmark2+1, , sizeof(struct gsm48_classmark2));
544 case GSM_MI_TYPE_TMSI:
545 gsm48_generate_mid_from_tmsi(buf, tmsi);
547 case GSM_MI_TYPE_IMSI:
548 gsm48_generate_mid_from_imsi(buf, imsi);
550 case GSM_MI_TYPE_IMEI:
551 case GSM_MI_TYPE_IMEISV:
552 gsm48_generate_mid_from_imsi(buf, imeisv);
554 case GSM_MI_TYPE_NONE:
556 buf[0] = GSM48_IE_MOBILE_ID;
558 buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
562 ie = msgb_put(msg, 1 + buf[1]);
563 memcpy(ie, buf + 1, 1 + buf[1]);
565 if (mi_type == GSM_MI_TYPE_TMSI) {
566 buf[0] = GSM48_IE_LOC_AREA;
567 gsm0408_generate_lai((struct gsm48_loc_area_id *)(buf + 1),
568 country_code, network_code, location_area_code);
570 ie = msgb_put(msg, 1 + sizeof(struct gsm48_loc_area_id));
571 memcpy(ie, buf, 1 + sizeof(struct gsm48_loc_area_id));
574 return gsm48_mm_sendmsg(ms, nmsg);
577 /* initiate a location update */
578 static int gsm48_mm_loc_update_no_rr(struct osmocom_ms *ms, void *arg)
582 /* stop all timers 4.4.4.1 */
583 gsm48_stop_cc_timer(mm, 0x3210);
584 gsm48_stop_cc_timer(mm, 0x3211);
585 gsm48_stop_cc_timer(mm, 0x3212);
586 gsm48_stop_cc_timer(mm, 0x3213);
588 memset(est, 0, sizeof(struct gsm_rr));
590 gsm48_sendrr(sm, est, RR_EST_REQ);
592 new_mm_state(ms, GSM48_MM_ST_WAIT_RR_CONN_LUPD, 0);
595 /* initiate an IMSI detach */
596 static int gsm48_mm_imsi_detach(struct osmocom_ms *ms, void *arg)
601 /* initiate an mm connection 4.5.1.1 */
602 static int gsm48_mm_init_mm_no_rr(struct osmocom_ms *ms, void *arg)
604 int emergency = 0, cause;
605 struct gsm_mm *mmmsg;
606 struct gsm_trans *trans = mmmsg->trans;
611 if (msg_type == MMCC_EST_REQ && mmmsg->emergency)
614 if (!emergency && mm->mmustate != MMUSTATE_U1_UPDATED) {
619 mmmsg->cause = cause;
620 return mm_recvmsg(ms, trans, MMCC_REL_IND, mmmsg);
622 mmmsg->cause = cause;
623 return mm_recvmsg(ms, trans, MMSS_REL_IND, mmmsg);
625 mmmsg->cause = cause;
626 return mm_recvmsg(ms, trans, MMSMS_REL_IND, mmmsg);
633 switch (mm->substate) {
634 case GSM48_MM_SST_NORMAL_SERVICE:
635 case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
636 break; /* allow when normal */
637 case GSM48_MM_SST_ATTEMPT_UPDATE:
638 /* store mm request if attempting to update */
640 store mm connection request (status waiting)
641 return trigger location update
646 /* reject if not emergency */
654 memset(est, 0, sizeof(struct gsm_rr));
655 est->cause = todo establishment cause;
656 todo: add msgb with cm_service request. todo this, change the cm_serv_req function into a general msgb-generation message for this and other functions (like service request during mm connection)
658 gsm48_sendrr(sm, est, RR_EST_REQ);
659 new_mm_state(ms, GSM48_MM_ST_WAIT_RR_CONN_MM_CON, 0);
664 static int gsm48_mm_init_mm_first(struct osmocom_ms *ms, void *arg)
666 int emergency = 0, cause;
667 struct gsm_mm *mmmsg;
668 struct gsm_trans *trans = mmmsg->trans;
671 send cm service request
673 gsm48_stop_cc_timer(mm, 0x3241);
674 gsm48_start_mm_timer(mm, 0x3230, GSM48_T3220_MS);
675 new_mm_state(ms, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
678 static int gsm48_mm_init_mm_more(struct osmocom_ms *ms, void *arg)
680 int emergency = 0, cause;
681 struct gsm_mm *mmmsg;
682 struct gsm_trans *trans = mmmsg->trans;
685 send cm service request
687 gsm48_stop_cc_timer(mm, 0x3241);
688 gsm48_start_mm_timer(mm, 0x3230, GSM48_T3220_MS);
689 new_mm_state(ms, GSM48_MM_ST_WAIT_ADD_OUT_MM_CONN, 0);
692 /* initiate an mm connection other cases */
693 static int gsm48_mm_init_mm_other(struct osmocom_ms *ms, void *arg)
696 struct gsm_mm *mmmsg;
697 struct gsm_trans *trans = mmmsg->trans;
701 mmmsg->cause = cause;
702 return mm_recvmsg(ms, trans, MMCC_REL_IND, mmmsg);
704 mmmsg->cause = cause;
705 return mm_recvmsg(ms, trans, MMSS_REL_IND, mmmsg);
707 mmmsg->cause = cause;
708 return mm_recvmsg(ms, trans, MMSMS_REL_IND, mmmsg);
714 /* respond to paging */
715 static int gsm48_mm_paging(struct osmocom_ms *ms, void *arg)
720 /* abort RR connection */
721 static int gsm48_mm_paging(struct osmocom_ms *ms, void *arg)
725 memset(abort, 0, sizeof(struct gsm_rr));
726 gsm48_sendrr(sm, abort, RR_ABORT_REQ);
729 /* abort RR connection */
730 static int gsm48_mm_classm_chg(struct osmocom_ms *ms, void *arg)
732 if (rr->state == in the dedicated without transitions)
733 gsm_rr_tx_cm_change(sm, abort, RR_ABORT_REQ);
736 /* state trasitions for mobile managemnt messages (upper layer / events) */
737 static struct eventstate {
741 int (*rout) (struct gsm_trans *trans, void *arg);
742 } eventstatelist[] = {
744 ** todo: check if there is a senders of every event
745 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
746 GSM48_MM_EVENT_NEW_LAI, gsm48_mm_loc_update_no_rr},
747 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
748 GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_update_no_rr},
749 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
750 GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_update_no_rr},
751 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
752 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_update_no_rr},
753 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
754 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach},
755 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
756 MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
757 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
758 MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
759 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
760 MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
761 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
762 GSM48_MM_EVENT_PAGING, gsm48_mm_paging},
764 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
765 GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_update_no_rr},
766 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
767 GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_update_no_rr},
768 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
769 GSM48_MM_EVENT_NEW_LAI, gsm48_mm_loc_update_no_rr},
770 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
771 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_update_no_rr},
772 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
773 MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
774 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
775 GSM48_MM_EVENT_PAGING, gsm48_mm_paging},
777 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
778 GSM48_MM_EVENT_NEW_LAI, gsm48_mm_loc_update_no_rr},
779 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
780 MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
781 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
782 GSM48_MM_EVENT_PAGING, gsm48_mm_paging},
784 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_IMSI),
785 MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
787 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
788 GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_update_no_rr},
789 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
790 GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_update_no_rr},
791 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
792 GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_update_no_rr},
793 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
794 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach},
795 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
796 MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
797 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
798 MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
799 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
800 MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
801 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
802 GSM48_MM_EVENT_PAGING, gsm48_mm_paging},
804 {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
805 MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
807 {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), 0,
808 MMCC_EST_REQ, gsm48_mm_init_mm_first},
809 {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), 0,
810 MMSS_EST_REQ, gsm48_mm_init_mm_first},
811 {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), 0,
812 MMSMS_EST_REQ, gsm48_mm_init_mm_first},
813 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), 0,
814 MMCC_EST_REQ, gsm48_mm_init_mm_more},
815 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), 0,
816 MMSS_EST_REQ, gsm48_mm_init_mm_more},
817 {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), 0,
818 MMSMS_EST_REQ, gsm48_mm_init_mm_more},
820 MMCC_EST_REQ, gsm48_mm_init_mm_other},
822 MMSS_EST_REQ, gsm48_mm_init_mm_other},
824 MMSMS_EST_REQ, gsm48_mm_init_mm_other},
826 {ALL_STATES, ALL_STATES, /* 4.3.2.2 */
827 GSM48_MM_EVENT_AUTH_RESPONSE, gsm48_mm_tx_auth_rsp},
828 {SBIT(GSM48_MM_ST_LOC_UPD_INIT) | /* all states where RR active */
829 SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
830 SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
831 SBIT(GSM48_MM_ST_IMSI_DETACH_INIT) |
832 SBIT(GSM48_MM_ST_PROCESS_CM_SERV_P) |
833 SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD) |
834 SBIT(GSM48_MM_ST_LOC_UPD_REJ) |
835 SBIT(GSM48_MM_ST_WAIT_REEST) |
836 SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CONN) |
837 SBIT(GSM48_MM_ST_MM_CONN_ACTIVE_VGCS) |
838 SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES, /* 4.3.4.1 */
839 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_tx_imsi_detach_ind},
840 {ALL_STATES, ALL_STATES,
841 GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_no_rr},
842 {ALL_STATES, ALL_STATES,
843 GSM48_MM_EVENT_CLASSMARK_CHG, gsm48_mm_classm_chg},
844 todo all other states (sim removed)
846 {SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
847 GSM48_MM_EVENT_, gsm48_mm_tx},
850 {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD) | SBIT(GSM48_MM_ST_LOC_UPD_REJ), ALL_STATES,
851 GSM48_MM_EVENT_TIMEOUT_T3240, gsm48_mm_abort_rr},
853 {SBIT(GSM48_MM_ST_), ALL_STATES,
854 GSM48_MM_EVENT_, gsm48_mm_tx},
855 {SBIT(GSM48_MM_ST_), ALL_STATES,
856 GSM48_MM_EVENT_, gsm48_mm_tx},
857 {SBIT(GSM48_MM_ST_), ALL_STATES,
858 GSM48_MM_EVENT_, gsm48_mm_tx},
859 {SBIT(GSM48_MM_ST_), ALL_STATES,
860 GSM48_MM_EVENT_, gsm48_mm_tx},
861 {SBIT(GSM48_MM_ST_), ALL_STATES,
862 GSM48_MM_EVENT_, gsm48_mm_tx},
863 {SBIT(GSM48_MM_ST_), ALL_STATES,
864 GSM48_MM_EVENT_, gsm48_mm_tx},
865 {SBIT(GSM48_MM_ST_), ALL_STATES,
866 GSM48_MM_EVENT_, gsm48_mm_tx},
867 {SBIT(GSM48_MM_ST_), ALL_STATES,
868 GSM48_MM_EVENT_, gsm48_mm_tx},
872 (sizeof(eventstatelist) / sizeof(struct eventstate))
874 /* MM event handler */
875 int mm_event(struct osmocom_ms *ms, int msg_type, struct gsm48_mmevent *mmevent)
877 struct gsm48_mmlayer *mm = &ms->mmlayer;
878 int msg_type = mmevent->msg_type;
880 DEBUGP(DMM, "(ms %s) Received '%s' event in state %s", ms->name,
881 get_mmevent_name(msg_type), mm_state_names[mm->state]);
882 if (mm->state == GSM48_MM_ST_MM_ILDE)
883 DEBUGP(DMM, " substate %s", mm_substate_names[mm->substate]);
886 /* Find function for current state and message */
887 for (i = 0; i < EVENTSLLEN; i++)
888 if ((msg_type == eventstatelist[i].type)
889 && ((1 << mm->state) & eventstatelist[i].states)
890 && ((1 << mm->substate) & eventstatelist[i].substates))
892 if (i == EVENTSLLEN) {
893 DEBUGP(DMM, "Message unhandled at this state.\n");
897 rc = eventstatelist[i].rout(ms, msg_type, arg);
902 /* decode network name */
903 static int decode_network_name(char *name, int name_len,
906 u_int8_t in_len = lv[0];
913 /* must be CB encoded */
914 if ((lv[1] & 0x70) != 0x00)
917 padding = lv[1] & 0x03;
918 length = ((in_len - 1) * 8 - padding) / 7;
921 if (length >= name_len)
922 length = name_len - 1;
923 gsm_7bit_decode(name, lv + 2, length);
929 static char bcd2char(u_int8_t bcd)
934 return 'A' + (bcd - 0xa);
937 static int decode_lai(struct gsm48_loc_area_id *lai, u_int16_t *mcc, u_int16_t *mnc, u_int16_t *lac)
939 *mcc = bcd2char(lai->digits[0] & 0x0f) * 100
940 + bcd2char(lai->digits[0] >> 4) * 10
941 + bcd2char(lai->digits[1] & 0x0f);
942 *mnc = bcd2char(lai->digits[1] >> 4) * 100
943 + bcd2char(lai->digits[2] & 0x0f) * 10;
944 + bcd2char(lai->digits[2] >> 4);
945 *lac = ntohs(lai->lac);
948 /* mm info is received from lower layer */
949 static int gsm48_mm_rx_info(struct osmocom_ms *ms, struct msgb *msg)
951 struct gsm48_hdr *gh = msgb_l3(msg);
952 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
953 struct tlv_parsed tp;
955 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
957 if (TLVP_PRESENT(&tp, GSM48_IE_NAME_LONG)) {
958 decode_network_name(name_long, sizeof(name_long),
959 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
962 if (TLVP_PRESENT(&tp, GSM48_IE_NAME_SHORT)) {
963 decode_network_name(name_short, sizeof(name_short),
964 TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
968 /* location updating reject is received from lower layer */
969 static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg)
971 struct gsm48_hdr *gh = msgb_l3(msg);
972 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
974 if (payload_len < 1) {
975 DEBUGP(DMM, "Short read of location updating reject message error.\n");
979 reject_cause = *gh->data;
981 if (llist_empty(ms->trans)) {
982 DEBUGP(DMM, "Abort (cause #%d) while no MM connection is established.\n", reject_cause);
985 DEBUGP(DMM, "Abort (cause #%d) while MM connection is established.\n", reject_cause);
986 while(translist not empty)
988 todo: release trans must send a release to it's application entitity
989 todo: release must cause release of state 6 and transfer to state 9
992 if (reject_cause == 6) {
993 new_sim_ustate(ms, GSM_MMUSTATE_U3_ROAMING_NA);
996 sim: delete key seq number
997 sim: apply update state
1002 /* location updating accept is received from lower layer */
1003 static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg)
1005 struct gsm48_hdr *gh = msgb_l3(msg);
1006 struct gsm48_loc_area_id *lai = gh->data;
1007 u_int8_t *tlv_start = gh->data;
1008 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1009 struct tlv_parsed tp;
1011 if (payload_len < sizeof(struct gsm48_loc_area_id)) {a
1013 DEBUGP(DMM, "Short read of location updating accept message error.\n");
1016 tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_LOC_AREA, 0);
1018 decode_lai(lai, &ms->current_mcc, &ms->current->mnc, &ms->current_lac);
1020 remove from forbidden list
1022 nnnew_mmu_state(ms, GSM_MMUSTATE_U1_UPDATED);
1024 gsm48_stop_cc_timer(mm, 0x3210);
1026 tlv_parse(&tp, &rsl_att_tlvdef, gh->data + sizeof(struct gsm48_loc_area_id),
1027 payload_len - sizeof(struct gsm48_loc_area_id), 0, 0);
1029 if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
1030 mi = TLVP_VAL(&tp, GSM48_IE_FACILITY)-1;
1033 mi_type = mi[1] & GSM_MI_TYPE_MASK;
1035 case GSM_MI_TYPE_TMSI:
1036 if (gh->data + sizeof(struct gsm48_loc_area_id) < 6
1039 memcpy(&tmsi, mi+2, 4);
1040 ms->tmsi = ntohl(tmsi);
1043 gsm48_mm_tx_tmsi_reall_cpl(ms);
1045 case GSM_MI_TYPE_IMSI:
1047 todo: remove tmsi from sim
1048 gsm48_mm_tx_tmsi_reall_cpl(ms);
1051 DEBUGP(DMM, "TMSI reallocation with unknown MI type %d.\n", mi_type);
1054 /* follow on proceed */
1055 if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
1056 DEBUGP(DMM, "follow-on proceed not supported.\n");
1059 gsm48_start_mm_timer(mm, 0x3240, GSM48_T3240_MS);
1060 new_mm_state(ms, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
1065 /* location update reject is received from lower layer */
1066 static int gsm48_mm_rx_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
1068 struct gsm48_hdr *gh = msgb_l3(msg);
1069 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1071 if (payload_len < 1) {
1072 DEBUGP(DMM, "Short read of location update reject message error.\n");
1076 reject_cause = *gh->data;
1078 gsm48_stop_cc_timer(mm, 0x3210);
1080 /* store until RR is released */
1081 mm->lupd_rej_cause = reject_cause;
1083 gsm48_start_mm_timer(mm, 0x3240, GSM48_T3240_MS);
1084 new_mm_state(ms, GSM48_MM_ST_LOC_UPD_REJ, 0);
1087 /* abort is received from lower layer */
1088 static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg)
1090 struct gsm48_hdr *gh = msgb_l3(msg);
1091 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1093 if (payload_len < 1) {
1094 DEBUGP(DMM, "Short read of abort message error.\n");
1098 reject_cause = *gh->data;
1101 /* cm service reject is received from lower layer */
1102 static int gsm48_mm_rx_cm_service_rej(struct osmocom_ms *ms, struct msgb *msg)
1104 struct gsm48_hdr *gh = msgb_l3(msg);
1105 unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1107 if (payload_len < 1) {
1108 DEBUGP(DMM, "Short read of cm service reject message error.\n");
1112 reject_cause = *gh->data;
1115 /* cm service acknowledge is received from lower layer */
1116 static int gsm48_mm_rx_cm_service_ack(struct osmocom_ms *ms, struct msgb *msg)
1118 loop through all transactions. there must only be one in the "MMCONSTATE_CM_REQ", others are "MMCONSTATE_WAITING" or "MMCONSTATE_ACTIVE".
1119 then send mm est confirm
1120 change state to active
1122 todo: an indication by the RR that the cyphering mode setting procedure is complete, shall be treated as cm_serv_ack!!
1124 gsm48_stop_mm_timer(mm, 0x3230);
1125 new_mm_state(ms, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
1128 /* state trasitions for mobile managemnt messages (lower layer) */
1129 static struct mmdatastate {
1132 int (*rout) (struct gsm_trans *trans, struct msgb *msg);
1133 } mmdatastatelist[] = {
1134 {ALL_STATES, /* 4.3.1.2 */
1135 GSM48_MT_MM_TMSI_REALL_CMD, gsm48_mm_rx_tmsi_realloc_cmd},
1136 {ALL_STATES, /* 4.3.2.2 */
1137 GSM48_MT_MM_AUTH_REQ, gsm48_mm_rx_auth_req},
1138 {ALL_STATES, /* 4.3.2.5 */
1139 GSM48_MT_MM_AUTH_REJ, gsm48_mm_rx_auth_rej},
1140 {ALL_STATES, /* 4.3.3.2 */
1141 GSM48_MT_MM_ID_REQ, gsm48_mm_rx_id_req},
1142 {ALL_STATES, /* 4.3.5.2 */
1143 GSM48_MT_MM_ABORT, gsm48_mm_rx_abort},
1144 {ALL_STATES, /* 4.3.6.2 */
1145 GSM48_MT_MM_INFO, gsm48_mm_rx_info},
1146 {GSM48_MM_ST_LOC_UPD_INIT, /* 4.4.4.5 */
1147 GSM48_MT_MM_LOC_UPD_ACCEPT, gsm48_mm_rx_loc_upd_acc},
1148 {GSM48_MM_ST_LOC_UPD_INIT, /* 4.4.4.7 */
1149 GSM48_MT_MM_LOC_UPD_REJECT, gsm48_mm_rx_loc_upd_rej},
1150 {ALL_STATES, /* 4.5.1.1 */
1151 GSM48_MT_MM_, gsm48_mm_rx_cm_service_ack},
1153 GSM48_MT_MM_, gsm48_mm_rx_},
1155 GSM48_MT_MM_, gsm48_mm_rx_},
1157 GSM48_MT_MM_, gsm48_mm_rx_},
1160 GSM48_MT_MM_, gsm48_mm_rx_},
1163 #define DMMATASLLEN \
1164 (sizeof(mmdatastatelist) / sizeof(struct mmdatastate))
1166 static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
1168 struct gsm48_hdr *gh = msgb_l3(msg);
1169 int msg_type = gh->msg_type & 0xbf;
1171 /* pull the MM header */
1172 msgb_pull(msg, sizeof(struct gsm48_mm_hdr));
1174 /* forward message */
1176 case GSM48_PDISC_MM:
1177 break; /* follow the selection proceedure below */
1179 case GSM48_PDISC_CC:
1180 /* push new header */
1181 msgb_push(msg, sizeof(struct gsm48_cc_hdr));
1182 cch = (struct gsm48_cc_hdr *)msg->data;
1183 cch->msg_type = MM_DATA_IND;
1185 return gsm48_cc_upmsg(ms, msg);
1188 case GSM48_PDISC_SMS:
1189 /* push new header */
1190 msgb_push(msg, sizeof(struct gsm48_sms_hdr));
1191 smsh = (struct gsm48_smscc_hdr *)msg->data;
1192 smsh->msg_type = MM_DATA_IND;
1194 return gsm48_sms_upmsg(ms, msg);
1198 DEBUGP(DRR, "Protocol type 0x%02x unsupported.\n", pdisc);
1203 DEBUGP(DMM, "(ms %s) Received '%s' in MM state %s\n", ms->name,
1204 gsm48_mm_msg_name(msg_type), mm_state_names[mm->state]);
1206 /* find function for current state and message */
1207 for (i = 0; i < MMDATASLLEN; i++)
1208 if ((msg_type == mmdatastatelist[i].type)
1209 && ((1 << mm->state) & mmdatastatelist[i].states))
1211 if (i == MMDATASLLEN) {
1212 DEBUGP(DMM, "Message unhandled at this state.\n");
1217 rc = mmdatastatelist[i].rout(ms, msg);
1224 /* timeout events of all timers */
1225 static void gsm48_mm_t3210(void *arg)
1227 struct gsm48_mmlayer *mm = arg;
1228 mm_event(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3210);
1230 static void gsm48_mm_t3211(void *arg)
1232 struct gsm48_mmlayer *mm = arg;
1233 mm_event(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3211);
1235 static void gsm48_mm_t3212(void *arg)
1237 struct gsm48_mmlayer *mm = arg;
1238 mm_event(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3212);
1240 static void gsm48_mm_t3213(void *arg)
1242 struct gsm48_mmlayer *mm = arg;
1243 mm_event(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3213);
1246 /* RR is esablised during location update */
1247 static int gsm48_mm_est_loc_upd(struct osmocom_ms *ms, struct gsm_rr *est)
1250 struct msgb *msg = gsm48_mm_msgb_alloc();
1251 struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
1252 struct gsm48_loc_upd *loc_upd = msgb_put(msg, 7);
1253 u_int8_t *classmark1 = ((u_int8_t *)loc_upd) + 6;
1257 gsm48_start_mm_timer(mm, 0x3210, GSM48_T3210_MS);
1258 new_mm_state(ms, GSM48_MM_ST_LOC_UPD_INIT, 0);
1261 gh->proto_discr = GSM48_PDISC_MM;
1262 gh->msg_type = GSM48_MT_MM_LOC_UPD_REQ;
1268 memcpy(classmark1, , sizeof(struct gsm48_classmark1));
1270 gsm0408_generate_lai(loc_upd->lai,
1271 country_code, network_code, location_area_code);
1274 case GSM_MI_TYPE_TMSI:
1275 gsm48_generate_mid_from_tmsi(buf, tmsi);
1277 case GSM_MI_TYPE_IMSI:
1278 gsm48_generate_mid_from_imsi(buf, imsi);
1280 case GSM_MI_TYPE_IMEI:
1281 case GSM_MI_TYPE_IMEISV:
1282 gsm48_generate_mid_from_imsi(buf, imeisv);
1284 case GSM_MI_TYPE_NONE:
1286 buf[0] = GSM48_IE_MOBILE_ID;
1288 buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
1292 ie = msgb_put(msg, 1 + buf[1]);
1293 memcpy(ie, buf + 1, 1 + buf[1]);
1295 return gsm48_mm_sendmsg(ms, nmsg);
1298 /* RR is released after location update reject */
1299 static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct gsm_rr *rel)
1301 struct gsm48_mmlayer *mm = &ms->mmlayer;
1303 struct gsm322_msg *ngm = msg->data;
1306 switch (mm->lupd_rej_cause) {
1310 attempt_counter = 0;
1315 new_sim_ustate(ms, GSM_MMUSTATE_U3_ROAMING_NA);
1318 sim: delete key seq number
1319 sim: apply update state
1323 /* forbidden list */
1324 switch (mm->lupd_rej_cause) {
1328 /* sim becomes invalid */
1329 subscr->sim_valid = 0;
1332 add_forbidden_list(ms, FORBIDDEN_PLMN, lai);
1335 add_forbidden_list(ms, FORBIDDEN_LOC_AREA_RPOS, lai);
1338 add_forbidden_list(ms, FORBIDDEN_LOC_AREA_ROAM, lai);
1345 nmsg = gsm322_msgb_alloc(GSM322_EVENT_LU_REJECT);
1348 ngm = (struct gsm322_msg *)nmsg->data;
1349 ngm->reject = mm->lupd_rej_cause;
1350 gsm322_sendmsg(ms, nmsg);
1352 /* return to IDLE, case 13 is also handled there */
1353 return gsm48_mm_return_idle(ms);
1356 /* RR is released in other states */
1357 static int gsm48_mm_rel_other(struct osmocom_ms *ms, struct gsm_rr *rel)
1360 ** tothink: shall we do this here or at radio ressource
1361 nmsg = gsm322_msgb_alloc(GSM322_EVENT_RET_IDLE);
1364 gsm322_sendmsg(ms, nmsg);
1366 return gsm48_mm_return_idle(ms);
1369 /* RR is esablised during mm connection */
1370 static int gsm48_mm_est_mm_con(struct osmocom_ms *ms, struct gsm_rr *est)
1372 loop through all transactions. there must only be one in the "MMCONSTATE_CM_REQ", others are "MMCONSTATE_WAITING" or "MMCONSTATE_ACTIVE".
1374 gsm48_start_mm_timer(mm, 0x3230, GSM48_T3220_MS);
1375 new_mm_state(ms, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
1378 /* state trasitions for radio ressource messages (lower layer) */
1379 static struct rrdatastate {
1382 int (*rout) (struct gsm_trans *trans, struct gsm_rr *msg);
1383 } rrdatastatelist[] = {
1384 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.1 */
1385 RR_ESTAB_CNF, gsm48_mm_est_loc_upd},
1386 {SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
1387 RR_REL_IND, gsm48_mm_rel_loc_upd_rej},
1389 RR_REL_IND, gsm48_mm_rel_other},
1390 {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), /* 4.5.1.1 */
1391 RR_ESTAB_CNF, gsm48_mm_est_mm_con},
1393 RR_DATA_IND, gsm48_mm_data_ind},
1396 #define RRDATASLLEN \
1397 (sizeof(rrdatastatelist) / sizeof(struct rrdatastate))
1399 static int gsm48_rcv_rr(struct osmocom_ms *ms, struct gsm_rr *rrmsg)
1401 struct gsm48_mmlayer *mm = &ms->mmlayer;
1402 int msg_type = rrmsg->msg_type;
1404 DEBUGP(DMM, "(ms %s) Received '%s' from RR in state %s\n", ms->name,
1405 gsm48_rr_msg_name(msg_type), mm_state_names[mm->state]);
1407 /* find function for current state and message */
1408 for (i = 0; i < RRDATASLLEN; i++)
1409 if ((msg_type == rrdatastatelist[i].type)
1410 && ((1 << mm->state) & rrdatastatelist[i].states))
1412 if (i == RRDATASLLEN) {
1413 DEBUGP(DMM, "Message unhandled at this state.\n");
1418 rc = rrdatastatelist[i].rout(ms, rrmsg);
1420 if (msg_type != RR_DATA_IND)
1426 /* dequeue messages from RR */
1427 int gsm48_mm_queue(struct osmocom_ms *ms)
1429 struct gsm48_mmlayer *mm = &ms->mmlayer;
1433 while ((msg = msgb_dequeue(&mm->up_queue))) {
1434 /* message is also freed here */
1435 gsm48_rcv_rr(ms, msg);
1436 work = 1; /* work done */
1443 wichtig: nur eine MM connection zur zeit, da ja auch nur ein cm-service-request laufen kann. die anderen werden dann als "waiting" deklariert.