From c072ad6e299a5930937d336bb13c407c02aefd7b Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 23 Jul 2009 21:25:08 +0200 Subject: [PATCH 1/3] add missing files to git --- openbsc/include/openbsc/transaction.h | 16 +++ openbsc/src/transaction.c | 134 ++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 openbsc/include/openbsc/transaction.h create mode 100644 openbsc/src/transaction.c diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h new file mode 100644 index 000000000..8f3e7de81 --- /dev/null +++ b/openbsc/include/openbsc/transaction.h @@ -0,0 +1,16 @@ +#ifndef _TRANSACT_H +#define _TRANSACT_H + +#include +#include + +struct gsm_trans *trans_find_by_id(struct gsm_lchan *lchan, u_int8_t trans_id); +struct gsm_trans *trans_find_by_callref(struct gsm_network *net, + u_int32_t callref); + +struct gsm_trans *trans_alloc(struct gsm_subscriber *subscr, + u_int8_t protocol, u_int8_t trans_id, + u_int32_t callref); +void trans_free(struct gsm_trans *trans); + +#endif diff --git a/openbsc/src/transaction.c b/openbsc/src/transaction.c new file mode 100644 index 000000000..e917cdd11 --- /dev/null +++ b/openbsc/src/transaction.c @@ -0,0 +1,134 @@ +/* GSM 04.07 Transaction handling */ + +/* (C) 2009 by Harald Welte + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void *tall_trans_ctx; + +struct gsm_trans *trans_find_by_id(struct gsm_lchan *lchan, u_int8_t trans_id) +{ + struct gsm_trans *trans; + struct gsm_network *net = lchan->ts->trx->bts->network; + + llist_for_each_entry(trans, &net->trans_list, entry) { + if (trans->lchan == lchan && trans->transaction_id == trans_id) + return trans; + } + return NULL; +} + +struct gsm_trans *trans_find_by_callref(struct gsm_network *net, + u_int32_t callref) +{ + struct gsm_trans *trans; + + llist_for_each_entry(trans, &net->trans_list, entry) { + if (trans->callref == callref) + return trans; + } + return NULL; +} + +struct gsm_trans *trans_alloc(struct gsm_subscriber *subscr, + u_int8_t protocol, u_int8_t trans_id, + u_int32_t callref) +{ + struct gsm_trans *trans; + + DEBUGP(DCC, "subscr=%p, subscr->net=%p\n", subscr, subscr->net); + + trans = talloc_zero(tall_trans_ctx, struct gsm_trans); + if (!trans) + return NULL; + + trans->subscr = subscr; + subscr_get(trans->subscr); + + trans->protocol = protocol; + trans->transaction_id = trans_id; + trans->callref = callref; + + llist_add_tail(&trans->entry, &subscr->net->trans_list); + + return trans; +} + +void trans_free(struct gsm_trans *trans) +{ + struct gsm_bts *bts; + + switch (trans->protocol) { + case GSM48_PDISC_CC: + _gsm48_cc_trans_free(trans); + break; + } + + if (trans->lchan) + put_lchan(trans->lchan); + + if (!trans->lchan && trans->subscr && trans->subscr->net) { + /* Stop paging on all bts' */ + bts = NULL; + do { + bts = gsm_bts_by_lac(trans->subscr->net, + trans->subscr->lac, bts); + if (!bts) + break; + /* Stop paging */ + paging_request_stop(bts, trans->subscr, NULL); + } while (1); + } + + if (trans->subscr) + subscr_put(trans->subscr); + + llist_del(&trans->entry); + + talloc_free(trans); +} + +#if 0 +int trans_assign_trans_id(struct gsm_subscriber *subscr, + u_int8_t protocol, u_int8_t ti_flag) +{ + struct gsm_network *net = subscr->net; + struct gsm_trans *trans; + unsigned int used_tid_bitmask = 0; + + /* generate bitmask of already-used TIDs for this (subscr,proto) */ + llist_for_each_entry(trans, &net->trans_list, entry) { + if (trans->subscr != subscr || + trans->protocol != protocol || + trans->transaction_id == 0xff) + continue; + used_tid_bitmask |= (1 << trans->transaction_id); + } + +} +#endif From b49248bf48b0856e3b156810681ea3fca44c728a Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 23 Jul 2009 21:36:44 +0200 Subject: [PATCH 2/3] move allocating new transaction_ids to transaction.c --- openbsc/include/openbsc/transaction.h | 2 ++ openbsc/src/gsm_04_08.c | 21 ++++----------------- openbsc/src/transaction.c | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h index 8f3e7de81..1450dbca5 100644 --- a/openbsc/include/openbsc/transaction.h +++ b/openbsc/include/openbsc/transaction.h @@ -13,4 +13,6 @@ struct gsm_trans *trans_alloc(struct gsm_subscriber *subscr, u_int32_t callref); void trans_free(struct gsm_trans *trans); +int trans_assign_trans_id(struct gsm_subscriber *subscr, + u_int8_t protocol, u_int8_t ti_flag); #endif diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 28d573a1d..642d0599b 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -2257,9 +2257,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh; struct gsm_mncc *setup = arg; - struct gsm_trans *transt; - u_int16_t trans_id_mask = 0; - int rc, i; + int rc, trans_id; gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); @@ -2277,14 +2275,8 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) } /* Get free transaction_id */ - llist_for_each_entry(transt, &trans->subscr->net->trans_list, entry) { - /* Transaction of our lchan? */ - if (transt->lchan == trans->lchan && - transt->transaction_id != 0xff) - trans_id_mask |= (1 << transt->transaction_id); - } - /* Assign free transaction ID */ - if ((trans_id_mask & 0x007f) == 0x7f) { + trans_id = trans_assign_trans_id(trans->subscr, GSM48_PDISC_CC, 0); + if (trans_id < 0) { /* no free transaction ID */ rc = mncc_release_ind(trans->subscr->net, trans, trans->callref, GSM48_CAUSE_LOC_PRN_S_LU, @@ -2293,12 +2285,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) trans_free(trans); return rc; } - for (i = 0; i < 7; i++) { - if ((trans_id_mask & (1 << i)) == 0) { - trans->transaction_id = i; /* flag = 0 */ - break; - } - } + trans->transaction_id = trans_id; gh->msg_type = GSM48_MT_CC_SETUP; diff --git a/openbsc/src/transaction.c b/openbsc/src/transaction.c index e917cdd11..f4cef28d2 100644 --- a/openbsc/src/transaction.c +++ b/openbsc/src/transaction.c @@ -113,13 +113,18 @@ void trans_free(struct gsm_trans *trans) talloc_free(trans); } -#if 0 +/* allocate an unused transaction ID for the given subscriber + * in the given protocol using the ti_flag specified */ int trans_assign_trans_id(struct gsm_subscriber *subscr, u_int8_t protocol, u_int8_t ti_flag) { struct gsm_network *net = subscr->net; struct gsm_trans *trans; unsigned int used_tid_bitmask = 0; + int i; + + if (ti_flag) + ti_flag = 0x8; /* generate bitmask of already-used TIDs for this (subscr,proto) */ llist_for_each_entry(trans, &net->trans_list, entry) { @@ -130,5 +135,10 @@ int trans_assign_trans_id(struct gsm_subscriber *subscr, used_tid_bitmask |= (1 << trans->transaction_id); } + for (i = 0; i <= 7; i++) { + if ((used_tid_bitmask & (1 << (i | ti_flag))) == 0) + return i | ti_flag; + } + + return -1; } -#endif From 7bfc26749662e3a3227037cce4a24748343b50be Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 Jul 2009 00:41:45 +0200 Subject: [PATCH 3/3] move allocation of talloc contexts into link-time constructor This is much more optimal than checking if the context exists every time we allocate the respective object. --- openbsc/src/abis_nm.c | 11 +++++++---- openbsc/src/e1_input.c | 10 ++++++---- openbsc/src/gsm_04_08.c | 5 ++--- openbsc/src/gsm_04_11.c | 14 ++++++-------- openbsc/src/gsm_subscriber.c | 16 ++++++++-------- openbsc/src/mncc.c | 11 +++++------ openbsc/src/msgb.c | 8 +++++--- openbsc/src/paging.c | 8 +++++--- openbsc/src/signal.c | 8 +++++--- openbsc/src/subchan_demux.c | 9 ++++++--- openbsc/src/trau_mux.c | 17 +++++++++-------- 11 files changed, 64 insertions(+), 53 deletions(-) diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c index 2b5647962..dec4b2957 100644 --- a/openbsc/src/abis_nm.c +++ b/openbsc/src/abis_nm.c @@ -2056,10 +2056,6 @@ static int bs11_read_swl_file(struct abis_nm_bs11_sw *bs11_sw) FILE *swl; int rc = 0; - if (!tall_fle_ctx) - tall_fle_ctx = talloc_named_const(tall_bsc_ctx, 1, - "bs11_file_list_entry"); - swl = fopen(bs11_sw->swl_fname, "r"); if (!swl) return -ENODEV; @@ -2373,3 +2369,10 @@ int abis_nm_ipaccess_restart(struct gsm_bts *bts) { return __simple_cmd(bts, NM_MT_IPACC_RESTART); } + + +static __attribute__((constructor)) void on_dso_load_abis_nm(void) +{ + tall_fle_ctx = talloc_named_const(tall_bsc_ctx, 1, + "bs11_file_list_entry"); +} diff --git a/openbsc/src/e1_input.c b/openbsc/src/e1_input.c index 2d0c1340f..7531755c2 100644 --- a/openbsc/src/e1_input.c +++ b/openbsc/src/e1_input.c @@ -370,10 +370,6 @@ e1inp_sign_link_create(struct e1inp_ts *ts, enum e1inp_sign_type type, if (ts->type != E1INP_TS_TYPE_SIGN) return NULL; - if (!tall_sigl_ctx) - tall_sigl_ctx = talloc_named_const(tall_bsc_ctx, 1, - "e1inp_sign_link"); - link = talloc_zero(tall_sigl_ctx, struct e1inp_sign_link); if (!link) return NULL; @@ -505,3 +501,9 @@ int e1inp_line_register(struct e1inp_line *line) return 0; } + +static __attribute__((constructor)) void on_dso_load_e1_inp(void) +{ + tall_sigl_ctx = talloc_named_const(tall_bsc_ctx, 1, + "e1inp_sign_link"); +} diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 642d0599b..a9f2ebd8e 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -350,9 +350,6 @@ static void allocate_loc_updating_req(struct gsm_lchan *lchan) use_lchan(lchan); release_loc_updating_req(lchan); - if (!tall_locop_ctx) - tall_locop_ctx = talloc_named_const(tall_bsc_ctx, 1, - "loc_updating_oper"); lchan->loc_operation = talloc_zero(tall_locop_ctx, struct gsm_loc_updating_operation); } @@ -408,6 +405,8 @@ static int gsm0408_handle_lchan_signal(unsigned int subsys, unsigned int signal, */ static __attribute__((constructor)) void on_dso_load_0408(void) { + tall_locop_ctx = talloc_named_const(tall_bsc_ctx, 1, + "loc_updating_oper"); register_signal_handler(SS_LCHAN, gsm0408_handle_lchan_signal, NULL); } diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c index 8db402b33..9218783ff 100644 --- a/openbsc/src/gsm_04_11.c +++ b/openbsc/src/gsm_04_11.c @@ -162,19 +162,11 @@ static int gsm340_rx_tpdu(struct msgb *msg) u_int8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */ int rc = 0; - if (!tall_sms_ctx) - tall_sms_ctx = talloc_named_const(tall_bsc_ctx, 1, - "sms_submit"); - sms = talloc(tall_sms_ctx, struct sms_submit); if (!sms) return -ENOMEM; memset(sms, 0, sizeof(*sms)); - if (!tall_gsms_ctx) - tall_gsms_ctx = talloc_named_const(tall_bsc_ctx, 1, - "sms"); - gsms = talloc(tall_gsms_ctx, struct gsm_sms); if (!gsms) { talloc_free(sms); @@ -513,3 +505,9 @@ int gsm0411_send_sms(struct gsm_lchan *lchan, struct sms_deliver *sms) return gsm0411_sendmsg(msg); } + +static __attribute__((constructor)) void on_dso_load_sms(void) +{ + tall_sms_ctx = talloc_named_const(tall_bsc_ctx, 1, "sms_submit"); + tall_gsms_ctx = talloc_named_const(tall_bsc_ctx, 1, "sms"); +} diff --git a/openbsc/src/gsm_subscriber.c b/openbsc/src/gsm_subscriber.c index e89290623..748015693 100644 --- a/openbsc/src/gsm_subscriber.c +++ b/openbsc/src/gsm_subscriber.c @@ -103,10 +103,6 @@ struct gsm_subscriber *subscr_alloc(void) { struct gsm_subscriber *s; - if (!tall_subscr_ctx) - tall_subscr_ctx = talloc_named_const(tall_bsc_ctx, 1, - "subscriber"); - s = talloc(tall_subscr_ctx, struct gsm_subscriber); if (!s) return NULL; @@ -213,10 +209,6 @@ void subscr_get_channel(struct gsm_subscriber *subscr, { struct subscr_request *request; - if (!tall_sub_req_ctx) - tall_sub_req_ctx = talloc_named_const(tall_bsc_ctx, 1, - "subscr_request"); - request = talloc(tall_sub_req_ctx, struct subscr_request); if (!request) { if (cbfn) @@ -273,3 +265,11 @@ void subscr_put_channel(struct gsm_lchan *lchan) subscr_send_paging_request(lchan->subscr); } + +static __attribute__((constructor)) void on_dso_load_subscr(void) +{ + tall_subscr_ctx = talloc_named_const(tall_bsc_ctx, 1, "subscriber"); + + tall_sub_req_ctx = talloc_named_const(tall_bsc_ctx, 1, + "subscr_request"); +} diff --git a/openbsc/src/mncc.c b/openbsc/src/mncc.c index b2dab078e..8cd62f6ce 100644 --- a/openbsc/src/mncc.c +++ b/openbsc/src/mncc.c @@ -140,9 +140,6 @@ static int mncc_setup_ind(struct gsm_call *call, int msg_type, if (call->remote_ref) return 0; - if (!tall_call_ctx) - tall_call_ctx = talloc_named_const(tall_bsc_ctx, 1, - "gsm_call"); /* create remote call */ if (!(remote = talloc(tall_call_ctx, struct gsm_call))) { memset(&mncc, 0, sizeof(struct gsm_mncc)); @@ -306,9 +303,6 @@ int mncc_recv(struct gsm_network *net, int msg_type, void *arg) if (!call) { if (msg_type != MNCC_SETUP_IND) return 0; /* drop */ - if (!tall_call_ctx) - tall_call_ctx = talloc_named_const(tall_bsc_ctx, 1, - "gsm_call"); /* create call */ if (!(call = talloc_zero(tall_call_ctx, struct gsm_call))) { struct gsm_mncc rel; @@ -395,3 +389,8 @@ int mncc_recv(struct gsm_network *net, int msg_type, void *arg) return rc; } + +static __attribute__((constructor)) void on_dso_load_trau_mncc(void) +{ + tall_call_ctx = talloc_named_const(tall_bsc_ctx, 1, "gsm_call"); +} diff --git a/openbsc/src/msgb.c b/openbsc/src/msgb.c index ae1334614..52edf2dcd 100644 --- a/openbsc/src/msgb.c +++ b/openbsc/src/msgb.c @@ -33,9 +33,6 @@ struct msgb *msgb_alloc(u_int16_t size, const char *name) { struct msgb *msg; - if (!tall_msgb_ctx) - tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 1, "msgb"); - msg = _talloc_zero(tall_msgb_ctx, sizeof(*msg) + size, name); if (!msg) @@ -76,3 +73,8 @@ struct msgb *msgb_dequeue(struct llist_head *queue) return llist_entry(lh, struct msgb, list); } + +static __attribute__((constructor)) void on_dso_load_trau_msgb(void) +{ + tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 1, "msgb"); +} diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index 0703e932f..b63a717b0 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -219,9 +219,6 @@ static void _paging_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, struct gsm_bts_paging_state *bts_entry = &bts->paging; struct gsm_paging_request *req; - if (!tall_paging_ctx) - tall_paging_ctx = talloc_named_const(NULL, 1, "paging_request"); - if (paging_pending_request(bts_entry, subscr)) { DEBUGP(DPAG, "Paging request already pending\n"); return; @@ -310,3 +307,8 @@ void paging_update_buffer_space(struct gsm_bts *bts, u_int16_t free_slots) { bts->paging.available_slots = free_slots; } + +static __attribute__((constructor)) void on_dso_load_paging(void) +{ + tall_paging_ctx = talloc_named_const(NULL, 1, "paging_request"); +} diff --git a/openbsc/src/signal.c b/openbsc/src/signal.c index 41352fb1a..bf5671ee1 100644 --- a/openbsc/src/signal.c +++ b/openbsc/src/signal.c @@ -39,9 +39,6 @@ int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data) { struct signal_handler *sig_data; - if (!tall_sigh_ctx) - tall_sigh_ctx = talloc_named_const(NULL, 1, "signal_handler"); - sig_data = talloc(tall_sigh_ctx, struct signal_handler); if (!sig_data) return -ENOMEM; @@ -84,3 +81,8 @@ void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data (*handler->cbfn)(subsys, signal, handler->data, signal_data); } } + +static __attribute__((constructor)) void on_dso_load_signal(void) +{ + tall_sigh_ctx = talloc_named_const(NULL, 1, "signal_handler"); +} diff --git a/openbsc/src/subchan_demux.c b/openbsc/src/subchan_demux.c index ccd4fadc6..368b9853c 100644 --- a/openbsc/src/subchan_demux.c +++ b/openbsc/src/subchan_demux.c @@ -312,9 +312,6 @@ int subchan_mux_init(struct subch_mux *mx) { int i; - if (!tall_tqe_ctx) - tall_tqe_ctx = talloc_named_const(tall_bsc_ctx, 1, - "subch_txq_entry"); memset(mx, 0, sizeof(*mx)); for (i = 0; i < NR_SUBCH; i++) { struct mux_subch *sch = &mx->subch[i]; @@ -323,3 +320,9 @@ int subchan_mux_init(struct subch_mux *mx) return 0; } + +static __attribute__((constructor)) void on_dso_load_ss_demux(void) +{ + tall_tqe_ctx = talloc_named_const(tall_bsc_ctx, 1, + "subch_txq_entry"); +} diff --git a/openbsc/src/trau_mux.c b/openbsc/src/trau_mux.c index 04febbd63..9ff7001d3 100644 --- a/openbsc/src/trau_mux.c +++ b/openbsc/src/trau_mux.c @@ -55,10 +55,6 @@ int trau_mux_map(const struct gsm_e1_subslot *src, { struct map_entry *me; - if (!tall_map_ctx) - tall_map_ctx = talloc_named_const(tall_bsc_ctx, 1, - "trau_map_entry"); - me = talloc(tall_map_ctx, struct map_entry); if (!me) return -ENOMEM; @@ -201,10 +197,6 @@ int trau_recv_lchan(struct gsm_lchan *lchan, u_int32_t callref) struct gsm_e1_subslot *src_ss; struct upqueue_entry *ue; - if (!tall_upq_ctx) - tall_upq_ctx = talloc_named_const(tall_bsc_ctx, 1, - "trau_upq_entry"); - ue = talloc(tall_upq_ctx, struct upqueue_entry); if (!ue) return -ENOMEM; @@ -243,3 +235,12 @@ int trau_send_lchan(struct gsm_lchan *lchan, struct decoded_trau_frame *tf) return subchan_mux_enqueue(mx, dst_e1_ss->e1_ts_ss, trau_bits_out, TRAU_FRAME_BITS); } + +static __attribute__((constructor)) void on_dso_load_trau_mux(void) +{ + tall_map_ctx = talloc_named_const(tall_bsc_ctx, 1, + "trau_map_entry"); + + tall_upq_ctx = talloc_named_const(tall_bsc_ctx, 1, + "trau_upq_entry"); +}