diff options
-rw-r--r-- | include/openbsc/gsm_04_08.h | 22 | ||||
-rw-r--r-- | src/chan_alloc.c | 7 | ||||
-rw-r--r-- | src/gsm_04_08.c | 20 |
3 files changed, 48 insertions, 1 deletions
diff --git a/include/openbsc/gsm_04_08.h b/include/openbsc/gsm_04_08.h index e781677c3..cc93ff9b4 100644 --- a/include/openbsc/gsm_04_08.h +++ b/include/openbsc/gsm_04_08.h @@ -375,6 +375,27 @@ enum gsm48_cause_loc { GSM48_CAUSE_LOC_NET_BEYOND = 0x0a, }; +/* Section 10.5.2.31 RR Cause / Table 10.5.70 */ +enum gsm48_rr_cause { + GSM48_RR_CAUSE_NORMAL = 0x00, + GSM48_RR_CAUSE_ABNORMAL_UNSPEC = 0x01, + GSM48_RR_CAUSE_ABNORMAL_UNACCT = 0x02, + GSM48_RR_CAUSE_ABNORMAL_TIMER = 0x03, + GSM48_RR_CAUSE_ABNORMAL_NOACT = 0x04, + GSM48_RR_CAUSE_PREMPTIVE_REL = 0x05, + GSM48_RR_CAUSE_HNDOVER_IMP = 0x06, + GSM48_RR_CAUSE_CHAN_MODE_UNACCT = 0x07, + GSM48_RR_CAUSE_FREQ_NOT_IMPL = 0x08, + GSM48_RR_CAUSE_CALL_ClEARED = 0x41, + GSM48_RR_CAUSE_SEMANT_INCORR = 0x5f, + GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60, + GSM48_RR_CAUSE_MSG_TYPE_N = 0x61, + GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62, + GSM48_RR_CAUSE_COND_IE_ERROR = 0x64, + GSM48_RR_CAUSE_NO_CELL_ALLOC_A = 0x65, + GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f, +}; + /* Annex G, GSM specific cause values for mobility management */ enum gsm48_reject_value { GSM48_REJECT_IMSI_UNKNOWN_IN_HLR = 2, @@ -429,5 +450,6 @@ struct msgb *gsm48_msgb_alloc(void); int gsm48_sendmsg(struct msgb *msg); int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi); +int gsm48_send_rr_release(struct gsm_lchan *lchan); #endif diff --git a/src/chan_alloc.c b/src/chan_alloc.c index 4658f12ec..7edde6e1f 100644 --- a/src/chan_alloc.c +++ b/src/chan_alloc.c @@ -1,7 +1,7 @@ /* GSM Channel allocation routines * * (C) 2008 by Harald Welte <laforge@gnumonks.org> - * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org> * * All Rights Reserved * @@ -212,6 +212,11 @@ int lchan_auto_release(struct gsm_lchan *lchan) return 0; } + /* Assume we have GSM04.08 running and send a release */ + if (lchan->subscr) { + gsm48_send_rr_release(lchan); + } + /* spoofed? message */ if (lchan->use_count < 0) { DEBUGP(DRLL, "Channel count is negative: %d\n", lchan->use_count); diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c index 2739b0b0f..541ff4202 100644 --- a/src/gsm_04_08.c +++ b/src/gsm_04_08.c @@ -710,6 +710,26 @@ static int gsm0408_rcv_rr(struct msgb *msg) return rc; } +/* 7.1.7 and 9.1.7 Channel release*/ +int gsm48_send_rr_release(struct gsm_lchan *lchan) +{ + struct msgb *msg = gsm48_msgb_alloc(); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + u_int8_t *cause; + + msg->lchan = lchan; + gh->proto_discr = GSM48_PDISC_RR; + gh->msg_type = GSM48_MT_RR_CHAN_REL; + + cause = msgb_put(msg, 1); + cause[0] = GSM48_RR_CAUSE_NORMAL; + + DEBUGP(DRR, "Sending Channel Release: Chan: Number: %d Type: %d\n", + lchan->nr, lchan->type); + + return gsm48_sendmsg(msg); +} + /* Call Control */ static int gsm48_cc_tx_status(struct gsm_lchan *lchan) |