aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Engel <tobias@ccc.de>2012-03-22 15:09:54 +0100
committerTobias Engel <tobias@ccc.de>2012-03-22 15:16:17 +0100
commit6d66a3ce55df5af86a7766178322a00d6c60026b (patch)
tree2d67ea52071d742508b69480ee3d466d4e438811
parent7d8ff3113c466e40466a311163b0caf98f8c8f72 (diff)
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.
-rw-r--r--openbsc/include/openbsc/gsm_subscriber.h1
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c39
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) {