Work on various L3 processes.
[osmocom-bb.git] / src / host / gsm48-andreas / gsm48_mm.c
1 /*
2  * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
3  *
4  * All Rights Reserved
5  *
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.
10  *
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.
15  *
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.
19  *
20  */
21
22 /*
23  * messages
24  */
25
26 /* allocate GSM 04.08 mobility management message (betreen MM and RR) */
27 static struct msgb *gsm48_mm_msgb_alloc(void)
28 {
29         struct msgb *msg;
30
31         msg = msgb_alloc_headroom(GSM48_MM_ALLOC_SIZE, GSM48_MM_ALLOC_HEADROOM,
32                 "GSM 04.08 MM");
33         if (!msg)
34                 return NULL;
35
36         return msg;
37 }
38
39 /*
40  * state transition
41  */
42
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)
45 {
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]);
52         DEBUGP(DMM, "\n");
53
54         mm->state = state;
55         mm->substate = substate;
56 }
57
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)
60 {
61         struct gsm_subscriber *subsr = &ms->subscr;
62         struct gsm48_mmlayer *mm == &ms->mmlayer;
63         struct gsm322_cellsel *cs = &ms->cellsel;
64
65         /* no sim present */
66         if (!subscr->sim_valid) {
67                 DEBUGP(DMM, "(ms %s) SIM invalid as returning to IDLE",
68                         ms->name);
69                 /* imsi detach due to power off */
70                 if (ms->mm->power_off) {
71                         struct msgb *nmsg;
72         
73                         nmsg = gsm48_mm_msgb_alloc(GSM48_MM_EVENT_POWER_OFF);
74                         if (!nmsg)
75                                 return -ENOMEM;
76                         gsm48_mm_sendevent(ms, nmsg);
77 ** do we need this
78                 }
79                 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_NO_IMSI);
80
81                 return 0;
82         }
83
84         /* no cell found */
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",
88                         ms->name);
89                 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_PLMN_SEARCH);
90
91                 return 0;
92         }
93
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",
97                         ms->name);
98                 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_PLMN_SEARCH);
99
100                 return 0;
101         }
102
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",
107                         ms->name);
108 ** todo 4.4.4.9
109                 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_NORMAL_SERVICE);
110
111                 return 0;
112         }
113
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);
118         else
119                 new_mm_state(mm, GSM48_MM_ST_IDLE, GSM48_MM_SST_LIMITED_SERVICE);
120
121         return 0;
122 }
123
124 /*
125  * process handlers
126  */
127
128 /* sending MM STATUS message */
129 static int gsm48_mm_tx_mm_status(struct osmocom_ms *ms, u_int8_t reject)
130 {
131         struct msgb *nmsg;
132         struct gsm48_hdr *ngh;
133         u_int8_t *reject_cause;
134
135         nmsg = gsm48_mm_msgb_alloc();
136         if (nmsg)
137                 return -ENOMEM;
138         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
139         reject_cause = msgb_put(nmsg, 1);
140
141         gh->proto_discr = GSM48_PDISC_MM;
142         gh->msg_type = GSM48_MT_MM_STATUS;
143         *reject_cause = reject;
144
145         return gsm48_mm_sendmsg(ms, nmsg);
146 }
147
148 /* 4.3.1.2 sending TMSI REALLOCATION COMPLETE message */
149 static int gsm48_mm_tx_tmsi_reall_cpl(struct osmocom_ms *ms)
150 {
151         struct msgb *nmsg;
152         struct gsm48_hdr *ngh;
153
154         nmsg = gsm48_mm_msgb_alloc();
155         if (nmsg)
156                 return -ENOMEM;
157         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
158
159         gh->proto_discr = GSM48_PDISC_MM;
160         gh->msg_type = GSM48_MT_MM_TMSI_REALL_COMPL;
161
162         return gsm48_mm_sendmsg(ms, nmsg);
163 }
164
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)
167 {
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;
172         u_int8_t mi_type;
173         char *str_cur = string;
174         u_int32_t tmsi;
175
176         if (payload_len < sizeof(struct gsm48_loc_area_id) + 2) {
177                 short:
178                 DEBUGP(DMM, "Short read of TMSI reallocation command accept message error.\n");
179                 return -EINVAL;
180         }
181         /* LAI */
182         decode_lai(lai, &subscr->tmsi_mcc, &subscr->tmsi_mnc, &subscr->tmsi_lac);
183         /* MI */
184         mi = gh->data + sizeof(struct gsm48_loc_area_id);
185         mi_type = mi[1] & GSM_MI_TYPE_MASK;
186         switch (mi_type) {
187         case GSM_MI_TYPE_TMSI:
188                 if (gh->data + sizeof(struct gsm48_loc_area_id) < 6
189                  || mi[0] < 5)
190                         goto short;
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);
196                 break;
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);
201                 break;
202         default:
203                 DEBUGP(DMM, "TMSI reallocation with unknown MI type %d.\n", mi_type);
204                 gsm48_mm_tx_mm_status(ms, GSM48_REJECT_INCORRECT_MESSAGE);
205
206                 return 0; /* don't store in SIM */
207         }
208
209 #ifdef TODO
210         store / remove from sim
211 #endif
212
213         return 0;
214 }
215
216 /* 4.3.2.2 AUTHENTICATION REQUEST is received */
217 static int gsm48_mm_rx_auth_req(struct osmocom_ms *ms, struct msgb *msg)
218 {
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;
223
224         if (payload_len < sizeof(struct gsm48_auth_req)) {
225                 DEBUGP(DMM, "Short read of authentication request message error.\n");
226                 return -EINVAL;
227         }
228
229         /* SIM is not available */
230         if (!subscr->sim_valid)
231                 return gsm48_mm_tx_mm_status(ms,
232                         GSM48_REJECT_MSG_NOT_COMPATIBLE);
233
234         /* key_seq and random */
235 #ifdef TODO
236         new key to sim:
237         (..., ar->key_seq, ar->rand);
238 #endif
239
240         /* wait for auth response event from SIM */
241         return 0;
242 }
243
244 /* 4.3.2.2 sending AUTHENTICATION RESPONSE */
245 static int gsm48_mm_tx_auth_rsp(struct osmocom_ms *ms, struct gsm48_mmevent *ev)
246 {
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);
251
252         gh->proto_discr = GSM48_PDISC_MM;
253         gh->msg_type = GSM48_MT_MM_AUTH_RSP;
254
255         /* SRES */
256         memcpy(sres, ev->sres, 4);
257
258         return gsm48_mm_sendmsg(ms, nmsg);
259 }
260
261 /* 4.3.2.5 AUTHENTICATION REJECT is received */
262 static int gsm48_mm_rx_auth_rej(struct osmocom_ms *ms, struct msgb *msg)
263 {
264         struct gsm_subscriber *subscr = &ms->subscr;
265
266         /* SIM invalid */
267         subscr->sim_valid = 0;
268
269         /* TMSI and LAI invalid */
270         subscr->tmsi_valid = 0;
271
272         /* key is invalid */
273         subscr->key_seq = 7;
274
275         /* update status */
276         new_sim_ustate(ms, GSM_MMUSTATE_U3_ROAMING_NA);
277
278 #ifdef TODO
279         sim: delete tmsi
280         sim: delete key seq number
281         sim: set update status
282 #endif
283
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);
288
289                 /* return to MM IDLE / No SIM */
290                 gsm48_mm_return_idle(ms);
291
292         }
293
294         return 0;
295 }
296
297 /* 4.3.3.1 IDENTITY REQUEST is received */
298 static int gsm48_mm_rx_id_req(struct osmocom_ms *ms, struct msgb *msg)
299 {
300         struct gsm48_hdr *gh = msgb_l3(msg);
301         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
302         u_int8_t mi_type;
303
304         if (payload_len < 1) {
305                 DEBUGP(DMM, "Short read of identity request message error.\n");
306                 return -EINVAL;
307         }
308         /* id type */
309         mi_type = *gh->data;
310
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);
318
319         gsm48_mm_tx_id_rsp(ms, mi_type);
320 }
321
322 /* send IDENTITY RESPONSE message */
323 static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, u_int8_t mi_type)
324 {
325         struct gsm_subscriber *subscr = &ms->subscr;
326         struct msgb *nmsg;
327         struct gsm48_hdr *ngh;
328         u_int8_t buf[11]; /* 1+9 should be enough, but it is not really clear */
329         u_int8_t *ie;
330
331         nmsg = gsm48_mm_msgb_alloc();
332         if (nmsg)
333                 return -ENOMEM;
334         ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
335
336         ngh->proto_discr = GSM48_PDISC_MM;
337         ngh->msg_type = GSM48_MT_MM_ID_RSP;
338
339         /* MI */
340         switch(mi_type) {
341         case GSM_MI_TYPE_TMSI:
342                 gsm48_generate_mid_from_tmsi(buf, subscr->tmsi);
343                 break;
344         case GSM_MI_TYPE_IMSI:
345                 gsm48_generate_mid_from_imsi(buf, subscr->imsi);
346                 break;
347         case GSM_MI_TYPE_IMEI:
348         case GSM_MI_TYPE_IMEISV:
349                 gsm48_generate_mid_from_imsi(buf, subscr->imeisv);
350                 break;
351         case GSM_MI_TYPE_NONE:
352         default:
353                 buf[0] = GSM48_IE_MOBILE_ID;
354                 buf[1] = 1;
355                 buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
356                 break;
357         }
358         /* MI as LV */
359         ie = msgb_put(nmsg, 1 + buf[1]);
360         memcpy(ie, buf + 1, 1 + buf[1]);
361
362         return gsm48_mm_sendmsg(ms, nmsg);
363 }
364
365
366
367
368 the process above is complete
369 ------------------------------------------------------------------------------
370 incomplete
371
372
373 /* initialize Mobility Management process */
374 int gsm48_init(struct osmocom_ms *ms)
375 {
376         struct gsm48_mmlayer *mm == &ms->mmlayer;
377
378         memset(mm, 0, sizeof(*mm));
379
380         /* 4.2.1.1 */
381         mm->state = GSM48_MM_ST_MM_ILDE;
382         mm->sstate = GSM48_MM_SST_PLMN_SEARCH;
383
384         /* init lists */
385         INIT_LLIST_HEAD(&mm->up_queue);
386
387         return 0;
388 }
389
390 to subscriber.c
391 static void new_sim_ustate(struct gsm_subscriber *subscr, int state)
392 {
393         DEBUGP(DMM, "(ms %s) new state %s -> %s\n", subscr->ms,
394                 subscr_ustate_names[subscr->ustate], subscr_ustate_names[state]);
395
396         subscr->ustate = state;
397 }
398
399 /* IMSI detach indication message from upper layer */
400 static int gsm48_mm_tx_imsi_detach_ind(struct osmocom_ms *ms, void *arg)
401 {
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 */
406         u_int8_t *ie;
407
408         msg->lchan = lchan;
409         gh->proto_discr = GSM48_PDISC_MM;
410         gh->msg_type = GSM48_MT_MM_IMSI_DETACH_IND;
411
412         while(translist not empty)
413                 release trans
414                 todo: release trans must send a release to it's application entitity
415
416         if (att flag set) {
417                 gsm48_start_mm_timer(mm, 0x3220, GSM48_T3220_MS);
418
419                 new_mm_state(mm, GSM48_MM_ST_IMSI_DETACH_INIT, 0);
420
421                 /* classmark 1 */
422                 memcpy(classmark1, , sizeof(struct gsm48_classmark1));
423                 /* MI */
424                 switch(mi_type) {
425                 case GSM_MI_TYPE_TMSI:
426                         gsm48_generate_mid_from_tmsi(buf, tmsi);
427                         break;
428                 case GSM_MI_TYPE_IMSI:
429                         gsm48_generate_mid_from_imsi(buf, imsi);
430                         break;
431                 case GSM_MI_TYPE_IMEI:
432                 case GSM_MI_TYPE_IMEISV:
433                         gsm48_generate_mid_from_imsi(buf, imeisv);
434                         break;
435                 case GSM_MI_TYPE_NONE:
436                 default:
437                         buf[0] = GSM48_IE_MOBILE_ID;
438                         buf[1] = 1;
439                         buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
440                         break;
441                 }
442                 /* MI as LV */
443                 ie = msgb_put(msg, 1 + buf[1]);
444                 memcpy(ie, buf + 1, 1 + buf[1]);
445
446                 return gsm48_mm_sendmsg(ms, nmsg);
447         } else {
448 oops: this must be wrong                return gsm48_mm_return_idle(ms);
449         }
450                 
451 }
452
453 todo: timeout t3220
454
455 static int gsm48_mm_imsi_detach_no_rr(struct osmocom_ms *ms, void *arg)
456 {
457         request rr
458
459         new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_IMSI_D, 0);
460
461 }
462
463 /* cm reestablish request message from upper layer */
464 static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, void *arg)
465 {
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;
470         u_int8_t buf[11];
471         u_int8_t *ie;
472
473         msg->lchan = lchan;
474         gh->proto_discr = GSM48_PDISC_MM;
475         gh->msg_type = GSM48_MT_MM_CM_SERV_REQ;
476
477         /* type and key */
478         serv_req->cm_service_type =
479         serv_req->cypher_key_seq =
480         /* classmark 2 */
481         classmark2[0] = sizeof(struct gsm48_classmark2);
482         memcpy(classmark2+1, , sizeof(struct gsm48_classmark2));
483         /* MI */
484         switch(mi_type) {
485         case GSM_MI_TYPE_TMSI:
486                 gsm48_generate_mid_from_tmsi(buf, tmsi);
487                 break;
488         case GSM_MI_TYPE_IMSI:
489                 gsm48_generate_mid_from_imsi(buf, imsi);
490                 break;
491         case GSM_MI_TYPE_IMEI:
492         case GSM_MI_TYPE_IMEISV:
493                 gsm48_generate_mid_from_imsi(buf, imeisv);
494                 break;
495         case GSM_MI_TYPE_NONE:
496         default:
497                 buf[0] = GSM48_IE_MOBILE_ID;
498                 buf[1] = 1;
499                 buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
500                 break;
501         }
502         /* MI as LV */
503         ie = msgb_put(msg, 1 + buf[1]);
504         memcpy(ie, buf + 1, 1 + buf[1]);
505         /* prio is optional for eMLPP */
506
507         return gsm48_mm_sendmsg(ms, nmsg);
508 }
509
510 /* cm service abort message from upper layer */
511 static int gsm48_mm_tx_cm_service_abort(struct osmocom_ms *ms, void *arg)
512 {
513         struct msgb *msg = gsm48_mm_msgb_alloc();
514         struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
515
516         msg->lchan = lchan;
517         gh->proto_discr = GSM48_PDISC_MM;
518         gh->msg_type = GSM48_MT_MM_CM_SERV_ABORT;
519
520         return gsm48_mm_sendmsg(ms, nmsg);
521 }
522
523 /* cm reestablish request message from upper layer */
524 static int gsm48_mm_tx_cm_reest_req(struct osmocom_ms *ms, void *arg)
525 {
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));
530         u_int8_t buf[11];
531         u_int8_t *ie;
532
533         msg->lchan = lchan;
534         gh->proto_discr = GSM48_PDISC_MM;
535         gh->msg_type = GSM48_MT_MM_CM_REEST_REQ;
536
537         /* key */
538         *key_seq =
539         /* classmark2 */
540         classmark2[0] = sizeof(struct gsm48_classmark2);
541         memcpy(classmark2+1, , sizeof(struct gsm48_classmark2));
542         /* MI */
543         switch(mi_type) {
544         case GSM_MI_TYPE_TMSI:
545                 gsm48_generate_mid_from_tmsi(buf, tmsi);
546                 break;
547         case GSM_MI_TYPE_IMSI:
548                 gsm48_generate_mid_from_imsi(buf, imsi);
549                 break;
550         case GSM_MI_TYPE_IMEI:
551         case GSM_MI_TYPE_IMEISV:
552                 gsm48_generate_mid_from_imsi(buf, imeisv);
553                 break;
554         case GSM_MI_TYPE_NONE:
555         default:
556                 buf[0] = GSM48_IE_MOBILE_ID;
557                 buf[1] = 1;
558                 buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
559                 break;
560         }
561         /* MI as LV */
562         ie = msgb_put(msg, 1 + buf[1]);
563         memcpy(ie, buf + 1, 1 + buf[1]);
564         /* LAI */
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);
569                 /* LAI as TV */
570                 ie = msgb_put(msg, 1 + sizeof(struct gsm48_loc_area_id));
571                 memcpy(ie, buf, 1 + sizeof(struct gsm48_loc_area_id));
572         }
573
574         return gsm48_mm_sendmsg(ms, nmsg);
575 }
576
577 /* initiate a location update */
578 static int gsm48_mm_loc_update_no_rr(struct osmocom_ms *ms, void *arg)
579 {
580         struct gsm_rr est;
581
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);
587
588         memset(est, 0, sizeof(struct gsm_rr));
589 todo: set cause
590         gsm48_sendrr(sm, est, RR_EST_REQ);
591
592         new_mm_state(ms, GSM48_MM_ST_WAIT_RR_CONN_LUPD, 0);
593 }
594
595 /* initiate an IMSI detach */
596 static int gsm48_mm_imsi_detach(struct osmocom_ms *ms, void *arg)
597 {
598         todo
599 }
600
601 /* initiate an mm connection 4.5.1.1 */
602 static int gsm48_mm_init_mm_no_rr(struct osmocom_ms *ms, void *arg)
603 {
604         int emergency = 0, cause;
605         struct gsm_mm *mmmsg;
606         struct gsm_trans *trans = mmmsg->trans;
607         struct gsm_rr est;
608
609 todo
610
611         if (msg_type == MMCC_EST_REQ && mmmsg->emergency)
612                 emergency = 1;
613
614         if (!emergency && mm->mmustate != MMUSTATE_U1_UPDATED) {
615                 todo set cause
616                 reject:
617                 switch(msg_type) {
618                 case MMCC_EST_REQ:
619                         mmmsg->cause = cause;
620                         return mm_recvmsg(ms, trans, MMCC_REL_IND, mmmsg);
621                 case MMSS_EST_REQ:
622                         mmmsg->cause = cause;
623                         return mm_recvmsg(ms, trans, MMSS_REL_IND, mmmsg);
624                 case MMSMS_EST_REQ:
625                         mmmsg->cause = cause;
626                         return mm_recvmsg(ms, trans, MMSMS_REL_IND, mmmsg);
627                 default:
628                         return 0;
629                 }
630         }
631
632                 
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 */
639                 if (!emergency) {
640                         store mm connection request (status waiting)
641                         return trigger location update
642                 }
643                 break;
644         }
645         default:
646                 /* reject if not emergency */
647                 if (!emergency) {
648                         todo set cause
649                         goto reject;
650                 }
651                 break;
652         }
653
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)
657 todo: set cause
658         gsm48_sendrr(sm, est, RR_EST_REQ);
659         new_mm_state(ms, GSM48_MM_ST_WAIT_RR_CONN_MM_CON, 0);
660         return 0;
661 }
662
663
664 static int gsm48_mm_init_mm_first(struct osmocom_ms *ms, void *arg)
665 {
666         int emergency = 0, cause;
667         struct gsm_mm *mmmsg;
668         struct gsm_trans *trans = mmmsg->trans;
669         struct gsm_rr est;
670
671         send cm service request 
672
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);
676 }
677
678 static int gsm48_mm_init_mm_more(struct osmocom_ms *ms, void *arg)
679 {
680         int emergency = 0, cause;
681         struct gsm_mm *mmmsg;
682         struct gsm_trans *trans = mmmsg->trans;
683         struct gsm_rr est;
684
685         send cm service request 
686
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);
690 }
691
692 /* initiate an mm connection other cases */
693 static int gsm48_mm_init_mm_other(struct osmocom_ms *ms, void *arg)
694 {
695         int emergency = 0;
696         struct gsm_mm *mmmsg;
697         struct gsm_trans *trans = mmmsg->trans;
698
699         switch(msg_type) {
700         case MMCC_EST_REQ:
701                 mmmsg->cause = cause;
702                 return mm_recvmsg(ms, trans, MMCC_REL_IND, mmmsg);
703         case MMSS_EST_REQ:
704                 mmmsg->cause = cause;
705                 return mm_recvmsg(ms, trans, MMSS_REL_IND, mmmsg);
706         case MMSMS_EST_REQ:
707                 mmmsg->cause = cause;
708                 return mm_recvmsg(ms, trans, MMSMS_REL_IND, mmmsg);
709         default:
710                 return 0;
711         }
712 }
713
714 /* respond to paging */
715 static int gsm48_mm_paging(struct osmocom_ms *ms, void *arg)
716 {
717         todo
718 }
719
720 /* abort RR connection */
721 static int gsm48_mm_paging(struct osmocom_ms *ms, void *arg)
722 {
723         struct gsm_rr abort;
724
725         memset(abort, 0, sizeof(struct gsm_rr));
726         gsm48_sendrr(sm, abort, RR_ABORT_REQ);
727 }
728
729 /* abort RR connection */
730 static int gsm48_mm_classm_chg(struct osmocom_ms *ms, void *arg)
731 {
732         if (rr->state == in the dedicated without transitions)
733         gsm_rr_tx_cm_change(sm, abort, RR_ABORT_REQ);
734 }
735
736 /* state trasitions for mobile managemnt messages (upper layer / events) */
737 static struct eventstate {
738         u_int32_t       states;
739         u_int32_t       substates;
740         int             type;
741         int             (*rout) (struct gsm_trans *trans, void *arg);
742 } eventstatelist[] = {
743         /* 4.2.2.1 */
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},
763         /* 4.2.2.2 */
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},
776         /* 4.2.2.3 */
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},
783         /* 4.2.2.4 */
784         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_IMSI),
785          MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
786         /* 4.2.2.5 */
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},
803         /* 4.2.2.4 */
804         {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
805          MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
806         /* 4.5.1.1 */
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},
819         {ALL_STATES, 0,
820          MMCC_EST_REQ, gsm48_mm_init_mm_other},
821         {ALL_STATES, 0,
822          MMSS_EST_REQ, gsm48_mm_init_mm_other},
823         {ALL_STATES, 0,
824          MMSMS_EST_REQ, gsm48_mm_init_mm_other},
825         /* MS events */
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)
845
846         {SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
847          GSM48_MM_EVENT_, gsm48_mm_tx},
848
849         /* 4.4.4.8 */
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},
852
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},
869 };
870
871 #define EVENTSLLEN \
872         (sizeof(eventstatelist) / sizeof(struct eventstate))
873
874 /* MM event handler */
875 int mm_event(struct osmocom_ms *ms, int msg_type, struct gsm48_mmevent *mmevent)
876 {
877         struct gsm48_mmlayer *mm = &ms->mmlayer;
878         int msg_type = mmevent->msg_type;
879
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]);
884         DEBUGP(DMM, "\n");
885
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))
891                         break;
892         if (i == EVENTSLLEN) {
893                 DEBUGP(DMM, "Message unhandled at this state.\n");
894                 return 0;
895         }
896
897         rc = eventstatelist[i].rout(ms, msg_type, arg);
898
899         return rc;
900 }
901
902 /* decode network name */
903 static int decode_network_name(char *name, int name_len,
904         const u_int8_t *lv)
905 {
906         u_int8_t in_len = lv[0];
907         int length, padding;
908
909         name[0] = '\0';
910         if (in_len < 1)
911                 return -EINVAL;
912
913         /* must be CB encoded */
914         if ((lv[1] & 0x70) != 0x00)
915                 return -ENOTSUP;
916
917         padding = lv[1] & 0x03;
918         length = ((in_len - 1) * 8 - padding) / 7;
919         if (length <= 0)
920                 return 0;
921         if (length >= name_len)
922                 length = name_len - 1;
923         gsm_7bit_decode(name, lv + 2, length);
924         name[length] = '\0';
925
926         return length;
927 }
928
929 static char bcd2char(u_int8_t bcd)
930 {
931         if (bcd < 0xa)
932                 return '0' + bcd;
933         else
934                 return 'A' + (bcd - 0xa);
935 }
936
937 static int decode_lai(struct gsm48_loc_area_id *lai, u_int16_t *mcc, u_int16_t *mnc, u_int16_t *lac)
938 {
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);
946 }
947
948 /* mm info is received from lower layer */
949 static int gsm48_mm_rx_info(struct osmocom_ms *ms, struct msgb *msg)
950 {
951         struct gsm48_hdr *gh = msgb_l3(msg);
952         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
953         struct tlv_parsed tp;
954
955         tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, 0, 0);
956         /* long name */
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);
960         }
961         /* short name */
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);
965         }
966 }
967
968 /* location updating reject is received from lower layer */
969 static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg)
970 {
971         struct gsm48_hdr *gh = msgb_l3(msg);
972         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
973
974         if (payload_len < 1) {
975                 DEBUGP(DMM, "Short read of location updating reject message error.\n");
976                 return -EINVAL;
977         }
978
979         reject_cause = *gh->data;
980
981         if (llist_empty(ms->trans)) {
982                 DEBUGP(DMM, "Abort (cause #%d) while no MM connection is established.\n", reject_cause);
983                 return 0;
984         } else {
985                 DEBUGP(DMM, "Abort (cause #%d) while MM connection is established.\n", reject_cause);
986                 while(translist not empty)
987                         release trans
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
990         }
991
992         if (reject_cause == 6) { 
993                 new_sim_ustate(ms, GSM_MMUSTATE_U3_ROAMING_NA);
994 #ifdef TODO
995                 sim: delete tmsi
996                 sim: delete key seq number
997                 sim: apply update state
998 #endif
999         }
1000 }
1001
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)
1004 {
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;
1010
1011         if (payload_len < sizeof(struct gsm48_loc_area_id)) {a
1012                 short:
1013                 DEBUGP(DMM, "Short read of location updating accept message error.\n");
1014                 return -EINVAL;
1015         }
1016         tlv_parse(&tp, &rsl_att_tlvdef, gh->data, payload_len, GSM48_IE_LOC_AREA, 0);
1017         /* LAI */
1018         decode_lai(lai, &ms->current_mcc, &ms->current->mnc, &ms->current_lac);
1019         todo: store in sim
1020         remove from forbidden list
1021
1022         nnnew_mmu_state(ms, GSM_MMUSTATE_U1_UPDATED);
1023
1024         gsm48_stop_cc_timer(mm, 0x3210);
1025
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);
1028         /* MI */
1029         if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
1030                 mi = TLVP_VAL(&tp, GSM48_IE_FACILITY)-1;
1031                 if (mi[0] < 1)
1032                         goto short;
1033                 mi_type = mi[1] & GSM_MI_TYPE_MASK;
1034                 switch (mi_type) {
1035                 case GSM_MI_TYPE_TMSI:
1036                         if (gh->data + sizeof(struct gsm48_loc_area_id) < 6
1037                          || mi[0] < 5)
1038                                 goto short;
1039                         memcpy(&tmsi, mi+2, 4);
1040                         ms->tmsi = ntohl(tmsi);
1041                         ms->tmsi_valid = 1;
1042                         todo: store in sim
1043                         gsm48_mm_tx_tmsi_reall_cpl(ms);
1044                         break;
1045                 case GSM_MI_TYPE_IMSI:
1046                         ms->tmsi_valid = 0;
1047                         todo: remove tmsi from sim
1048                         gsm48_mm_tx_tmsi_reall_cpl(ms);
1049                         break;
1050                 default:
1051                         DEBUGP(DMM, "TMSI reallocation with unknown MI type %d.\n", mi_type);
1052                 }
1053         }
1054         /* follow on proceed */
1055         if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
1056                 DEBUGP(DMM, "follow-on proceed not supported.\n");
1057         }
1058
1059         gsm48_start_mm_timer(mm, 0x3240, GSM48_T3240_MS);
1060         new_mm_state(ms, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
1061
1062         return 0;
1063 }
1064
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)
1067 {
1068         struct gsm48_hdr *gh = msgb_l3(msg);
1069         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1070
1071         if (payload_len < 1) {
1072                 DEBUGP(DMM, "Short read of location update reject message error.\n");
1073                 return -EINVAL;
1074         }
1075         /* reject cause */
1076         reject_cause = *gh->data;
1077
1078         gsm48_stop_cc_timer(mm, 0x3210);
1079
1080         /* store until RR is released */
1081         mm->lupd_rej_cause = reject_cause;
1082
1083         gsm48_start_mm_timer(mm, 0x3240, GSM48_T3240_MS);
1084         new_mm_state(ms, GSM48_MM_ST_LOC_UPD_REJ, 0);
1085 }
1086
1087 /* abort is received from lower layer */
1088 static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg)
1089 {
1090         struct gsm48_hdr *gh = msgb_l3(msg);
1091         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1092
1093         if (payload_len < 1) {
1094                 DEBUGP(DMM, "Short read of abort message error.\n");
1095                 return -EINVAL;
1096         }
1097         /* reject cause */
1098         reject_cause = *gh->data;
1099 }
1100
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)
1103 {
1104         struct gsm48_hdr *gh = msgb_l3(msg);
1105         unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
1106
1107         if (payload_len < 1) {
1108                 DEBUGP(DMM, "Short read of cm service reject message error.\n");
1109                 return -EINVAL;
1110         }
1111         /* reject cause */
1112         reject_cause = *gh->data;
1113 }
1114
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)
1117 {
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
1121
1122         todo: an indication by the RR that the cyphering mode setting procedure is complete, shall be treated as cm_serv_ack!!
1123
1124         gsm48_stop_mm_timer(mm, 0x3230);
1125         new_mm_state(ms, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
1126 }
1127
1128 /* state trasitions for mobile managemnt messages (lower layer) */
1129 static struct mmdatastate {
1130         u_int32_t       states;
1131         int             type;
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},
1152         {ALL_STATES,
1153          GSM48_MT_MM_, gsm48_mm_rx_},
1154         {ALL_STATES,
1155          GSM48_MT_MM_, gsm48_mm_rx_},
1156         {ALL_STATES,
1157          GSM48_MT_MM_, gsm48_mm_rx_},
1158
1159         {SBIT(GSM_MSTATE_),
1160          GSM48_MT_MM_, gsm48_mm_rx_},
1161 };
1162
1163 #define DMMATASLLEN \
1164         (sizeof(mmdatastatelist) / sizeof(struct mmdatastate))
1165
1166 static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
1167 {
1168         struct gsm48_hdr *gh = msgb_l3(msg);
1169         int msg_type = gh->msg_type & 0xbf;
1170
1171         /* pull the MM header */
1172         msgb_pull(msg, sizeof(struct gsm48_mm_hdr));
1173
1174         /* forward message */
1175         switch (pdisc) {
1176         case GSM48_PDISC_MM:
1177                 break; /* follow the selection proceedure below */
1178
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;
1184
1185                 return gsm48_cc_upmsg(ms, msg);
1186
1187 #if 0
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;
1193
1194                 return gsm48_sms_upmsg(ms, msg);
1195 #endif
1196
1197         default:
1198                 DEBUGP(DRR, "Protocol type 0x%02x unsupported.\n", pdisc);
1199                 free_msgb(msg);
1200                 return;
1201         }
1202
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]);
1205
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))
1210                         break;
1211         if (i == MMDATASLLEN) {
1212                 DEBUGP(DMM, "Message unhandled at this state.\n");
1213                 free_msgb(msg);
1214                 return 0;
1215         }
1216
1217         rc = mmdatastatelist[i].rout(ms, msg);
1218
1219         free_msgb(msg);
1220
1221         return rc;
1222 }
1223
1224 /* timeout events of all timers */
1225 static void gsm48_mm_t3210(void *arg)
1226 {
1227         struct gsm48_mmlayer *mm = arg;
1228         mm_event(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3210);
1229 }
1230 static void gsm48_mm_t3211(void *arg)
1231 {
1232         struct gsm48_mmlayer *mm = arg;
1233         mm_event(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3211);
1234 }
1235 static void gsm48_mm_t3212(void *arg)
1236 {
1237         struct gsm48_mmlayer *mm = arg;
1238         mm_event(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3212);
1239 }
1240 static void gsm48_mm_t3213(void *arg)
1241 {
1242         struct gsm48_mmlayer *mm = arg;
1243         mm_event(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3213);
1244 }
1245
1246 /* RR is esablised during location update */
1247 static int gsm48_mm_est_loc_upd(struct osmocom_ms *ms, struct gsm_rr *est)
1248 {
1249         /* 4.4.4.1 */
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;
1254         u_int8_t buf[11];
1255         u_int8_t *ie;
1256
1257         gsm48_start_mm_timer(mm, 0x3210, GSM48_T3210_MS);
1258         new_mm_state(ms, GSM48_MM_ST_LOC_UPD_INIT, 0);
1259
1260         msg->lchan = lchan;
1261         gh->proto_discr = GSM48_PDISC_MM;
1262         gh->msg_type = GSM48_MT_MM_LOC_UPD_REQ;
1263
1264         /* type and key */
1265         loc_upd->type =
1266         loc_upd->key_seq =
1267         /* classmark 1 */
1268         memcpy(classmark1, , sizeof(struct gsm48_classmark1));
1269         /* LAI */
1270         gsm0408_generate_lai(loc_upd->lai,
1271                 country_code, network_code, location_area_code);
1272         /* MI */
1273         switch(mi_type) {
1274         case GSM_MI_TYPE_TMSI:
1275                 gsm48_generate_mid_from_tmsi(buf, tmsi);
1276                 break;
1277         case GSM_MI_TYPE_IMSI:
1278                 gsm48_generate_mid_from_imsi(buf, imsi);
1279                 break;
1280         case GSM_MI_TYPE_IMEI:
1281         case GSM_MI_TYPE_IMEISV:
1282                 gsm48_generate_mid_from_imsi(buf, imeisv);
1283                 break;
1284         case GSM_MI_TYPE_NONE:
1285         default:
1286                 buf[0] = GSM48_IE_MOBILE_ID;
1287                 buf[1] = 1;
1288                 buf[2] = 0xf0 | GSM_MI_TYPE_NONE;
1289                 break;
1290         }
1291         /* MI as LV */
1292         ie = msgb_put(msg, 1 + buf[1]);
1293         memcpy(ie, buf + 1, 1 + buf[1]);
1294
1295         return gsm48_mm_sendmsg(ms, nmsg);
1296 }
1297
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)
1300 {
1301         struct gsm48_mmlayer *mm = &ms->mmlayer;
1302         struct msgb *nmsg;
1303         struct gsm322_msg *ngm = msg->data;
1304         
1305         /* new status */
1306         switch (mm->lupd_rej_cause) {
1307         case 11:
1308         case 12:
1309         case 13:
1310                 attempt_counter = 0;
1311                 // fall through
1312         case 2:
1313         case 3:
1314         case 6:
1315                 new_sim_ustate(ms, GSM_MMUSTATE_U3_ROAMING_NA);
1316 #ifdef TODO
1317                 sim: delete tmsi
1318                 sim: delete key seq number
1319                 sim: apply update state
1320 #endif
1321         }
1322
1323         /* forbidden list */
1324         switch (mm->lupd_rej_cause) {
1325         case 2:
1326         case 3:
1327         case 6:
1328                 /* sim becomes invalid */
1329                 subscr->sim_valid = 0;
1330                 break;
1331         case 11:
1332                 add_forbidden_list(ms, FORBIDDEN_PLMN, lai);
1333                 break;
1334         case 12:
1335                 add_forbidden_list(ms, FORBIDDEN_LOC_AREA_RPOS, lai);
1336                 break;
1337         case 13:
1338                 add_forbidden_list(ms, FORBIDDEN_LOC_AREA_ROAM, lai);
1339                 break;
1340         default:
1341                 todo 4.4.4.9
1342         }
1343
1344         /* send event */
1345         nmsg = gsm322_msgb_alloc(GSM322_EVENT_LU_REJECT);
1346         if (!nmsg)
1347                 return -ENOMEM;
1348         ngm = (struct gsm322_msg *)nmsg->data;
1349         ngm->reject = mm->lupd_rej_cause;
1350         gsm322_sendmsg(ms, nmsg);
1351
1352         /* return to IDLE, case 13 is also handled there */
1353         return gsm48_mm_return_idle(ms);
1354 }
1355
1356 /* RR is released in other states */
1357 static int gsm48_mm_rel_other(struct osmocom_ms *ms, struct gsm_rr *rel)
1358 {
1359         /* send event */
1360 ** tothink: shall we do this here or at radio ressource
1361         nmsg = gsm322_msgb_alloc(GSM322_EVENT_RET_IDLE);
1362         if (!nmsg)
1363                 return -ENOMEM;
1364         gsm322_sendmsg(ms, nmsg);
1365
1366         return gsm48_mm_return_idle(ms);
1367 }
1368
1369 /* RR is esablised during mm connection */
1370 static int gsm48_mm_est_mm_con(struct osmocom_ms *ms, struct gsm_rr *est)
1371 {
1372         loop through all transactions. there must only be one in the "MMCONSTATE_CM_REQ", others are "MMCONSTATE_WAITING" or "MMCONSTATE_ACTIVE".
1373
1374         gsm48_start_mm_timer(mm, 0x3230, GSM48_T3220_MS);
1375         new_mm_state(ms, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
1376 }
1377
1378 /* state trasitions for radio ressource messages (lower layer) */
1379 static struct rrdatastate {
1380         u_int32_t       states;
1381         int             type;
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},
1388         {ALL_STATES,
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},
1392         {ALL_STATES,
1393          RR_DATA_IND, gsm48_mm_data_ind},
1394 };
1395
1396 #define RRDATASLLEN \
1397         (sizeof(rrdatastatelist) / sizeof(struct rrdatastate))
1398
1399 static int gsm48_rcv_rr(struct osmocom_ms *ms, struct gsm_rr *rrmsg)
1400 {
1401         struct gsm48_mmlayer *mm = &ms->mmlayer;
1402         int msg_type = rrmsg->msg_type;
1403
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]);
1406
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))
1411                         break;
1412         if (i == RRDATASLLEN) {
1413                 DEBUGP(DMM, "Message unhandled at this state.\n");
1414                 free_msgb(msg);
1415                 return 0;
1416         }
1417
1418         rc = rrdatastatelist[i].rout(ms, rrmsg);
1419         
1420         if (msg_type != RR_DATA_IND)
1421                 free_msgb(msg);
1422
1423         return rc;
1424 }
1425
1426 /* dequeue messages from RR */
1427 int gsm48_mm_queue(struct osmocom_ms *ms)
1428 {
1429         struct gsm48_mmlayer *mm = &ms->mmlayer;
1430         struct msgb *msg;
1431         int work = 0;
1432         
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 */
1437         }
1438         
1439         return work;
1440 }
1441
1442
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.