1 /* GSM 04.07 Transaction handling */
3 /* (C) 2009 by Harald Welte <laforge@gnumonks.org>
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.
24 #include <osmocom/core/talloc.h>
25 #include <osmocom/core/timer.h>
26 #include <osmocom/core/msgb.h>
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>
35 void _gsm48_cc_trans_free(struct gsm_trans *trans);
37 struct gsm_trans *trans_find_by_id(struct osmocom_ms *ms,
38 uint8_t proto, uint8_t trans_id)
40 struct gsm_trans *trans;
42 llist_for_each_entry(trans, &ms->trans_list, entry) {
43 if (trans->protocol == proto &&
44 trans->transaction_id == trans_id)
50 struct gsm_trans *trans_find_by_callref(struct osmocom_ms *ms,
53 struct gsm_trans *trans;
55 llist_for_each_entry(trans, &ms->trans_list, entry) {
56 if (trans->callref == callref)
62 struct gsm_trans *trans_alloc(struct osmocom_ms *ms,
63 uint8_t protocol, uint8_t trans_id,
66 struct gsm_trans *trans;
68 trans = talloc_zero(l23_ctx, struct gsm_trans);
72 DEBUGP(DCC, "ms %s allocates transaction (proto %d trans_id %d "
73 "callref %x mem %p)\n", ms->name, protocol, trans_id, callref,
78 trans->protocol = protocol;
79 trans->transaction_id = trans_id;
80 trans->callref = callref;
82 llist_add_tail(&trans->entry, &ms->trans_list);
87 void trans_free(struct gsm_trans *trans)
89 switch (trans->protocol) {
91 _gsm48_cc_trans_free(trans);
95 _gsm411_ss_trans_free(trans);
98 _gsm411_sms_trans_free(trans);
103 DEBUGP(DCC, "ms %s frees transaction (mem %p)\n", trans->ms->name,
106 llist_del(&trans->entry);
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)
116 struct gsm_trans *trans;
117 unsigned int used_tid_bitmask = 0;
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)
128 used_tid_bitmask |= (1 << trans->transaction_id);
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)))
135 for (i = 0; i < 7; i++) {
136 j = ((h + i) % 7) | ti_flag;
137 if ((used_tid_bitmask & (1 << j)) == 0)