[mobile] Adding security warning, if default IMEI is not changed
[osmocom-bb.git] / src / host / layer23 / src / mobile / transaction.c
1 /* GSM 04.07 Transaction handling */
2
3 /* (C) 2009 by Harald Welte <laforge@gnumonks.org>
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 #include <stdint.h>
23
24 #include <osmocom/core/talloc.h>
25 #include <osmocom/core/timer.h>
26 #include <osmocom/core/msgb.h>
27
28 #include <osmocom/bb/common/osmocom_data.h>
29 #include <osmocom/bb/common/logging.h>
30 #include <osmocom/bb/mobile/mncc.h>
31 #include <osmocom/bb/mobile/transaction.h>
32
33 extern void *l23_ctx;
34
35 void _gsm48_cc_trans_free(struct gsm_trans *trans);
36
37 struct gsm_trans *trans_find_by_id(struct osmocom_ms *ms,
38                                    uint8_t proto, uint8_t trans_id)
39 {
40         struct gsm_trans *trans;
41
42         llist_for_each_entry(trans, &ms->trans_list, entry) {
43                 if (trans->protocol == proto &&
44                     trans->transaction_id == trans_id)
45                         return trans;
46         }
47         return NULL;
48 }
49
50 struct gsm_trans *trans_find_by_callref(struct osmocom_ms *ms,
51                                         uint32_t callref)
52 {
53         struct gsm_trans *trans;
54
55         llist_for_each_entry(trans, &ms->trans_list, entry) {
56                 if (trans->callref == callref)
57                         return trans;
58         }
59         return NULL;
60 }
61
62 struct gsm_trans *trans_alloc(struct osmocom_ms *ms,
63                               uint8_t protocol, uint8_t trans_id,
64                               uint32_t callref)
65 {
66         struct gsm_trans *trans;
67
68         trans = talloc_zero(l23_ctx, struct gsm_trans);
69         if (!trans)
70                 return NULL;
71
72         DEBUGP(DCC, "ms %s allocates transaction (proto %d trans_id %d "
73                 "callref %x mem %p)\n", ms->name, protocol, trans_id, callref,
74                 trans);
75
76         trans->ms = ms;
77
78         trans->protocol = protocol;
79         trans->transaction_id = trans_id;
80         trans->callref = callref;
81
82         llist_add_tail(&trans->entry, &ms->trans_list);
83
84         return trans;
85 }
86
87 void trans_free(struct gsm_trans *trans)
88 {
89         switch (trans->protocol) {
90         case GSM48_PDISC_CC:
91                 _gsm48_cc_trans_free(trans);
92                 break;
93 #if 0
94         case GSM48_PDISC_SS:
95                 _gsm411_ss_trans_free(trans);
96                 break;
97         case GSM48_PDISC_SMS:
98                 _gsm411_sms_trans_free(trans);
99                 break;
100 #endif
101         }
102
103         DEBUGP(DCC, "ms %s frees transaction (mem %p)\n", trans->ms->name,
104                 trans);
105
106         llist_del(&trans->entry);
107
108         talloc_free(trans);
109 }
110
111 /* allocate an unused transaction ID 
112  * in the given protocol using the ti_flag specified */
113 int trans_assign_trans_id(struct osmocom_ms *ms,
114                           uint8_t protocol, uint8_t ti_flag)
115 {
116         struct gsm_trans *trans;
117         unsigned int used_tid_bitmask = 0;
118         int i, j, h;
119
120         if (ti_flag)
121                 ti_flag = 0x8;
122
123         /* generate bitmask of already-used TIDs for this (proto) */
124         llist_for_each_entry(trans, &ms->trans_list, entry) {
125                 if (trans->protocol != protocol ||
126                     trans->transaction_id == 0xff)
127                         continue;
128                 used_tid_bitmask |= (1 << trans->transaction_id);
129         }
130
131         /* find a new one, trying to go in a 'circular' pattern */
132         for (h = 6; h > 0; h--)
133                 if (used_tid_bitmask & (1 << (h | ti_flag)))
134                         break;
135         for (i = 0; i < 7; i++) {
136                 j = ((h + i) % 7) | ti_flag;
137                 if ((used_tid_bitmask & (1 << j)) == 0)
138                         return j;
139         }
140
141         return -1;
142 }
143