msc: Create a dummy operation to keep the channel open for five seconds
* We should create the transaction for SMS, CC on the CM Service Request but for now we will use a band aid and create a dummy operarion to wait five seconds for the transaction to be opened.
This commit is contained in:
parent
d1d45b3b89
commit
02d39b2c4d
|
@ -28,6 +28,7 @@ void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t caus
|
|||
int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
|
||||
int gsm0408_new_conn(struct gsm_subscriber_connection *conn);
|
||||
enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
|
||||
enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
|
||||
|
||||
|
|
|
@ -179,6 +179,14 @@ struct gsm_security_operation {
|
|||
void *cb_data;
|
||||
};
|
||||
|
||||
/*
|
||||
* A dummy to keep a connection up for at least
|
||||
* a couple of seconds to work around MSC issues.
|
||||
*/
|
||||
struct gsm_anchor_operation {
|
||||
struct timer_list timeout;
|
||||
};
|
||||
|
||||
/* Maximum number of neighbor cells whose average we track */
|
||||
#define MAX_NEIGH_MEAS 10
|
||||
/* Maximum size of the averaging window for neighbor cells */
|
||||
|
@ -224,6 +232,7 @@ struct gsm_subscriber_connection {
|
|||
*/
|
||||
struct gsm_loc_updating_operation *loc_operation;
|
||||
struct gsm_security_operation *sec_operation;
|
||||
struct gsm_anchor_operation *anch_operation;
|
||||
|
||||
/* Are we part of a special "silent" call */
|
||||
int silent_call;
|
||||
|
|
|
@ -63,6 +63,7 @@ int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, u_int32_t tmsi);
|
|||
static int gsm48_tx_simple(struct gsm_subscriber_connection *conn,
|
||||
u_int8_t pdisc, u_int8_t msg_type);
|
||||
static void schedule_reject(struct gsm_subscriber_connection *conn);
|
||||
static void release_anchor(struct gsm_subscriber_connection *conn);
|
||||
|
||||
struct gsm_lai {
|
||||
u_int16_t mcc;
|
||||
|
@ -218,6 +219,9 @@ static void release_loc_updating_req(struct gsm_subscriber_connection *conn)
|
|||
if (!conn->loc_operation)
|
||||
return;
|
||||
|
||||
/* No need to keep the connection up */
|
||||
release_anchor(conn);
|
||||
|
||||
bsc_del_timer(&conn->loc_operation->updating_timer);
|
||||
talloc_free(conn->loc_operation);
|
||||
conn->loc_operation = 0;
|
||||
|
@ -294,6 +298,7 @@ void gsm0408_clear_request(struct gsm_subscriber_connection* conn, uint32_t caus
|
|||
*/
|
||||
release_loc_updating_req(conn);
|
||||
release_security_operation(conn);
|
||||
release_anchor(conn);
|
||||
|
||||
/* Free all transactions that are associated with the released lchan */
|
||||
/* FIXME: this is not neccessarily the right thing to do, we should
|
||||
|
@ -3076,6 +3081,37 @@ static int gsm0408_rcv_cc(struct gsm_subscriber_connection *conn, struct msgb *m
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Create a dummy to wait five seconds */
|
||||
static void release_anchor(struct gsm_subscriber_connection *conn)
|
||||
{
|
||||
if (!conn->anch_operation)
|
||||
return;
|
||||
|
||||
bsc_del_timer(&conn->anch_operation->timeout);
|
||||
talloc_free(conn->anch_operation);
|
||||
conn->anch_operation = NULL;
|
||||
}
|
||||
|
||||
static void anchor_timeout(void *_data)
|
||||
{
|
||||
struct gsm_subscriber_connection *con = _data;
|
||||
|
||||
release_anchor(con);
|
||||
msc_release_connection(con);
|
||||
}
|
||||
|
||||
int gsm0408_new_conn(struct gsm_subscriber_connection *conn)
|
||||
{
|
||||
conn->anch_operation = talloc_zero(conn, struct gsm_anchor_operation);
|
||||
if (!conn->anch_operation)
|
||||
return -1;
|
||||
|
||||
conn->anch_operation->timeout.data = conn;
|
||||
conn->anch_operation->timeout.cb = anchor_timeout;
|
||||
bsc_schedule_timer(&conn->anch_operation->timeout, 5, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* here we get data from the BSC level... */
|
||||
int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
||||
{
|
||||
|
@ -3088,6 +3124,7 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
|||
|
||||
switch (pdisc) {
|
||||
case GSM48_PDISC_CC:
|
||||
release_anchor(conn);
|
||||
rc = gsm0408_rcv_cc(conn, msg);
|
||||
break;
|
||||
case GSM48_PDISC_MM:
|
||||
|
@ -3097,6 +3134,7 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
|||
rc = gsm0408_rcv_rr(conn, msg);
|
||||
break;
|
||||
case GSM48_PDISC_SMS:
|
||||
release_anchor(conn);
|
||||
rc = gsm0411_rcv_sms(conn, msg);
|
||||
break;
|
||||
case GSM48_PDISC_MM_GPRS:
|
||||
|
@ -3105,6 +3143,7 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
|||
"GSM 04.08 discriminator 0x%02x\n", pdisc);
|
||||
break;
|
||||
case GSM48_PDISC_NC_SS:
|
||||
release_anchor(conn);
|
||||
rc = handle_rcv_ussd(conn, msg);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -44,6 +44,7 @@ static void msc_clear_request(struct gsm_subscriber_connection* conn, uint32_t c
|
|||
static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
|
||||
uint16_t chosen_channel)
|
||||
{
|
||||
gsm0408_new_conn(conn);
|
||||
gsm0408_dispatch(conn, msg);
|
||||
|
||||
/* TODO: do better */
|
||||
|
@ -80,7 +81,7 @@ void msc_release_connection(struct gsm_subscriber_connection *conn)
|
|||
return;
|
||||
|
||||
/* check if there is a pending operation */
|
||||
if (conn->loc_operation || conn->sec_operation)
|
||||
if (conn->loc_operation || conn->sec_operation || conn->anch_operation)
|
||||
return;
|
||||
|
||||
llist_for_each_entry(trans, &conn->bts->network->trans_list, entry) {
|
||||
|
|
Loading…
Reference in New Issue