From 03582a8bdcceccaa5c9f4218419f2a2462431837 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 16 Jul 2009 15:24:27 +0200 Subject: bsc_hack.c: Make adding of (nano)BTS to the network dynamic Fix the FIXME and replace the hardcoded site_id's of the nanoBTS with a command line option. You can use -i DEVICE_X for every BTS you want to handle. --- openbsc/src/bsc_hack.c | 53 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c index 688ee9fbc..58c209f07 100644 --- a/openbsc/src/bsc_hack.c +++ b/openbsc/src/bsc_hack.c @@ -63,6 +63,15 @@ static enum gsm_bts_type BTS_TYPE = GSM_BTS_TYPE_BS11; static enum gsm_band BAND = GSM_BAND_900; static const char *database_name = "hlr.sqlite3"; +struct nano_bts_id { + struct llist_head entry; + int site_id; + int bts_id; +}; + +static LLIST_HEAD(nanobts_ids); + + /* The following definitions are for OM and NM packets that we cannot yet * generate by code but we just pass on */ @@ -963,8 +972,6 @@ static int bootstrap_bts(struct gsm_bts *bts) static int bootstrap_network(void) { - struct gsm_bts *bts; - switch(BTS_TYPE) { case GSM_BTS_TYPE_NANOBTS_1800: if (ARFCN < 512 || ARFCN > 885) { @@ -993,9 +1000,6 @@ static int bootstrap_network(void) gsmnet->name_long = "OpenBSC"; gsmnet->name_short = "OpenBSC"; - bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC); - bootstrap_bts(bts); - if (db_init(database_name)) { printf("DB: Failed to init database. Please check the option settings.\n"); return -1; @@ -1014,17 +1018,27 @@ static int bootstrap_network(void) /* E1 mISDN input setup */ if (BTS_TYPE == GSM_BTS_TYPE_BS11) { + struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC); + bootstrap_bts(bts); + gsmnet->num_bts = 1; return e1_config(bts, cardnr, release_l2); } else { - /* FIXME: do this dynamic */ - bts->ip_access.site_id = 1801; - bts->ip_access.bts_id = 0; + struct nano_bts_id *bts_id; + struct gsm_bts *bts; + + if (llist_empty(&nanobts_ids)) { + fprintf(stderr, "You need to specify -i DEVICE_1 -i DEVICE_2 for nanoBTS.\n"); + return -EINVAL; + } + + llist_for_each_entry(bts_id, &nanobts_ids, entry) { + bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC); + bootstrap_bts(bts); + bts->ip_access.site_id = bts_id->site_id; + bts->ip_access.bts_id = 0; + } - bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC); - bootstrap_bts(bts); - bts->ip_access.site_id = 1800; - bts->ip_access.bts_id = 0; return ipaccess_setup(gsmnet); } } @@ -1061,6 +1075,7 @@ static void print_help() printf(" -r --reject-cause number The reject cause for LOCATION UPDATING REJECT.\n"); printf(" -p --pcap file The filename of the pcap file\n"); printf(" -t --bts-type type The BTS type (bs11, nanobts900, nanobts1800)\n"); + printf(" -i --bts-id=NUMBER The known nanoBTS device numbers. Can be specified multiple times.\n"); printf(" -C --cardnr number For bs11 select E1 card number other than 0\n"); printf(" -R --release-l2 Releases mISDN layer 2 after exit, to unload driver.\n"); printf(" -h --help this text\n"); @@ -1087,10 +1102,11 @@ static void handle_options(int argc, char** argv) {"release-l2", 0, 0, 'R'}, {"timestamp", 0, 0, 'T'}, {"band", 0, 0, 'b'}, + {"bts-id", 1, 0, 'i'}, {0, 0, 0, 0} }; - c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:", + c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:", long_options, &option_index); if (c == -1) break; @@ -1145,6 +1161,17 @@ static void handle_options(int argc, char** argv) case 'b': BAND = gsm_band_parse(atoi(optarg)); break; + case 'i': { + struct nano_bts_id *bts_id = talloc_zero(tall_bsc_ctx, struct nano_bts_id); + if (!bts_id) { + fprintf(stderr, "Failed to allocate bts id\n"); + exit(-1); + } + + bts_id->site_id = atoi(optarg); + llist_add(&bts_id->entry, &nanobts_ids); + break; + } default: /* ignore */ break; -- cgit v1.2.3 From 565547171caa01703580f6c7b93214f329b97017 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 18 Jul 2009 16:18:11 +0200 Subject: some more comments for BS11 attributes --- openbsc/src/bsc_hack.c | 71 +++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c index 58c209f07..c100ee4ba 100644 --- a/openbsc/src/bsc_hack.c +++ b/openbsc/src/bsc_hack.c @@ -228,26 +228,27 @@ SET ATTRIBUTES unsigned char msg_3[] = { NM_MT_BS11_SET_ATTR, NM_OC_BS11_HANDOVER, 0x00, 0xFF, 0xFF, - 0xD0, 0x00, - 0x64, 0x00, - 0x67, 0x00, - 0x68, 0x00, - 0x6A, 0x00, - 0x6C, 0x00, - 0x6D, 0x00, - 0x6F, 0x08, - 0x70, 0x08, 0x01, + 0xD0, 0x00, /* enableDelayPowerBudgetHO */ + 0x64, 0x00, /* enableDistanceHO */ + 0x67, 0x00, /* enableInternalInterCellHandover */ + 0x68, 0x00, /* enableInternalInterCellHandover */ + 0x6A, 0x00, /* enablePowerBudgetHO */ + 0x6C, 0x00, /* enableRXLEVHO */ + 0x6D, 0x00, /* enableRXQUALHO */ + 0x6F, 0x08, /* hoAveragingDistance */ + 0x70, 0x08, 0x01, /* hoAveragingLev */ 0x71, 0x10, 0x10, 0x10, - 0x72, 0x08, 0x02, - 0x73, 0x0A, - 0x74, 0x05, - 0x75, 0x06, - 0x76, 0x06, - 0x78, 0x14, - 0x79, 0x14, - 0x7A, 0x14, - 0x7D, 0x06, - 0x92, 0x03, 0x20, 0x01, 0x00, + 0x72, 0x08, 0x02, /* hoAveragingQual */ + 0x73, 0x0A, /* hoLowerThresholdLevDL */ + 0x74, 0x05, /* hoLowerThresholdLevUL */ + 0x75, 0x06, /* hoLowerThresholdQualDL */ + 0x76, 0x06, /* hoLowerThresholdQualUL */ + 0x78, 0x14, /* hoThresholdLevDLintra */ + 0x79, 0x14, /* hoThresholdLevULintra */ + 0x7A, 0x14, /* hoThresholdMsRangeMax */ + 0x7D, 0x06, /* nCell */ + NM_ATT_BS11_TIMER_HO_REQUEST, 0x03, + 0x20, 0x01, 0x00, 0x45, 0x01, 0x00, 0x48, 0x01, 0x00, 0x5A, 0x01, 0x00, @@ -300,22 +301,22 @@ unsigned char msg_4[] = NM_MT_BS11_SET_ATTR, NM_OC_BS11_PWR_CTRL, 0x00, 0xFF, 0xFF, NM_ATT_BS11_ENA_MS_PWR_CTRL, 0x00, NM_ATT_BS11_ENA_PWR_CTRL_RLFW, 0x00, - 0x7E, 0x04, 0x01, - 0x7F, 0x04, 0x02, - 0x80, 0x0F, - 0x81, 0x0A, - 0x82, 0x05, - 0x83, 0x05, - 0x84, 0x0C, - 0x85, 0x14, - 0x86, 0x0F, - 0x87, 0x04, - 0x88, 0x04, - 0x89, 0x02, - 0x8A, 0x02, - 0x8B, 0x02, - 0x8C, 0x01, - 0x8D, 0x40, + 0x7E, 0x04, 0x01, /* pcAveragingLev */ + 0x7F, 0x04, 0x02, /* pcAveragingQual */ + 0x80, 0x0F, /* pcLowerThresholdLevDL */ + 0x81, 0x0A, /* pcLowerThresholdLevUL */ + 0x82, 0x05, /* pcLowerThresholdQualDL */ + 0x83, 0x05, /* pcLowerThresholdQualUL */ + 0x84, 0x0C, /* pcRLFThreshold */ + 0x85, 0x14, /* pcUpperThresholdLevDL */ + 0x86, 0x0F, /* pcUpperThresholdLevUL */ + 0x87, 0x04, /* pcUpperThresholdQualDL */ + 0x88, 0x04, /* pcUpperThresholdQualUL */ + 0x89, 0x02, /* powerConfirm */ + 0x8A, 0x02, /* powerConfirmInterval */ + 0x8B, 0x02, /* powerIncrStepSize */ + 0x8C, 0x01, /* powerRedStepSize */ + 0x8D, 0x40, /* radioLinkTimeoutBs */ 0x65, 0x01, 0x00 // set to 0x01 to enable BSPowerControl }; -- cgit v1.2.3 From 7543eb72d0ba91d17fe7c9a6cd7d630beab1b19f Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 19 Jul 2009 17:51:36 +0200 Subject: fix copy+paste mistake in ecnoding short net name in mm info --- openbsc/src/gsm_04_08.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbsc/src') diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 9e0427e05..9fb53a723 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -1349,7 +1349,7 @@ int gsm48_tx_mm_info(struct gsm_lchan *lchan) name_len = strlen(net->name_short); /* 10.5.3.5a */ ptr8 = (u_int8_t *) msgb_put(msg, 3); - ptr8[0] = GSM48_IE_NAME_LONG; + ptr8[0] = GSM48_IE_NAME_SHORT; ptr8[1] = name_len*2 + 1; ptr8[2] = 0x90; /* UCS2, no spare bits, no CI */ -- cgit v1.2.3 From ae0f2362bb5a02ade62a02b73c4754922553d831 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 19 Jul 2009 18:36:49 +0200 Subject: send DEACTIVATE SACCH when sending RR CHANEL RELEASE As per specification, we first send the RR CHANNEL RELEASE to the MS, and then tell the BTS to disable the SACCH on that channel. --- openbsc/src/abis_rsl.c | 19 +++++++++++++++++++ openbsc/src/gsm_04_08.c | 6 +++++- 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'openbsc/src') diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index df95e7979..cc4a22934 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -652,6 +652,25 @@ int rsl_chan_mode_modify_req(struct gsm_lchan *lchan) return abis_rsl_sendmsg(msg); } +/* Chapter 8.4.5 */ +int rsl_deact_sacch(struct gsm_lchan *lchan) +{ + struct abis_rsl_dchan_hdr *dh; + struct msgb *msg = rsl_msgb_alloc(); + + dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh)); + init_dchan_hdr(dh, RSL_MT_DEACTIVATE_SACCH); + dh->chan_nr = lchan2chan_nr(lchan); + + msg->lchan = lchan; + msg->trx = lchan->ts->trx; + + DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n", + gsm_ts_name(lchan->ts), dh->chan_nr); + + return abis_rsl_sendmsg(msg); +} + /* Chapter 9.1.7 of 04.08 */ int rsl_chan_release(struct gsm_lchan *lchan) { diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 9fb53a723..df4d3c668 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -1769,7 +1769,11 @@ int gsm48_send_rr_release(struct gsm_lchan *lchan) DEBUGP(DRR, "Sending Channel Release: Chan: Number: %d Type: %d\n", lchan->nr, lchan->type); - return gsm48_sendmsg(msg); + /* Send actual release request to MS */ + gsm48_sendmsg(msg); + + /* Deactivate the SACCH on the BTS side */ + return rsl_deact_sacch(lchan); } /* Call Control */ -- cgit v1.2.3 From e6c22d9db778f0fa226ccdaac86ee44315f63bee Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 21 Jul 2009 20:40:05 +0200 Subject: use the TSC that is configured in bts->tsc rather than hardcoded value --- openbsc/src/abis_nm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbsc/src') diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c index f2383e2fa..2b5647962 100644 --- a/openbsc/src/abis_nm.c +++ b/openbsc/src/abis_nm.c @@ -1643,7 +1643,7 @@ int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, u_int8_t chan_comb) msgb_tv_put(msg, NM_ATT_HSN, 0x00); msgb_tv_put(msg, NM_ATT_MAIO, 0x00); } - msgb_tv_put(msg, NM_ATT_TSC, 0x07); /* training sequence */ + msgb_tv_put(msg, NM_ATT_TSC, bts->tsc); /* training sequence */ if (bts->type == GSM_BTS_TYPE_BS11) msgb_tlv_put(msg, 0x59, 1, &zero); -- cgit v1.2.3 From 814c4b79843fe9ead98672a1ad7ac989e7aab9b6 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 21 Jul 2009 20:55:56 +0200 Subject: use actual bts->tsc rather than hard-coded value --- openbsc/src/abis_rsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbsc/src') diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index cc4a22934..394d98e8e 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -1044,7 +1044,7 @@ static int rsl_rx_chan_rqd(struct msgb *msg) ia.chan_desc.h0.h = 0; ia.chan_desc.h0.arfcn_high = arfcn >> 8; ia.chan_desc.h0.arfcn_low = arfcn & 0xff; - ia.chan_desc.h0.tsc = 7; + ia.chan_desc.h0.tsc = bts->tsc; /* use request reference extracted from CHAN_RQD */ memcpy(&ia.req_ref, rqd_ref, sizeof(ia.req_ref)); ia.timing_advance = rqd_ta; -- cgit v1.2.3 From f8d536def97a65f5a0f1dec7f38ee15030acae53 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 21 Jul 2009 22:12:23 +0200 Subject: allow user to set BSIC and TSC from command line --- openbsc/src/bsc_hack.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c index c100ee4ba..1bfb7068b 100644 --- a/openbsc/src/bsc_hack.c +++ b/openbsc/src/bsc_hack.c @@ -56,6 +56,8 @@ static struct gsm_network *gsmnet; static int MCC = 1; static int MNC = 1; static int LAC = 1; +static int TSC = HARDCODED_TSC; +static int BSIC = HARDCODED_BSIC; static int ARFCN = HARDCODED_ARFCN; static int cardnr = 0; static int release_l2 = 0; @@ -893,13 +895,18 @@ static void patch_tables(struct gsm_bts *bts) /* patch BSIC */ bs11_attr_bts[1] = bts->bsic; nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic; + + /* patch TSC */ + si4[15] &= ~0xe0; + si4[15] |= (bts->tsc & 7) << 5; } static void bootstrap_rsl(struct gsm_bts_trx *trx) { fprintf(stdout, "bootstrapping RSL for BTS/TRX (%u/%u) " - "using MCC=%u MNC=%u\n", trx->nr, trx->bts->nr, MCC, MNC); + "using MCC=%u MNC=%u BSIC=%u TSC=%u\n", + trx->nr, trx->bts->nr, MCC, MNC, BSIC, TSC); set_system_infos(trx); } @@ -1019,7 +1026,7 @@ static int bootstrap_network(void) /* E1 mISDN input setup */ if (BTS_TYPE == GSM_BTS_TYPE_BS11) { - struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC); + struct gsm_bts *bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC); bootstrap_bts(bts); gsmnet->num_bts = 1; @@ -1034,7 +1041,7 @@ static int bootstrap_network(void) } llist_for_each_entry(bts_id, &nanobts_ids, entry) { - bts = gsm_bts_alloc(gsmnet, BTS_TYPE, HARDCODED_TSC, HARDCODED_BSIC); + bts = gsm_bts_alloc(gsmnet, BTS_TYPE, TSC, BSIC); bootstrap_bts(bts); bts->ip_access.site_id = bts_id->site_id; bts->ip_access.bts_id = 0; @@ -1104,10 +1111,12 @@ static void handle_options(int argc, char** argv) {"timestamp", 0, 0, 'T'}, {"band", 0, 0, 'b'}, {"bts-id", 1, 0, 'i'}, + {"tsc", 1, 0, 'S'}, + {"bsic", 1, 0, 'B'}, {0, 0, 0, 0} }; - c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:", + c = getopt_long(argc, argv, "hc:n:d:sar:p:f:t:C:RL:l:Tb:i:S:B:", long_options, &option_index); if (c == -1) break; @@ -1172,6 +1181,12 @@ static void handle_options(int argc, char** argv) bts_id->site_id = atoi(optarg); llist_add(&bts_id->entry, &nanobts_ids); break; + case 'S': + TSC = atoi(optarg); + break; + case 'B': + BSIC = atoi(optarg); + break; } default: /* ignore */ -- cgit v1.2.3 From aa0b29c2650104b4cb06cd63f295af16fa3a3231 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 23 Jul 2009 18:56:43 +0200 Subject: gms_transactions data model reorganization This changeset factors out gsm_transaction as something independent of call control in preparation to re-use the code from SMS. A transaction is uniquely identified by either its callref, or by a tuple of (transaction_id, protocol, subscriber). --- openbsc/src/Makefile.am | 3 +- openbsc/src/gsm_04_08.c | 183 ++++++++++++++++--------------------------- openbsc/src/gsm_subscriber.c | 1 + 3 files changed, 69 insertions(+), 118 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am index c0ac63cb1..c6e9dae53 100644 --- a/openbsc/src/Makefile.am +++ b/openbsc/src/Makefile.am @@ -9,7 +9,8 @@ libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_04_08.c gsm_data.c mncc.c \ gsm_subscriber.c msgb.c select.c chan_alloc.c timer.c debug.c db.c \ gsm_04_11.c telnet_interface.c subchan_demux.c \ trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c tlv_parser.c \ - input/misdn.c input/ipaccess.c signal.c gsm_utils.c talloc.c + input/misdn.c input/ipaccess.c signal.c gsm_utils.c talloc.c \ + transaction.c libvty_a_SOURCES = vty/buffer.c vty/command.c vty/vector.c vty/vty.c diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index df4d3c668..6f729e370 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -45,6 +45,7 @@ #include #include #include +#include #define GSM48_ALLOC_SIZE 1024 #define GSM48_ALLOC_HEADROOM 128 @@ -54,7 +55,6 @@ #define GSM_MAX_USERUSER 128 static void *tall_locop_ctx; -static void *tall_trans_ctx; static const struct tlv_definition rsl_att_tlvdef = { .def = { @@ -292,7 +292,6 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi); static int gsm48_tx_simple(struct gsm_lchan *lchan, u_int8_t pdisc, u_int8_t msg_type); static void schedule_reject(struct gsm_lchan *lchan); -void free_trans(struct gsm_trans *trans); struct gsm_lai { u_int16_t mcc; @@ -392,9 +391,12 @@ static int gsm0408_handle_lchan_signal(unsigned int subsys, unsigned int signal, release_loc_updating_req(lchan); /* Free all transactions that are associated with the released lchan */ + /* FIXME: this is not neccessarily the right thing to do, we should + * only set trans->lchan to NULL and wait for another lchan to be + * established to the same MM entity (phone/subscriber) */ llist_for_each_entry_safe(trans, temp, &lchan->ts->trx->bts->network->trans_list, entry) { if (trans->lchan == lchan) - free_trans(trans); + trans_free(trans); } return 0; @@ -1789,9 +1791,9 @@ static void new_cc_state(struct gsm_trans *trans, int state) return; DEBUGP(DCC, "new state %s -> %s\n", - cc_state_names[trans->state], cc_state_names[state]); + cc_state_names[trans->cc.state], cc_state_names[state]); - trans->state = state; + trans->cc.state = state; } static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg) @@ -1831,10 +1833,10 @@ static int gsm48_tx_simple(struct gsm_lchan *lchan, static void gsm48_stop_cc_timer(struct gsm_trans *trans) { - if (bsc_timer_pending(&trans->cc_timer)) { - DEBUGP(DCC, "stopping pending timer T%x\n", trans->Tcurrent); - bsc_del_timer(&trans->cc_timer); - trans->Tcurrent = 0; + if (bsc_timer_pending(&trans->cc.timer)) { + DEBUGP(DCC, "stopping pending timer T%x\n", trans->cc.Tcurrent); + bsc_del_timer(&trans->cc.timer); + trans->cc.Tcurrent = 0; } } @@ -1883,10 +1885,10 @@ int mncc_release_ind(struct gsm_network *net, struct gsm_trans *trans, return mncc_recvmsg(net, trans, MNCC_REL_IND, &rel); } -void free_trans(struct gsm_trans *trans) +/* Call Control Specific transaction release. + * gets called by trans_free, DO NOT CALL YOURSELF! */ +void _gsm48_cc_trans_free(struct gsm_trans *trans) { - struct gsm_bts *bts; - gsm48_stop_cc_timer(trans); /* send release to L4, if callref still exists */ @@ -1895,37 +1897,11 @@ void free_trans(struct gsm_trans *trans) mncc_release_ind(trans->network, trans, trans->callref, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL); - if (trans->state != GSM_CSTATE_NULL) - new_cc_state(trans, GSM_CSTATE_NULL); - } - - 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->lchan) { - trau_mux_unmap(&trans->lchan->ts->e1_link, trans->callref); - put_lchan(trans->lchan); } - - if (trans->subscr) - subscr_put(trans->subscr); - - if (trans->state != GSM_CSTATE_NULL) + if (trans->cc.state != GSM_CSTATE_NULL) new_cc_state(trans, GSM_CSTATE_NULL); - - llist_del(&trans->entry); - - talloc_free(trans); + if (trans->lchan) + trau_mux_unmap(&trans->lchan->ts->e1_link, trans->callref); } static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg); @@ -1966,7 +1942,7 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event, use_lchan(lchan); } /* send SETUP request to called party */ - gsm48_cc_tx_setup(transt, &transt->cc_msg); + gsm48_cc_tx_setup(transt, &transt->cc.msg); if (is_ipaccess_bts(lchan->ts->trx->bts)) rsl_ipacc_bind(lchan); break; @@ -1978,7 +1954,7 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_DEST_OOO); transt->callref = 0; - free_trans(transt); + trans_free(transt); break; } } @@ -2027,21 +2003,11 @@ static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan) return 0; } -static struct gsm_trans *get_trans_ref(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; -} - /* bridge channels of two transactions */ static int tch_bridge(struct gsm_network *net, u_int32_t *refs) { - struct gsm_trans *trans1 = get_trans_ref(net, refs[0]); - struct gsm_trans *trans2 = get_trans_ref(net, refs[1]); + struct gsm_trans *trans1 = trans_find_by_callref(net, refs[0]); + struct gsm_trans *trans2 = trans_find_by_callref(net, refs[1]); if (!trans1 || !trans2) return -EIO; @@ -2059,7 +2025,7 @@ static int tch_recv(struct gsm_network *net, struct gsm_mncc *data, int enable) struct gsm_trans *trans; /* Find callref */ - trans = get_trans_ref(net, data->callref); + trans = trans_find_by_callref(net, data->callref); if (!trans) return -EIO; if (!trans->lchan) @@ -2077,7 +2043,7 @@ static int tch_frame(struct gsm_network *net, struct gsm_trau_frame *frame) struct gsm_trans *trans; /* Find callref */ - trans = get_trans_ref(net, frame->callref); + trans = trans_find_by_callref(net, frame->callref); if (!trans) return -EIO; if (!trans->lchan) @@ -2116,7 +2082,7 @@ static void gsm48_cc_timeout(void *arg) memset(&l4_rel, 0, sizeof(struct gsm_mncc)); l4_rel.callref = trans->callref; - switch(trans->Tcurrent) { + switch(trans->cc.Tcurrent) { case 0x303: release = 1; l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND; @@ -2134,21 +2100,21 @@ static void gsm48_cc_timeout(void *arg) l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND; break; case 0x308: - if (!trans->T308_second) { + if (!trans->cc.T308_second) { /* restart T308 a second time */ - gsm48_cc_tx_release(trans, &trans->cc_msg); - trans->T308_second = 1; + gsm48_cc_tx_release(trans, &trans->cc.msg); + trans->cc.T308_second = 1; break; /* stay in release state */ } - free_trans(trans); + trans_free(trans); return; // release = 1; // l4_cause = 14; // break; case 0x306: release = 1; - mo_cause = trans->cc_msg.cause.value; - mo_location = trans->cc_msg.cause.location; + mo_cause = trans->cc.msg.cause.value; + mo_location = trans->cc.msg.cause.location; break; case 0x323: disconnect = 1; @@ -2173,9 +2139,9 @@ static void gsm48_cc_timeout(void *arg) /* process disconnect towards mobile station */ if (disconnect || release) { mncc_set_cause(&mo_rel, mo_location, mo_cause); - mo_rel.cause.diag[0] = ((trans->Tcurrent & 0xf00) >> 8) + '0'; - mo_rel.cause.diag[1] = ((trans->Tcurrent & 0x0f0) >> 4) + '0'; - mo_rel.cause.diag[2] = (trans->Tcurrent & 0x00f) + '0'; + mo_rel.cause.diag[0] = ((trans->cc.Tcurrent & 0xf00) >> 8) + '0'; + mo_rel.cause.diag[1] = ((trans->cc.Tcurrent & 0x0f0) >> 4) + '0'; + mo_rel.cause.diag[2] = (trans->cc.Tcurrent & 0x00f) + '0'; mo_rel.cause.diag_len = 3; if (disconnect) @@ -2190,10 +2156,10 @@ static void gsm48_start_cc_timer(struct gsm_trans *trans, int current, int sec, int micro) { DEBUGP(DCC, "starting timer T%x with %d seconds\n", current, sec); - trans->cc_timer.cb = gsm48_cc_timeout; - trans->cc_timer.data = trans; - bsc_schedule_timer(&trans->cc_timer, sec, micro); - trans->Tcurrent = current; + trans->cc.timer.cb = gsm48_cc_timeout; + trans->cc.timer.data = trans; + bsc_schedule_timer(&trans->cc.timer, sec, micro); + trans->cc.Tcurrent = current; } static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) @@ -2293,7 +2259,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL); trans->callref = 0; - free_trans(trans); + trans_free(trans); return rc; } @@ -2311,7 +2277,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL); trans->callref = 0; - free_trans(trans); + trans_free(trans); return rc; } for (i = 0; i < 7; i++) { @@ -2695,7 +2661,7 @@ static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg) encode_useruser(msg, 0, &disc->useruser); /* store disconnect cause for T306 expiry */ - memcpy(&trans->cc_msg, disc, sizeof(struct gsm_mncc)); + memcpy(&trans->cc.msg, disc, sizeof(struct gsm_mncc)); new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND); @@ -2740,7 +2706,7 @@ static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg) TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); } - if (trans->state == GSM_CSTATE_RELEASE_REQ) { + if (trans->cc.state == GSM_CSTATE_RELEASE_REQ) { /* release collision 5.4.5 */ rc = mncc_recvmsg(trans->network, trans, MNCC_REL_CNF, &rel); } else { @@ -2752,7 +2718,7 @@ static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg) new_cc_state(trans, GSM_CSTATE_NULL); trans->callref = 0; - free_trans(trans); + trans_free(trans); return rc; } @@ -2782,10 +2748,10 @@ static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg) if (rel->fields & MNCC_F_USERUSER) encode_useruser(msg, 0, &rel->useruser); - trans->T308_second = 0; - memcpy(&trans->cc_msg, rel, sizeof(struct gsm_mncc)); + trans->cc.T308_second = 0; + memcpy(&trans->cc.msg, rel, sizeof(struct gsm_mncc)); - if (trans->state != GSM_CSTATE_RELEASE_REQ) + if (trans->cc.state != GSM_CSTATE_RELEASE_REQ) new_cc_state(trans, GSM_CSTATE_RELEASE_REQ); return gsm48_sendmsg(msg); @@ -2830,7 +2796,7 @@ static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg) } if (trans->callref) { - switch (trans->state) { + switch (trans->cc.state) { case GSM_CSTATE_CALL_PRESENT: rc = mncc_recvmsg(trans->network, trans, MNCC_REJ_IND, &rel); @@ -2846,7 +2812,7 @@ static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg) } trans->callref = 0; - free_trans(trans); + trans_free(trans); return rc; } @@ -2875,7 +2841,7 @@ static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg) if (rel->fields & MNCC_F_USERUSER) encode_useruser(msg, 0, &rel->useruser); - free_trans(trans); + trans_free(trans); return gsm48_sendmsg(msg); } @@ -3385,7 +3351,7 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg) rel.callref = data->callref; /* Find callref */ - trans = get_trans_ref(net, data->callref); + trans = trans_find_by_callref(net, data->callref); /* Callref unknown */ if (!trans) { @@ -3437,7 +3403,8 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg) GSM48_CC_CAUSE_DEST_OOO); } /* Create transaction */ - if (!(trans = talloc_zero(tall_trans_ctx, struct gsm_trans))) { + trans = trans_alloc(subscr, GSM48_PDISC_CC, 0xff, data->callref); + if (!trans) { DEBUGP(DCC, "No memory for trans.\n"); subscr_put(subscr); /* Ressource unavailable */ @@ -3446,12 +3413,6 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg) GSM48_CC_CAUSE_RESOURCE_UNAVAIL); return -ENOMEM; } - trans->callref = data->callref; - trans->network = net; - trans->transaction_id = 0xff; /* unassigned */ - llist_add_tail(&trans->entry, &net->trans_list); - /* Assign subscriber to transaction */ - trans->subscr = subscr; /* Find lchan */ for (i = 0; i < net->num_bts; i++) { bts = gsm_bts_num(net, i); @@ -3487,7 +3448,7 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg) return 0; } /* store setup informations until paging was successfull */ - memcpy(&trans->cc_msg, data, sizeof(struct gsm_mncc)); + memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc)); /* start paging subscriber on all BTS with her location */ subscr->net = net; bts = NULL; @@ -3525,7 +3486,7 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg) else rc = mncc_recvmsg(net, trans, MNCC_REL_IND, &rel); trans->callref = 0; - free_trans(trans); + trans_free(trans); return rc; } @@ -3534,13 +3495,13 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg) lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, trans->transaction_id, (lchan->subscr)?(lchan->subscr->extension):"-", - get_mncc_name(msg_type), trans->state, - cc_state_names[trans->state]); + get_mncc_name(msg_type), trans->cc.state, + cc_state_names[trans->cc.state]); /* Find function for current state and message */ for (i = 0; i < DOWNSLLEN; i++) if ((msg_type == downstatelist[i].type) - && ((1 << trans->state) & downstatelist[i].states)) + && ((1 << trans->cc.state) & downstatelist[i].states)) break; if (i == DOWNSLLEN) { DEBUGP(DCC, "Message unhandled at this state.\n"); @@ -3613,8 +3574,7 @@ static int gsm0408_rcv_cc(struct msgb *msg) u_int8_t msg_type = gh->msg_type & 0xbf; u_int8_t transaction_id = (gh->proto_discr & 0xf0) ^ 0x80; /* flip */ struct gsm_lchan *lchan = msg->lchan; - struct gsm_trans *trans = NULL, *transt; - struct gsm_network *net = lchan->ts->trx->bts->network; + struct gsm_trans *trans = NULL; int i, rc = 0; if (msg_type & 0x80) { @@ -3623,50 +3583,38 @@ static int gsm0408_rcv_cc(struct msgb *msg) } /* Find transaction */ - llist_for_each_entry(transt, &net->trans_list, entry) { - /* Transaction of our lchan? */ - if (transt->lchan == lchan - && transt->transaction_id == transaction_id) { - trans = transt; - } - } - + trans = trans_find_by_id(lchan, transaction_id); + DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) " "Received '%s' from MS in state %d (%s)\n", lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, transaction_id, (lchan->subscr)?(lchan->subscr->extension):"-", - cc_msg_names[msg_type], trans?(trans->state):0, - cc_state_names[trans?(trans->state):0]); + cc_msg_names[msg_type], trans?(trans->cc.state):0, + cc_state_names[trans?(trans->cc.state):0]); /* Create transaction */ if (!trans) { DEBUGP(DCC, "Unknown transaction ID %02x, " "creating new trans.\n", transaction_id); /* Create transaction */ - if (!(trans = talloc_zero(tall_trans_ctx, struct gsm_trans))) { + trans = trans_alloc(lchan->subscr, GSM48_PDISC_CC, + transaction_id, new_callref++); + if (!trans) { DEBUGP(DCC, "No memory for trans.\n"); rc = gsm48_tx_simple(msg->lchan, GSM48_PDISC_CC | transaction_id, GSM48_MT_CC_RELEASE_COMPL); return -ENOMEM; } - llist_add_tail(&trans->entry, &net->trans_list); /* Assign transaction */ - trans->callref = new_callref++; - trans->network = net; - trans->transaction_id = transaction_id; trans->lchan = lchan; use_lchan(lchan); - if (lchan->subscr) { - trans->subscr = lchan->subscr; - subscr_get(trans->subscr); - } } /* find function for current state and message */ for (i = 0; i < DATASLLEN; i++) if ((msg_type == datastatelist[i].type) - && ((1 << trans->state) & datastatelist[i].states)) + && ((1 << trans->cc.state) & datastatelist[i].states)) break; if (i == DATASLLEN) { DEBUGP(DCC, "Message unhandled at this state.\n"); @@ -3823,3 +3771,4 @@ int bsc_upqueue(struct gsm_network *net) return work; } + diff --git a/openbsc/src/gsm_subscriber.c b/openbsc/src/gsm_subscriber.c index a323d4e87..56f15951a 100644 --- a/openbsc/src/gsm_subscriber.c +++ b/openbsc/src/gsm_subscriber.c @@ -168,6 +168,7 @@ int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason) /* FIXME: Migrate pending requests from one BSC to another */ switch (reason) { case GSM_SUBSCRIBER_UPDATE_ATTACHED: + s->net = bts->network; /* Indicate "attached to LAC" */ s->lac = bts->location_area_code; break; -- cgit v1.2.3 From b3c3faee940cda77afa9ba2500afa9ae9919851e Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 23 Jul 2009 19:06:52 +0200 Subject: remove bogus 'network' member of 'struct gsm_transaction' Since a transaction is associated to a gsm_subscriber, and the subsciber is part of a network, we don't need to have a dedicated transaction->network pointer. --- openbsc/src/gsm_04_08.c | 65 ++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 30 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 6f729e370..4359f8709 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -1894,7 +1894,7 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans) /* send release to L4, if callref still exists */ if (trans->callref) { /* Ressource unavailable */ - mncc_release_ind(trans->network, trans, trans->callref, + mncc_release_ind(trans->subscr->net, trans, trans->callref, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL); } @@ -1950,7 +1950,8 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event, DEBUGP(DCC, "Paging subscr %s expired!\n", subscr->extension); /* Temporarily out of order */ - mncc_release_ind(transt->network, transt, transt->callref, + mncc_release_ind(transt->subscr->net, transt, + transt->callref, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_DEST_OOO); transt->callref = 0; @@ -2125,7 +2126,7 @@ static void gsm48_cc_timeout(void *arg) if (release && trans->callref) { /* process release towards layer 4 */ - mncc_release_ind(trans->network, trans, trans->callref, + mncc_release_ind(trans->subscr->net, trans, trans->callref, l4_location, l4_cause); trans->callref = 0; } @@ -2133,7 +2134,7 @@ static void gsm48_cc_timeout(void *arg) if (disconnect && trans->callref) { /* process disconnect towards layer 4 */ mncc_set_cause(&l4_rel, l4_location, l4_cause); - mncc_recvmsg(trans->network, trans, MNCC_DISC_IND, &l4_rel); + mncc_recvmsg(trans->subscr->net, trans, MNCC_DISC_IND, &l4_rel); } /* process disconnect towards mobile station */ @@ -2234,7 +2235,7 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) new_cc_state(trans, GSM_CSTATE_INITIATED); /* indicate setup to MNCC */ - mncc_recvmsg(trans->network, trans, MNCC_SETUP_IND, &setup); + mncc_recvmsg(trans->subscr->net, trans, MNCC_SETUP_IND, &setup); return 0; } @@ -2255,7 +2256,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) DEBUGP(DCC, "TX Setup with assigned transaction. " "This is not allowed!\n"); /* Temporarily out of order */ - rc = mncc_release_ind(trans->network, trans, trans->callref, + rc = mncc_release_ind(trans->subscr->net, trans, trans->callref, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL); trans->callref = 0; @@ -2264,7 +2265,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) } /* Get free transaction_id */ - llist_for_each_entry(transt, &trans->network->trans_list, entry) { + llist_for_each_entry(transt, &trans->subscr->net->trans_list, entry) { /* Transaction of our lchan? */ if (transt->lchan == trans->lchan && transt->transaction_id != 0xff) @@ -2273,7 +2274,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) /* Assign free transaction ID */ if ((trans_id_mask & 0x007f) == 0x7f) { /* no free transaction ID */ - rc = mncc_release_ind(trans->network, trans, trans->callref, + rc = mncc_release_ind(trans->subscr->net, trans, trans->callref, GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_RESOURCE_UNAVAIL); trans->callref = 0; @@ -2364,7 +2365,8 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg) new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF); - return mncc_recvmsg(trans->network, trans, MNCC_CALL_CONF_IND, &call_conf); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_CALL_CONF_IND, + &call_conf); } static int gsm48_cc_tx_call_proc(struct gsm_trans *trans, void *arg) @@ -2427,7 +2429,8 @@ static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg) new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED); - return mncc_recvmsg(trans->network, trans, MNCC_ALERT_IND, &alerting); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_ALERT_IND, + &alerting); } static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg) @@ -2546,7 +2549,7 @@ static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg) new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST); - return mncc_recvmsg(trans->network, trans, MNCC_SETUP_CNF, &connect); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_SETUP_CNF, &connect); } @@ -2560,7 +2563,7 @@ static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg) memset(&connect_ack, 0, sizeof(struct gsm_mncc)); connect_ack.callref = trans->callref; - return mncc_recvmsg(trans->network, trans, MNCC_SETUP_COMPL_IND, + return mncc_recvmsg(trans->subscr->net, trans, MNCC_SETUP_COMPL_IND, &connect_ack); } @@ -2617,7 +2620,7 @@ static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg) TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); } - return mncc_recvmsg(trans->network, trans, MNCC_DISC_IND, &disc); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_DISC_IND, &disc); } @@ -2708,11 +2711,12 @@ static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg) if (trans->cc.state == GSM_CSTATE_RELEASE_REQ) { /* release collision 5.4.5 */ - rc = mncc_recvmsg(trans->network, trans, MNCC_REL_CNF, &rel); + rc = mncc_recvmsg(trans->subscr->net, trans, MNCC_REL_CNF, &rel); } else { - rc = gsm48_tx_simple(msg->lchan, GSM48_PDISC_CC | trans->transaction_id, - GSM48_MT_CC_RELEASE_COMPL); - rc = mncc_recvmsg(trans->network, trans, MNCC_REL_IND, &rel); + rc = gsm48_tx_simple(msg->lchan, + GSM48_PDISC_CC | trans->transaction_id, + GSM48_MT_CC_RELEASE_COMPL); + rc = mncc_recvmsg(trans->subscr->net, trans, MNCC_REL_IND, &rel); } new_cc_state(trans, GSM_CSTATE_NULL); @@ -2798,15 +2802,15 @@ static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg) if (trans->callref) { switch (trans->cc.state) { case GSM_CSTATE_CALL_PRESENT: - rc = mncc_recvmsg(trans->network, trans, + rc = mncc_recvmsg(trans->subscr->net, trans, MNCC_REJ_IND, &rel); break; case GSM_CSTATE_RELEASE_REQ: - rc = mncc_recvmsg(trans->network, trans, + rc = mncc_recvmsg(trans->subscr->net, trans, MNCC_REL_CNF, &rel); break; default: - rc = mncc_recvmsg(trans->network, trans, + rc = mncc_recvmsg(trans->subscr->net, trans, MNCC_REL_IND, &rel); } } @@ -2869,7 +2873,7 @@ static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg) TLVP_VAL(&tp, GSM48_IE_SS_VERS)-1); } - return mncc_recvmsg(trans->network, trans, MNCC_FACILITY_IND, &fac); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_FACILITY_IND, &fac); } static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg) @@ -2894,7 +2898,7 @@ static int gsm48_cc_rx_hold(struct gsm_trans *trans, struct msgb *msg) memset(&hold, 0, sizeof(struct gsm_mncc)); hold.callref = trans->callref; - return mncc_recvmsg(trans->network, trans, MNCC_HOLD_IND, &hold); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_HOLD_IND, &hold); } static int gsm48_cc_tx_hold_ack(struct gsm_trans *trans, void *arg) @@ -2934,7 +2938,8 @@ static int gsm48_cc_rx_retrieve(struct gsm_trans *trans, struct msgb *msg) memset(&retrieve, 0, sizeof(struct gsm_mncc)); retrieve.callref = trans->callref; - return mncc_recvmsg(trans->network, trans, MNCC_RETRIEVE_IND, &retrieve); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_RETRIEVE_IND, + &retrieve); } static int gsm48_cc_tx_retrieve_ack(struct gsm_trans *trans, void *arg) @@ -2985,7 +2990,7 @@ static int gsm48_cc_rx_start_dtmf(struct gsm_trans *trans, struct msgb *msg) TLVP_VAL(&tp, GSM48_IE_KPD_FACILITY)-1); } - return mncc_recvmsg(trans->network, trans, MNCC_START_DTMF_IND, &dtmf); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_START_DTMF_IND, &dtmf); } static int gsm48_cc_tx_start_dtmf_ack(struct gsm_trans *trans, void *arg) @@ -3043,7 +3048,7 @@ static int gsm48_cc_rx_stop_dtmf(struct gsm_trans *trans, struct msgb *msg) memset(&dtmf, 0, sizeof(struct gsm_mncc)); dtmf.callref = trans->callref; - return mncc_recvmsg(trans->network, trans, MNCC_STOP_DTMF_IND, &dtmf); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_STOP_DTMF_IND, &dtmf); } static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg) @@ -3065,7 +3070,7 @@ static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg) new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY); - return mncc_recvmsg(trans->network, trans, MNCC_MODIFY_IND, &modify); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_MODIFY_IND, &modify); } static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg) @@ -3109,7 +3114,7 @@ static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg new_cc_state(trans, GSM_CSTATE_ACTIVE); - return mncc_recvmsg(trans->network, trans, MNCC_MODIFY_CNF, &modify); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_MODIFY_CNF, &modify); } static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg) @@ -3157,7 +3162,7 @@ static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg) new_cc_state(trans, GSM_CSTATE_ACTIVE); - return mncc_recvmsg(trans->network, trans, MNCC_MODIFY_REJ, &modify); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_MODIFY_REJ, &modify); } static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg) @@ -3209,7 +3214,7 @@ static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg) if (payload_len >= 1) decode_notify(¬ify.notify, gh->data); - return mncc_recvmsg(trans->network, trans, MNCC_NOTIFY_IND, ¬ify); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_NOTIFY_IND, ¬ify); } static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg) @@ -3252,7 +3257,7 @@ static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg) if (TLVP_PRESENT(&tp, GSM48_IE_MORE_DATA)) user.more = 1; - return mncc_recvmsg(trans->network, trans, MNCC_USERINFO_IND, &user); + return mncc_recvmsg(trans->subscr->net, trans, MNCC_USERINFO_IND, &user); } static int gsm48_lchan_modify(struct gsm_trans *trans, void *arg) -- cgit v1.2.3 From 761e944182255225bd2d48caa7d66a28ec7dea65 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 23 Jul 2009 19:21:02 +0200 Subject: make sure subscr->net is always set since a subscriber is an element of the gsm_network, we have to ensure subscr->net is always set correctly. We do this by using gsm_network as an argument to all functions that resolve or create a subscriber. --- openbsc/src/db.c | 14 ++++++++++---- openbsc/src/gsm_04_08.c | 27 +++++++++++++++++---------- openbsc/src/gsm_04_11.c | 3 ++- openbsc/src/gsm_subscriber.c | 15 +++++++++------ openbsc/src/vty_interface.c | 4 ++-- 5 files changed, 40 insertions(+), 23 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/db.c b/openbsc/src/db.c index 543f44ce2..fc2950a36 100644 --- a/openbsc/src/db.c +++ b/openbsc/src/db.c @@ -158,12 +158,13 @@ int db_fini() { return 0; } -struct gsm_subscriber* db_create_subscriber(char *imsi) { +struct gsm_subscriber* db_create_subscriber(struct gsm_network *net, char *imsi) +{ dbi_result result; struct gsm_subscriber* subscr; /* Is this subscriber known in the db? */ - subscr = db_get_subscriber(GSM_SUBSCRIBER_IMSI, imsi); + subscr = db_get_subscriber(net, GSM_SUBSCRIBER_IMSI, imsi); if (subscr) { result = dbi_conn_queryf(conn, "UPDATE Subscriber set updated = datetime('now') " @@ -189,6 +190,7 @@ struct gsm_subscriber* db_create_subscriber(char *imsi) { if (result==NULL) { printf("DB: Failed to create Subscriber by IMSI.\n"); } + subscr->net = net; subscr->id = dbi_conn_sequence_last(conn, NULL); strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH-1); dbi_result_free(result); @@ -196,7 +198,10 @@ struct gsm_subscriber* db_create_subscriber(char *imsi) { return subscr; } -struct gsm_subscriber *db_get_subscriber(enum gsm_subscriber_field field, const char *id) { +struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, + enum gsm_subscriber_field field, + const char *id) +{ dbi_result result; const char *string; char *quoted; @@ -246,6 +251,7 @@ struct gsm_subscriber *db_get_subscriber(enum gsm_subscriber_field field, const } subscr = subscr_alloc(); + subscr->net = net; subscr->id = dbi_result_get_ulonglong(result, "id"); string = dbi_result_get_string(result, "imsi"); if (string) @@ -459,7 +465,7 @@ int db_sms_store(struct gsm_sms *sms) } /* retrieve the next unsent SMS with ID >= min_id */ -struct gsm_sms *db_sms_get_unsent(int min_id) +struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_id) { dbi_result result; struct gsm_sms *sms = malloc(sizeof(*sms)); diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 4359f8709..507daf998 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -1131,6 +1131,8 @@ static int mm_rx_id_resp(struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); struct gsm_lchan *lchan = msg->lchan; + struct gsm_bts *bts = lchan->ts->trx->bts; + struct gsm_network *net = bts->network; u_int8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK; char mi_string[MI_SIZE]; @@ -1141,7 +1143,7 @@ static int mm_rx_id_resp(struct msgb *msg) switch (mi_type) { case GSM_MI_TYPE_IMSI: if (!lchan->subscr) - lchan->subscr = db_create_subscriber(mi_string); + lchan->subscr = db_create_subscriber(net, mi_string); if (lchan->loc_operation) lchan->loc_operation->waiting_for_imsi = 0; break; @@ -1198,6 +1200,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg) struct gsm48_loc_upd_req *lu; struct gsm_subscriber *subscr = NULL; struct gsm_lchan *lchan = msg->lchan; + struct gsm_bts *bts = lchan->ts->trx->bts; u_int8_t mi_type; char mi_string[MI_SIZE]; int rc; @@ -1232,7 +1235,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg) lchan->loc_operation->waiting_for_imei = 1; /* look up subscriber based on IMSI */ - subscr = db_create_subscriber(mi_string); + subscr = db_create_subscriber(bts->network, mi_string); break; case GSM_MI_TYPE_TMSI: DEBUGPC(DMM, "\n"); @@ -1241,7 +1244,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg) lchan->loc_operation->waiting_for_imei = 1; /* look up the subscriber based on TMSI, request IMSI if it fails */ - subscr = subscr_get_by_tmsi(mi_string); + subscr = subscr_get_by_tmsi(bts->network, mi_string); if (!subscr) { /* send IDENTITY REQUEST message to get IMSI */ rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMSI); @@ -1423,6 +1426,7 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg) u_int8_t mi_type; char mi_string[MI_SIZE]; + struct gsm_bts *bts = msg->lchan->ts->trx->bts; struct gsm_subscriber *subscr; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_service_request *req = @@ -1457,7 +1461,7 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg) DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n", req->cm_service_type, mi_type, mi_string); - subscr = subscr_get_by_tmsi(mi_string); + subscr = subscr_get_by_tmsi(bts->network, mi_string); /* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */ if (!subscr) @@ -1480,6 +1484,7 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg) static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg) { + struct gsm_bts *bts = msg->lchan->ts->trx->bts; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_imsi_detach_ind *idi = (struct gsm48_imsi_detach_ind *) gh->data; @@ -1493,10 +1498,10 @@ static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg) switch (mi_type) { case GSM_MI_TYPE_TMSI: - subscr = subscr_get_by_tmsi(mi_string); + subscr = subscr_get_by_tmsi(bts->network, mi_string); break; case GSM_MI_TYPE_IMSI: - subscr = subscr_get_by_imsi(mi_string); + subscr = subscr_get_by_imsi(bts->network, mi_string); break; case GSM_MI_TYPE_IMEI: case GSM_MI_TYPE_IMEISV: @@ -1576,6 +1581,7 @@ static int gsm0408_rcv_mm(struct msgb *msg) /* Receive a PAGING RESPONSE message from the MS */ static int gsm48_rr_rx_pag_resp(struct msgb *msg) { + struct gsm_bts *bts = msg->lchan->ts->trx->bts; struct gsm48_hdr *gh = msgb_l3(msg); u_int8_t *classmark2_lv = gh->data + 1; u_int8_t *mi_lv = gh->data + 2 + *classmark2_lv; @@ -1590,10 +1596,10 @@ static int gsm48_rr_rx_pag_resp(struct msgb *msg) mi_type, mi_string); switch (mi_type) { case GSM_MI_TYPE_TMSI: - subscr = subscr_get_by_tmsi(mi_string); + subscr = subscr_get_by_tmsi(bts->network, mi_string); break; case GSM_MI_TYPE_IMSI: - subscr = subscr_get_by_imsi(mi_string); + subscr = subscr_get_by_imsi(bts->network, mi_string); break; } @@ -3381,9 +3387,10 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg) } /* New transaction due to setup, find subscriber */ if (data->called.number[0]) - subscr = subscr_get_by_extension(data->called.number); + subscr = subscr_get_by_extension(net, + data->called.number); else - subscr = subscr_get_by_imsi(data->imsi); + subscr = subscr_get_by_imsi(net, data->imsi); /* If subscriber is not found */ if (!subscr) { DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) " diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c index 1b622b12b..8db402b33 100644 --- a/openbsc/src/gsm_04_11.c +++ b/openbsc/src/gsm_04_11.c @@ -154,6 +154,7 @@ static int gsm340_rx_sms_submit(struct msgb *msg, struct sms_submit *sms, /* process an incoming TPDU (called from RP-DATA) */ static int gsm340_rx_tpdu(struct msgb *msg) { + struct gsm_bts *bts = msg->lchan->ts->trx->bts; u_int8_t *smsp = msgb_sms(msg); struct sms_submit *sms; struct gsm_sms *gsms; @@ -257,7 +258,7 @@ static int gsm340_rx_tpdu(struct msgb *msg) /* FIXME: sender refcount */ /* determine gsms->receiver based on dialled number */ - gsms->receiver = subscr_get_by_extension(sms->dest_addr); + gsms->receiver = subscr_get_by_extension(bts->network, sms->dest_addr); if (!gsms->receiver) { rc = 1; /* cause 1: unknown subscriber */ goto out; diff --git a/openbsc/src/gsm_subscriber.c b/openbsc/src/gsm_subscriber.c index 56f15951a..e89290623 100644 --- a/openbsc/src/gsm_subscriber.c +++ b/openbsc/src/gsm_subscriber.c @@ -126,7 +126,8 @@ static void subscr_free(struct gsm_subscriber *subscr) talloc_free(subscr); } -struct gsm_subscriber *subscr_get_by_tmsi(const char *tmsi) +struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_network *net, + const char *tmsi) { struct gsm_subscriber *subscr; @@ -136,10 +137,11 @@ struct gsm_subscriber *subscr_get_by_tmsi(const char *tmsi) return subscr_get(subscr); } - return db_get_subscriber(GSM_SUBSCRIBER_TMSI, tmsi); + return db_get_subscriber(net, GSM_SUBSCRIBER_TMSI, tmsi); } -struct gsm_subscriber *subscr_get_by_imsi(const char *imsi) +struct gsm_subscriber *subscr_get_by_imsi(struct gsm_network *net, + const char *imsi) { struct gsm_subscriber *subscr; @@ -148,10 +150,11 @@ struct gsm_subscriber *subscr_get_by_imsi(const char *imsi) return subscr_get(subscr); } - return db_get_subscriber(GSM_SUBSCRIBER_IMSI, imsi); + return db_get_subscriber(net, GSM_SUBSCRIBER_IMSI, imsi); } -struct gsm_subscriber *subscr_get_by_extension(const char *ext) +struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net, + const char *ext) { struct gsm_subscriber *subscr; @@ -160,7 +163,7 @@ struct gsm_subscriber *subscr_get_by_extension(const char *ext) return subscr_get(subscr); } - return db_get_subscriber(GSM_SUBSCRIBER_EXTENSION, ext); + return db_get_subscriber(net, GSM_SUBSCRIBER_EXTENSION, ext); } int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason) diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index 462689098..11b2ff60b 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -589,7 +589,7 @@ DEFUN(cfg_subscr, const char *imsi = argv[0]; struct gsm_subscriber *subscr; - subscr = subscr_get_by_imsi(imsi); + subscr = subscr_get_by_imsi(gsmnet, imsi); if (!subscr) { vty_out(vty, "%% No subscriber for IMSI %s%s", imsi, VTY_NEWLINE); @@ -855,7 +855,7 @@ DEFUN(show_subscr, if (argc >= 1) { imsi = argv[0]; - subscr = subscr_get_by_imsi(imsi); + subscr = subscr_get_by_imsi(gsmnet, imsi); if (!subscr) { vty_out(vty, "%% unknown subscriber%s", VTY_NEWLINE); -- cgit v1.2.3 From 39e2eadc99c38876c39700cc2f8fa2a2973c1fdd Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 23 Jul 2009 21:13:03 +0200 Subject: centralize the code that needs to deal with transaction_id There were many places in the code where we had to explicitly reference the transaction_id and put it into a packet. By introducing and optional gsm_trans parameter to gsm48_sendmsg(), we can implement this code once rather than dozens of time. --- openbsc/src/gsm_04_08.c | 120 +++++++++++++++++------------------------------- 1 file changed, 41 insertions(+), 79 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 507daf998..ab9a4085b 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -983,10 +983,18 @@ struct msgb *gsm48_msgb_alloc(void) "GSM 04.08"); } -int gsm48_sendmsg(struct msgb *msg) +int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans) { + struct gsm48_hdr *gh = (struct gsm48_hdr *) msg->data; + + /* if we get passed a transaction reference, do some common + * work that the caller no longer has to do */ + if (trans) { + gh->proto_discr = trans->protocol | trans->transaction_id; + msg->lchan = trans->lchan; + } + if (msg->lchan) { - struct gsm48_hdr *gh = (struct gsm48_hdr *) msg->data; msg->trx = msg->lchan->ts->trx; if ((gh->proto_discr & GSM48_PDISC_MASK) == GSM48_PDISC_CC) @@ -1022,7 +1030,7 @@ int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause) DEBUGP(DMM, "-> LOCATION UPDATING REJECT on channel: %d\n", lchan->nr); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, NULL); } /* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */ @@ -1050,7 +1058,7 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi) DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n"); - ret = gsm48_sendmsg(msg); + ret = gsm48_sendmsg(msg, NULL); ret = gsm48_tx_mm_info(lchan); @@ -1121,7 +1129,7 @@ static int mm_tx_identity_req(struct gsm_lchan *lchan, u_int8_t id_type) gh->msg_type = GSM48_MT_MM_ID_REQ; gh->data[0] = id_type; - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, NULL); } #define MI_SIZE 32 @@ -1302,7 +1310,7 @@ int gsm48_tx_chan_mode_modify(struct gsm_lchan *lchan, u_int8_t mode) cmm->chan_desc.h0.arfcn_low = arfcn & 0xff; cmm->mode = mode; - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, NULL); } #if 0 @@ -1382,7 +1390,7 @@ int gsm48_tx_mm_info(struct gsm_lchan *lchan) ptr8[7] |= 0x80; #endif - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, NULL); } static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan) @@ -1408,7 +1416,7 @@ static int gsm48_tx_mm_serv_rej(struct gsm_lchan *lchan, gh->data[0] = value; DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, NULL); } @@ -1778,7 +1786,7 @@ int gsm48_send_rr_release(struct gsm_lchan *lchan) lchan->nr, lchan->type); /* Send actual release request to MS */ - gsm48_sendmsg(msg); + gsm48_sendmsg(msg, NULL); /* Deactivate the SACCH on the BTS side */ return rsl_deact_sacch(lchan); @@ -1808,8 +1816,6 @@ static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg) struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); u_int8_t *cause, *call_state; - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_STATUS; cause = msgb_put(msg, 3); @@ -1820,7 +1826,7 @@ static int gsm48_cc_tx_status(struct gsm_trans *trans, void *arg) call_state = msgb_put(msg, 1); call_state[0] = 0xc0 | 0x00; - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_tx_simple(struct gsm_lchan *lchan, @@ -1834,7 +1840,7 @@ static int gsm48_tx_simple(struct gsm_lchan *lchan, gh->proto_discr = pdisc; gh->msg_type = msg_type; - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, NULL); } static void gsm48_stop_cc_timer(struct gsm_trans *trans) @@ -2294,8 +2300,6 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) } } - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_SETUP; gsm48_start_cc_timer(trans, 0x303, GSM48_T303); @@ -2327,7 +2331,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_CALL_PRESENT); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg) @@ -2381,8 +2385,6 @@ static int gsm48_cc_tx_call_proc(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_CALL_PROC; new_cc_state(trans, GSM_CSTATE_MO_CALL_PROC); @@ -2397,7 +2399,7 @@ static int gsm48_cc_tx_call_proc(struct gsm_trans *trans, void *arg) if (proceeding->fields & MNCC_F_PROGRESS) encode_progress(msg, 0, &proceeding->progress); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg) @@ -2445,8 +2447,6 @@ static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_ALERTING; /* facility */ @@ -2461,7 +2461,7 @@ static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg) @@ -2470,8 +2470,6 @@ static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_PROGRESS; /* progress */ @@ -2480,7 +2478,7 @@ static int gsm48_cc_tx_progress(struct gsm_trans *trans, void *arg) if (progress->fields & MNCC_F_USERUSER) encode_useruser(msg, 0, &progress->useruser); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg) @@ -2489,8 +2487,6 @@ static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_CONNECT; gsm48_stop_cc_timer(trans); @@ -2511,7 +2507,7 @@ static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_CONNECT_IND); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg) @@ -2578,13 +2574,11 @@ static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_CONNECT_ACK; new_cc_state(trans, GSM_CSTATE_ACTIVE); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg) @@ -2646,8 +2640,6 @@ static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_DISCONNECT; gsm48_stop_cc_timer(trans); @@ -2674,7 +2666,7 @@ static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg) @@ -2739,8 +2731,6 @@ static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_RELEASE; trans->callref = 0; @@ -2764,7 +2754,7 @@ static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg) if (trans->cc.state != GSM_CSTATE_RELEASE_REQ) new_cc_state(trans, GSM_CSTATE_RELEASE_REQ); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg) @@ -2833,8 +2823,6 @@ static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_RELEASE_COMPL; trans->callref = 0; @@ -2853,7 +2841,7 @@ static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg) trans_free(trans); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg) @@ -2888,14 +2876,12 @@ static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_FACILITY; /* facility */ encode_facility(msg, 1, &fac->facility); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_hold(struct gsm_trans *trans, struct msgb *msg) @@ -2912,11 +2898,9 @@ static int gsm48_cc_tx_hold_ack(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_HOLD_ACK; - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_tx_hold_rej(struct gsm_trans *trans, void *arg) @@ -2925,8 +2909,6 @@ static int gsm48_cc_tx_hold_rej(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_HOLD_REJ; /* cause */ @@ -2935,7 +2917,7 @@ static int gsm48_cc_tx_hold_rej(struct gsm_trans *trans, void *arg) else encode_cause(msg, 1, &default_cause); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_retrieve(struct gsm_trans *trans, struct msgb *msg) @@ -2953,11 +2935,9 @@ static int gsm48_cc_tx_retrieve_ack(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_RETR_ACK; - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_tx_retrieve_rej(struct gsm_trans *trans, void *arg) @@ -2966,8 +2946,6 @@ static int gsm48_cc_tx_retrieve_rej(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_RETR_REJ; /* cause */ @@ -2976,7 +2954,7 @@ static int gsm48_cc_tx_retrieve_rej(struct gsm_trans *trans, void *arg) else encode_cause(msg, 1, &default_cause); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_start_dtmf(struct gsm_trans *trans, struct msgb *msg) @@ -3005,15 +2983,13 @@ static int gsm48_cc_tx_start_dtmf_ack(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_START_DTMF_ACK; /* keypad */ if (dtmf->fields & MNCC_F_KEYPAD) encode_keypad(msg, dtmf->keypad); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg) @@ -3022,8 +2998,6 @@ static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_START_DTMF_REJ; /* cause */ @@ -3032,7 +3006,7 @@ static int gsm48_cc_tx_start_dtmf_rej(struct gsm_trans *trans, void *arg) else encode_cause(msg, 1, &default_cause); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_tx_stop_dtmf_ack(struct gsm_trans *trans, void *arg) @@ -3040,11 +3014,9 @@ static int gsm48_cc_tx_stop_dtmf_ack(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_STOP_DTMF_ACK; - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_stop_dtmf(struct gsm_trans *trans, struct msgb *msg) @@ -3085,8 +3057,6 @@ static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_MODIFY; gsm48_start_cc_timer(trans, 0x323, GSM48_T323); @@ -3096,7 +3066,7 @@ static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_MO_TERM_MODIFY); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg) @@ -3129,8 +3099,6 @@ static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_MODIFY_COMPL; /* bearer capability */ @@ -3138,7 +3106,7 @@ static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_ACTIVE); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg) @@ -3177,8 +3145,6 @@ static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_MODIFY_REJECT; /* bearer capability */ @@ -3188,7 +3154,7 @@ static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg) new_cc_state(trans, GSM_CSTATE_ACTIVE); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg) @@ -3197,14 +3163,12 @@ static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_NOTIFY; /* notify */ encode_notify(msg, notify->notify); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg) @@ -3229,8 +3193,6 @@ static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg) struct msgb *msg = gsm48_msgb_alloc(); struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); - gh->proto_discr = GSM48_PDISC_CC | trans->transaction_id; - msg->lchan = trans->lchan; gh->msg_type = GSM48_MT_CC_USER_INFO; /* user-user */ @@ -3240,7 +3202,7 @@ static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg) if (user->more) encode_more(msg); - return gsm48_sendmsg(msg); + return gsm48_sendmsg(msg, trans); } static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg) -- cgit v1.2.3 From 6f5aee07e50d5dd80529b2780556eb570a340cd2 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 23 Jul 2009 21:21:14 +0200 Subject: trans->transaction_id now reflects the actual (unshifted) value --- openbsc/src/gsm_04_08.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index ab9a4085b..28d573a1d 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -990,7 +990,7 @@ int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans) /* if we get passed a transaction reference, do some common * work that the caller no longer has to do */ if (trans) { - gh->proto_discr = trans->protocol | trans->transaction_id; + gh->proto_discr = trans->protocol | (trans->transaction_id << 4); msg->lchan = trans->lchan; } @@ -1859,7 +1859,7 @@ static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans, if (trans) if (trans->lchan) - DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) " + DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) " "Sending '%s' to MNCC.\n", trans->lchan->ts->trx->bts->nr, trans->lchan->ts->trx->nr, @@ -2281,7 +2281,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) /* Transaction of our lchan? */ if (transt->lchan == trans->lchan && transt->transaction_id != 0xff) - trans_id_mask |= (1 << (transt->transaction_id >> 4)); + trans_id_mask |= (1 << transt->transaction_id); } /* Assign free transaction ID */ if ((trans_id_mask & 0x007f) == 0x7f) { @@ -2295,7 +2295,7 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg) } for (i = 0; i < 7; i++) { if ((trans_id_mask & (1 << i)) == 0) { - trans->transaction_id = i << 4; /* flag = 0 */ + trans->transaction_id = i; /* flag = 0 */ break; } } @@ -2712,7 +2712,7 @@ static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg) rc = mncc_recvmsg(trans->subscr->net, trans, MNCC_REL_CNF, &rel); } else { rc = gsm48_tx_simple(msg->lchan, - GSM48_PDISC_CC | trans->transaction_id, + GSM48_PDISC_CC | (trans->transaction_id << 4), GSM48_MT_CC_RELEASE_COMPL); rc = mncc_recvmsg(trans->subscr->net, trans, MNCC_REL_IND, &rel); } @@ -3546,7 +3546,7 @@ static int gsm0408_rcv_cc(struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); u_int8_t msg_type = gh->msg_type & 0xbf; - u_int8_t transaction_id = (gh->proto_discr & 0xf0) ^ 0x80; /* flip */ + u_int8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4; /* flip */ struct gsm_lchan *lchan = msg->lchan; struct gsm_trans *trans = NULL; int i, rc = 0; @@ -3559,7 +3559,7 @@ static int gsm0408_rcv_cc(struct msgb *msg) /* Find transaction */ trans = trans_find_by_id(lchan, transaction_id); - DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) " + DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) " "Received '%s' from MS in state %d (%s)\n", lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, transaction_id, (lchan->subscr)?(lchan->subscr->extension):"-", @@ -3568,7 +3568,7 @@ static int gsm0408_rcv_cc(struct msgb *msg) /* Create transaction */ if (!trans) { - DEBUGP(DCC, "Unknown transaction ID %02x, " + DEBUGP(DCC, "Unknown transaction ID %x, " "creating new trans.\n", transaction_id); /* Create transaction */ trans = trans_alloc(lchan->subscr, GSM48_PDISC_CC, @@ -3576,7 +3576,7 @@ static int gsm0408_rcv_cc(struct msgb *msg) if (!trans) { DEBUGP(DCC, "No memory for trans.\n"); rc = gsm48_tx_simple(msg->lchan, - GSM48_PDISC_CC | transaction_id, + GSM48_PDISC_CC | (transaction_id << 4), GSM48_MT_CC_RELEASE_COMPL); return -ENOMEM; } -- cgit v1.2.3 From c072ad6e299a5930937d336bb13c407c02aefd7b Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 23 Jul 2009 21:25:08 +0200 Subject: add missing files to git --- openbsc/src/transaction.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 openbsc/src/transaction.c (limited to 'openbsc/src') 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 -- cgit v1.2.3 From b49248bf48b0856e3b156810681ea3fca44c728a Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 23 Jul 2009 21:36:44 +0200 Subject: move allocating new transaction_ids to transaction.c --- openbsc/src/gsm_04_08.c | 21 ++++----------------- openbsc/src/transaction.c | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 19 deletions(-) (limited to 'openbsc/src') 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 -- cgit v1.2.3 From 7bfc26749662e3a3227037cce4a24748343b50be Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 Jul 2009 00:41:45 +0200 Subject: 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(-) (limited to 'openbsc/src') 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"); +} -- cgit v1.2.3 From 709f2fd8c0bba0dafd9e2c8c3d2e469852a6ddd4 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 Jul 2009 13:32:00 +0200 Subject: enable select.c handler to support removal of two consecutive fd's --- openbsc/src/select.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'openbsc/src') diff --git a/openbsc/src/select.c b/openbsc/src/select.c index 11b7e6b49..7f45426d0 100644 --- a/openbsc/src/select.c +++ b/openbsc/src/select.c @@ -25,6 +25,7 @@ static int maxfd = 0; static LLIST_HEAD(bsc_fds); +static int unregistered_count; int bsc_register_fd(struct bsc_fd *fd) { @@ -50,6 +51,7 @@ int bsc_register_fd(struct bsc_fd *fd) void bsc_unregister_fd(struct bsc_fd *fd) { + unregistered_count++; llist_del(&fd->list); } @@ -86,6 +88,8 @@ int bsc_select_main(int polling) bsc_update_timers(); /* call registered callback functions */ +restart: + unregistered_count = 0; llist_for_each_entry_safe(ufd, tmp, &bsc_fds, list) { int flags = 0; @@ -102,6 +106,11 @@ int bsc_select_main(int polling) work = 1; ufd->cb(ufd, flags); } + /* ugly, ugly hack. If more than one filedescriptors were + * unregistered, they might have been consecutive and + * llist_for_each_entry_safe() is no longer safe */ + if (unregistered_count > 1) + goto restart; } return work; } -- cgit v1.2.3 From 8830e07efb693dc441a08f66df85862488e02473 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 Jul 2009 17:58:09 +0200 Subject: implement human-readable RSL cause printing --- openbsc/src/abis_rsl.c | 82 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 18 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 394d98e8e..a494ad302 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -314,18 +314,55 @@ static void pad_macblock(u_int8_t *out, const u_int8_t *in, int len) memset(out+len, 0x2b, MACBLOCK_SIZE-len); } -static void print_rsl_cause(u_int8_t *cause_tlv) +static const char *rsl_err_vals[0xff] = { + [RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure", + [RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure", + [RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure", + [RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure", + [RSL_ERR_OM_INTERVENTION] = "O&M Intervention", + [RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified", + [RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure", + [RSL_ERR_RR_UNAVAIL] = "Radio Resource not available", + [RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure", + [RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload", + [RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload", + [RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload", + [RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified", + [RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available", + [RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available", + [RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented", + [RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented", + [RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated", + [RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified", + [RSL_ERR_MSG_DISCR] = "Message Discriminator Error", + [RSL_ERR_MSG_TYPE] = "Message Type Error", + [RSL_ERR_MSG_SEQ] = "Message Sequence Error", + [RSL_ERR_IE_ERROR] = "General IE error", + [RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error", + [RSL_ERR_OPT_IE_ERROR] = "Optional IE error", + [RSL_ERR_IE_NONEXIST] = "IE non-existent", + [RSL_ERR_IE_LENGTH] = "IE length error", + [RSL_ERR_IE_CONTENT] = "IE content error", + [RSL_ERR_PROTO] = "Protocol error, unspecified", + [RSL_ERR_INTERWORKING] = "Interworking error, unspecified", +}; + +static const char *rsl_err_name(u_int8_t err) { - u_int8_t cause_len; - int i; + if (rsl_err_vals[err]) + return rsl_err_vals[err]; + else + return "unknown"; +} - if (cause_tlv[0] != RSL_IE_CAUSE) - return; +static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len) +{ + int i; - cause_len = cause_tlv[1]; - DEBUGPC(DRSL, "CAUSE: "); - for (i = 0; i < cause_len; i++) - DEBUGPC(DRSL, "%02x ", cause_tlv[2+i]); + DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ", + cause_v[0], rsl_err_name(cause_v[0])); + for (i = 1; i < cause_len-1; i++) + DEBUGPC(DRSL, "%02x ", cause_v[i]); } /* Send a BCCH_INFO message as per Chapter 8.5.1 */ @@ -817,8 +854,9 @@ static int rsl_rx_chan_act_nack(struct msgb *msg) rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh)); if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) - DEBUGPC(DRSL, "CAUSE=0x%02x ", *TLVP_VAL(&tp, RSL_IE_CAUSE)); - + print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE), + TLVP_LEN(&tp, RSL_IE_CAUSE)); + return 0; } @@ -829,10 +867,13 @@ static int rsl_rx_conn_fail(struct msgb *msg) struct tlv_parsed tp; DEBUGPC(DRSL, "CONNECTION FAIL: "); - print_rsl_cause(dh->data); rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh)); + if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) + print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE), + TLVP_LEN(&tp, RSL_IE_CAUSE)); + if (msg->trx->bts->type == GSM_BTS_TYPE_BS11) { /* FIXME: we have no idea what cause 0x18 is !!! */ if (TLVP_PRESENT(&tp, RSL_IE_CAUSE) && @@ -954,9 +995,16 @@ static int abis_rsl_rx_dchan(struct msgb *msg) static int rsl_rx_error_rep(struct msgb *msg) { struct abis_rsl_common_hdr *rslh = msgb_l2(msg); + struct tlv_parsed tp; DEBUGP(DRSL, "ERROR REPORT "); - print_rsl_cause(rslh->data); + + rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh)); + + if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) + print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE), + TLVP_LEN(&tp, RSL_IE_CAUSE)); + DEBUGPC(DRSL, "\n"); return 0; @@ -1292,12 +1340,10 @@ static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg) struct tlv_parsed tv; rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh)); - if (!TLVP_PRESENT(&tv, RSL_IE_CAUSE)) { - DEBUGPC(DRSL, "mandatory IE missing! "); - return -EINVAL; - } - DEBUGPC(DRSL, "cause=0x%02x ", *TLVP_VAL(&tv, RSL_IE_CAUSE)); + if (TLVP_PRESENT(&tv, RSL_IE_CAUSE)) + print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE), + TLVP_LEN(&tv, RSL_IE_CAUSE)); return 0; } -- cgit v1.2.3 From 888b11462a2331eab7e9e7b49d92254314f7ee7e Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 Jul 2009 18:02:05 +0200 Subject: send a [new] signal in case of IPAC_DISCONNECT_INDication --- openbsc/src/abis_rsl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'openbsc/src') diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index a494ad302..f26e4c912 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -1345,6 +1345,8 @@ static int abis_rsl_rx_ipacc_disc_ind(struct msgb *msg) print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE), TLVP_LEN(&tv, RSL_IE_CAUSE)); + dispatch_signal(SS_ABISIP, S_ABISIP_DISC_IND, msg->lchan); + return 0; } -- cgit v1.2.3 From f4e79f24fcdabdfd81be5d3842b4bf4c05465db4 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 Jul 2009 18:11:56 +0200 Subject: improve ip-access BIND/CONNECT RTP support * explicitly set the "ip speech mode" IE during BIND and CONNECT messages, depending on the speech codec used by the voice call * more verbose debug messages regarding IPAC_BIND and IPAC_CONNECT * do not always blindly specify RTP payload type, but use the value returned by BIND_ACK, _if_ it is present. --- openbsc/src/abis_rsl.c | 58 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 7 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index f26e4c912..56c3f711b 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -1242,17 +1242,45 @@ static int abis_rsl_rx_rll(struct msgb *msg) return rc; } +static u_int8_t ipa_smod_s_for_tch_mode(u_int8_t tch_mode) +{ +#if 0 + switch (tch_mode) { + case GSM48_CMODE_SPEECH_V1: + return 0x00; + case GSM48_CMODE_SPEECH_EFR: + return 0x01; + case GSM48_CMODE_SPEECH_AMR: + return 0x02; + /* FIXME: Type1 half-rate and type3 half-rate */ + } + return 0; +#else + /* hard-code EFR for now, since tch_mode is not correct at this + * point in time */ + return 0x01; +#endif +} + /* ip.access specific RSL extensions */ int rsl_ipacc_bind(struct gsm_lchan *lchan) { struct msgb *msg = rsl_msgb_alloc(); struct abis_rsl_dchan_hdr *dh; + u_int8_t speech_mode_s; dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh)); init_dchan_hdr(dh, RSL_MT_IPAC_BIND); dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS; dh->chan_nr = lchan2chan_nr(lchan); + speech_mode_s = ipa_smod_s_for_tch_mode(lchan->tch_mode); + /* 0x1- == receive-only, 0x-1 == EFR codec */ + msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, 0x10 | speech_mode_s); + + DEBUGPC(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND\n", + gsm_ts_name(lchan->ts), dh->chan_nr); + msg->trx = lchan->ts->trx; return abis_rsl_sendmsg(msg); @@ -1264,12 +1292,20 @@ int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port, struct msgb *msg = rsl_msgb_alloc(); struct abis_rsl_dchan_hdr *dh; u_int8_t *att_f8, *att_ip, *att_port; + u_int8_t speech_mode_s; + struct in_addr ia; dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh)); init_dchan_hdr(dh, RSL_MT_IPAC_CONNECT); dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS; dh->chan_nr = lchan2chan_nr(lchan); + ia.s_addr = htonl(ip); + DEBUGP(DRSL, "IPAC_CONNECT channel=%s chan_nr=0x%02x " + "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d\n", + gsm_ts_name(lchan->ts), dh->chan_nr, + inet_ntoa(ia), port, rtp_payload2, conn_id); + att_f8 = msgb_put(msg, sizeof(conn_id)+1); att_f8[0] = RSL_IE_IPAC_CONN_ID; att_f8[1] = conn_id >> 8; @@ -1288,8 +1324,12 @@ int rsl_ipacc_connect(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port, att_port[1] = port >> 8; att_port[2] = port & 0xff; - msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, 1); /* F4 01 */ - msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2); /* FC 7F */ + speech_mode_s = ipa_smod_s_for_tch_mode(lchan->tch_mode); + /* 0x0- == both directions, 0x-1 == EFR codec */ + msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, 0x00 | speech_mode_s); + if (rtp_payload2) + msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, rtp_payload2); + msg->trx = lchan->ts->trx; return abis_rsl_sendmsg(msg); @@ -1310,7 +1350,6 @@ static int abis_rsl_rx_ipacc_bindack(struct msgb *msg) rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh)); if (!TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_PORT) || !TLVP_PRESENT(&tv, RSL_IE_IPAC_LOCAL_IP) || - !TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2) || !TLVP_PRESENT(&tv, RSL_IE_IPAC_CONN_ID)) { DEBUGPC(DRSL, "mandatory IE missing"); return -EINVAL; @@ -1319,15 +1358,20 @@ static int abis_rsl_rx_ipacc_bindack(struct msgb *msg) port = *((u_int16_t *) TLVP_VAL(&tv, RSL_IE_IPAC_LOCAL_PORT)); attr_f8 = *((u_int16_t *) TLVP_VAL(&tv, 0xf8)); - DEBUGPC(DRSL, "IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d", - inet_ntoa(ip), ntohs(port), *TLVP_VAL(&tv, 0xfc), - ntohs(attr_f8)); + DEBUGPC(DRSL, "IP=%s PORT=%d CONN_ID=%d ", + inet_ntoa(ip), ntohs(port), ntohs(attr_f8)); + + if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) { + ts->abis_ip.rtp_payload2 = + *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2); + DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ", + ts->abis_ip.rtp_payload2); + } /* update our local information about this TS */ ts->abis_ip.bound_ip = ntohl(ip.s_addr); ts->abis_ip.bound_port = ntohs(port); ts->abis_ip.conn_id = ntohs(attr_f8); - ts->abis_ip.rtp_payload2 = *TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2); dispatch_signal(SS_ABISIP, S_ABISIP_BIND_ACK, msg->lchan); -- cgit v1.2.3