From 6d66a3ce55df5af86a7766178322a00d6c60026b Mon Sep 17 00:00:00 2001 From: Tobias Engel Date: Thu, 22 Mar 2012 15:09:54 +0100 Subject: Call Waiting SS This patch adds the ability to activate, deactivate and interrogate the Call Waiting SS (GSM 04.83) from a mobile station using either the menu or the MMI codes *43#, #43# and *#43# (see GSM 02.30). struct gsm_subscriber now has a member active_cc_transactions which will be increased/decreased in new_cc_state. A call to a subscriber will now only proceed if active_cc_transactions is either 0, or CW has been provisioned and activated for that subscriber, otherwise the caller will receive a "busy" signal. --- openbsc/include/openbsc/gsm_subscriber.h | 1 + openbsc/src/libmsc/gsm_04_08.c | 39 +++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 6cf85731b..995a1cf8b 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -48,6 +48,7 @@ struct gsm_subscriber { /* for internal management */ int use_count; + int active_cc_transactions; struct llist_head entry; /* pending requests */ diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 0e18d0c1d..bb043f9ea 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -1173,9 +1173,19 @@ static void new_cc_state(struct gsm_trans *trans, int state) if (state > 31 || state < 0) return; - DEBUGP(DCC, "new state %s -> %s\n", - gsm48_cc_state_name(trans->cc.state), - gsm48_cc_state_name(state)); + if (trans->subscr) { + if (state != GSM_CSTATE_NULL && + trans->cc.state == GSM_CSTATE_NULL) + trans->subscr->active_cc_transactions++; + else if(state == GSM_CSTATE_NULL && + trans->cc.state != GSM_CSTATE_NULL) + trans->subscr->active_cc_transactions--; + } + + DEBUGP(DCC, "new state %s -> %s, %d active transactions\n", + gsm48_cc_state_name(trans->cc.state), + gsm48_cc_state_name(state), + trans->subscr->active_cc_transactions); trans->cc.state = state; } @@ -2945,6 +2955,29 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg) GSM48_CAUSE_LOC_PRN_S_LU, GSM48_CC_CAUSE_DEST_OOO); } + /* If subscriber is "busy" */ + if (subscr->active_cc_transactions) { + int rc; + uint8_t ss_status = 0; + rc = db_ss_interrogate_status(subscr, + GSM0902_SS_CODE_CW, + GSM0902_TS_CODE_TELEPHONY, + &ss_status); + DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) " + "Received '%s' from MNCC with " + "busy subscriber %s, cw ss_status: %X\n", + data->called.number, get_mncc_name(msg_type), + data->called.number, ss_status); + if(rc < 0 || (ss_status != (GSM0902_SS_STATUS_P_BIT | + GSM0902_SS_STATUS_A_BIT))) { + subscr_put(subscr); + /* User busy */ + return mncc_release_ind(net, NULL, + data->callref, + GSM48_CAUSE_LOC_USER, + GSM48_CC_CAUSE_USER_BUSY); + } + } /* Create transaction */ trans = trans_alloc(subscr, GSM48_PDISC_CC, 0xff, data->callref); if (!trans) { -- cgit v1.2.3