diff options
Diffstat (limited to 'src/osmo-bsc/bsc_api.c')
-rw-r--r-- | src/osmo-bsc/bsc_api.c | 133 |
1 files changed, 7 insertions, 126 deletions
diff --git a/src/osmo-bsc/bsc_api.c b/src/osmo-bsc/bsc_api.c index 4cf11a466..35e697769 100644 --- a/src/osmo-bsc/bsc_api.c +++ b/src/osmo-bsc/bsc_api.c @@ -33,6 +33,7 @@ #include <osmocom/bsc/bsc_subscriber.h> #include <osmocom/bsc/penalty_timers.h> #include <osmocom/bsc/osmo_bsc_sigtran.h> +#include <osmocom/bsc/bsc_subscr_conn_fsm.h> #include <osmocom/gsm/protocol/gsm_08_08.h> #include <osmocom/gsm/gsm48.h> @@ -41,10 +42,6 @@ #define GSM0808_T10_VALUE 6, 0 -#define HO_DTAP_CACHE_MSGB_CB_LINK_ID 0 -#define HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH 1 - -static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind); static void handle_release(struct gsm_subscriber_connection *conn, struct gsm_lchan *lchan); static void handle_chan_ack(struct gsm_subscriber_connection *conn, struct gsm_lchan *lchan); static void handle_chan_nack(struct gsm_subscriber_connection *conn, struct gsm_lchan *lchan); @@ -116,97 +113,6 @@ static int handle_new_assignment(struct gsm_subscriber_connection *conn, int cha return 0; } -static void ho_dtap_cache_add(struct gsm_subscriber_connection *conn, struct msgb *msg, - int link_id, bool allow_sacch) -{ - if (conn->ho_dtap_cache_len >= 23) { - LOGP(DHO, LOGL_ERROR, "%s: Cannot cache more DTAP messages," - " already reached sane maximum of %u cached messages\n", - bsc_subscr_name(conn->bsub), conn->ho_dtap_cache_len); - msgb_free(msg); - return; - } - conn->ho_dtap_cache_len ++; - LOGP(DHO, LOGL_DEBUG, "%s: Caching DTAP message during ho/ass (%u)\n", - bsc_subscr_name(conn->bsub), conn->ho_dtap_cache_len); - msg->cb[HO_DTAP_CACHE_MSGB_CB_LINK_ID] = (unsigned long)link_id; - msg->cb[HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH] = allow_sacch ? 1 : 0; - msgb_enqueue(&conn->ho_dtap_cache, msg); -} - -void ho_dtap_cache_flush(struct gsm_subscriber_connection *conn, int send) -{ - struct msgb *msg; - unsigned int flushed_count = 0; - - if (conn->secondary_lchan || conn->ho) { - LOGP(DHO, LOGL_ERROR, "%s: Cannot send cached DTAP messages, handover/assignment is still ongoing\n", - bsc_subscr_name(conn->bsub)); - send = 0; - } - - while ((msg = msgb_dequeue(&conn->ho_dtap_cache))) { - conn->ho_dtap_cache_len --; - flushed_count ++; - if (send) { - int link_id = (int)msg->cb[HO_DTAP_CACHE_MSGB_CB_LINK_ID]; - bool allow_sacch = !!msg->cb[HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH]; - LOGP(DHO, LOGL_DEBUG, "%s: Sending cached DTAP message after handover/assignment (%u/%u)\n", - bsc_subscr_name(conn->bsub), flushed_count, conn->ho_dtap_cache_len); - gsm0808_submit_dtap(conn, msg, link_id, allow_sacch); - } else - msgb_free(msg); - } -} - -/*! \brief process incoming 08.08 DTAP from MSC (send via BTS to MS) */ -int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn, - struct msgb *msg, int link_id, int allow_sacch) -{ - uint8_t sapi; - - - if (!conn->lchan) { - LOGP(DMSC, LOGL_ERROR, - "%s Called submit dtap without an lchan.\n", - bsc_subscr_name(conn->bsub)); - msgb_free(msg); - return -1; - } - - /* buffer message during assignment / handover */ - if (conn->secondary_lchan || conn->ho) { - ho_dtap_cache_add(conn, msg, link_id, !! allow_sacch); - return 0; - } - - sapi = link_id & 0x7; - msg->lchan = conn->lchan; - msg->dst = msg->lchan->ts->trx->rsl_link; - - /* If we are on a TCH and need to submit a SMS (on SAPI=3) we need to use the SACH */ - if (allow_sacch && sapi != 0) { - if (conn->lchan->type == GSM_LCHAN_TCH_F || conn->lchan->type == GSM_LCHAN_TCH_H) - link_id |= 0x40; - } - - msg->l3h = msg->data; - /* is requested SAPI already up? */ - if (conn->lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) { - /* Establish L2 for additional SAPI */ - OBSC_LINKID_CB(msg) = link_id; - if (rll_establish(msg->lchan, sapi, rll_ind_cb, msg) != 0) { - msgb_free(msg); - bsc_sapi_n_reject(conn, link_id); - return -1; - } - return 0; - } else { - /* Directly forward via RLL/RSL to BTS */ - return rsl_data_request(msg, link_id); - } -} - /* * \brief Check if the given channel is compatible with the mode/fullrate */ @@ -316,7 +222,7 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn, /* FIXME: release old channel */ /* send pending messages, if any */ - ho_dtap_cache_flush(conn, 1); + gscon_dtap_queue_flush(conn, 1); return; } @@ -332,7 +238,7 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn, conn->secondary_lchan = NULL; /* send pending messages, if any */ - ho_dtap_cache_flush(conn, 1); + gscon_dtap_queue_flush(conn, 1); if (is_ipaccess_bts(conn_get_bts(conn)) && conn->lchan->tch_mode != GSM48_CMODE_SIGN) rsl_ipacc_crcx(conn->lchan); @@ -359,7 +265,7 @@ static void handle_ass_fail(struct gsm_subscriber_connection *conn, /* FIXME: release allocated new channel */ /* send pending messages, if any */ - ho_dtap_cache_flush(conn, 1); + gscon_dtap_queue_flush(conn, 1); return; } @@ -377,7 +283,7 @@ static void handle_ass_fail(struct gsm_subscriber_connection *conn, } /* send pending messages, if any */ - ho_dtap_cache_flush(conn, 1); + gscon_dtap_queue_flush(conn, 1); gh = msgb_l3(msg); if (msgb_l3len(msg) - sizeof(*gh) != 1) { @@ -443,7 +349,7 @@ static void handle_rr_ho_compl(struct msgb *msg) /* FIXME: release old channel */ /* send pending messages, if any */ - ho_dtap_cache_flush(msg->lchan->conn, 1); + gscon_dtap_queue_flush(msg->lchan->conn, 1); } /* Chapter 9.1.17 Handover Failure */ @@ -465,7 +371,7 @@ static void handle_rr_ho_fail(struct msgb *msg) /* FIXME: release allocated new channel */ /* send pending messages, if any */ - ho_dtap_cache_flush(msg->lchan->conn, 1); + gscon_dtap_queue_flush(msg->lchan->conn, 1); } @@ -643,31 +549,6 @@ int gsm0808_clear(struct gsm_subscriber_connection *conn) return 0; } -static void rll_ind_cb(struct gsm_lchan *lchan, uint8_t link_id, void *_data, enum bsc_rllr_ind rllr_ind) -{ - struct msgb *msg = _data; - - /* - * There seems to be a small window that the RLL timer can - * fire after a lchan_release call and before the S_CHALLOC_FREED - * is called. Check if a conn is set before proceeding. - */ - if (!lchan->conn) - return; - - switch (rllr_ind) { - case BSC_RLLR_IND_EST_CONF: - rsl_data_request(msg, OBSC_LINKID_CB(msg)); - break; - case BSC_RLLR_IND_REL_IND: - case BSC_RLLR_IND_ERR_IND: - case BSC_RLLR_IND_TIMEOUT: - bsc_sapi_n_reject(lchan->conn, OBSC_LINKID_CB(msg)); - msgb_free(msg); - break; - } -} - static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data) { |