lchan: Change transaction to work on the GSM Subscriber Connection

Change the MSC transaction code to operate on a GSM Subscriber Connection
instead of the lchan. This will help us to separate the two commands properly.
This commit is contained in:
Holger Hans Peter Freyther 2010-03-23 07:00:22 +01:00
parent 68884aa156
commit e95d4825f5
7 changed files with 56 additions and 63 deletions

View File

@ -20,8 +20,8 @@ struct gsm_trans {
/* To whom we belong, unique identifier of remote MM entity */ /* To whom we belong, unique identifier of remote MM entity */
struct gsm_subscriber *subscr; struct gsm_subscriber *subscr;
/* The LCHAN that we're currently using to transmit messages */ /* The associated connection we are using to transmit messages */
struct gsm_lchan *lchan; struct gsm_subscriber_connection *conn;
/* reference from MNCC or other application */ /* reference from MNCC or other application */
u_int32_t callref; u_int32_t callref;
@ -71,6 +71,6 @@ int trans_assign_trans_id(struct gsm_subscriber *subscr,
/* update all transactions to use a different LCHAN, e.g. /* update all transactions to use a different LCHAN, e.g.
* after handover has succeeded */ * after handover has succeeded */
int trans_lchan_change(struct gsm_lchan *lchan_old, int trans_lchan_change(struct gsm_subscriber_connection *conn_old,
struct gsm_lchan *lchan_new); struct gsm_subscriber_connection *conn_new);
#endif #endif

View File

@ -166,7 +166,7 @@ static int gsm0408_handle_lchan_signal(unsigned int subsys, unsigned int signal,
* only set trans->lchan to NULL and wait for another lchan to be * only set trans->lchan to NULL and wait for another lchan to be
* established to the same MM entity (phone/subscriber) */ * established to the same MM entity (phone/subscriber) */
llist_for_each_entry_safe(trans, temp, &lchan->ts->trx->bts->network->trans_list, entry) { llist_for_each_entry_safe(trans, temp, &lchan->ts->trx->bts->network->trans_list, entry) {
if (trans->lchan == lchan) if (trans->conn && trans->conn->lchan == lchan)
trans_free(trans); trans_free(trans);
} }
@ -1071,12 +1071,12 @@ static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
struct msgb *msg; struct msgb *msg;
if (trans) if (trans)
if (trans->lchan) if (trans->conn)
DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) " DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) "
"Sending '%s' to MNCC.\n", "Sending '%s' to MNCC.\n",
trans->lchan->ts->trx->bts->nr, trans->conn->lchan->ts->trx->bts->nr,
trans->lchan->ts->trx->nr, trans->conn->lchan->ts->trx->nr,
trans->lchan->ts->nr, trans->transaction_id, trans->conn->lchan->ts->nr, trans->transaction_id,
(trans->subscr)?(trans->subscr->extension):"-", (trans->subscr)?(trans->subscr->extension):"-",
get_mncc_name(msg_type)); get_mncc_name(msg_type));
else else
@ -1125,8 +1125,8 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans)
} }
if (trans->cc.state != GSM_CSTATE_NULL) if (trans->cc.state != GSM_CSTATE_NULL)
new_cc_state(trans, GSM_CSTATE_NULL); new_cc_state(trans, GSM_CSTATE_NULL);
if (trans->lchan) if (trans->conn)
trau_mux_unmap(&trans->lchan->ts->e1_link, trans->callref); trau_mux_unmap(&trans->conn->lchan->ts->e1_link, trans->callref);
} }
static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg); static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
@ -1139,7 +1139,6 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
struct gsm_subscriber *subscr = param; struct gsm_subscriber *subscr = param;
struct gsm_trans *transt, *tmp; struct gsm_trans *transt, *tmp;
struct gsm_network *net; struct gsm_network *net;
struct gsm_subscriber_connection *conn;
if (hooknum != GSM_HOOK_RR_PAGING) if (hooknum != GSM_HOOK_RR_PAGING)
return -EINVAL; return -EINVAL;
@ -1152,11 +1151,9 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
return -EINVAL; return -EINVAL;
} }
conn = &lchan->conn;
/* check all tranactions (without lchan) for subscriber */ /* check all tranactions (without lchan) for subscriber */
llist_for_each_entry_safe(transt, tmp, &net->trans_list, entry) { llist_for_each_entry_safe(transt, tmp, &net->trans_list, entry) {
if (transt->subscr != subscr || transt->lchan) if (transt->subscr != subscr || transt->conn)
continue; continue;
switch (event) { switch (event) {
case GSM_PAGING_SUCCEEDED: case GSM_PAGING_SUCCEEDED:
@ -1165,9 +1162,9 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
DEBUGP(DCC, "Paging subscr %s succeeded!\n", DEBUGP(DCC, "Paging subscr %s succeeded!\n",
subscr->extension); subscr->extension);
/* Assign lchan */ /* Assign lchan */
if (!transt->lchan) { if (!transt->conn) {
transt->lchan = lchan; transt->conn = &lchan->conn;
use_subscr_con(conn); use_subscr_con(transt->conn);
} }
/* send SETUP request to called party */ /* send SETUP request to called party */
gsm48_cc_tx_setup(transt, &transt->cc.msg); gsm48_cc_tx_setup(transt, &transt->cc.msg);
@ -1212,7 +1209,7 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
* a tch_recv_mncc request pending */ * a tch_recv_mncc request pending */
net = lchan->ts->trx->bts->network; net = lchan->ts->trx->bts->network;
llist_for_each_entry(trans, &net->trans_list, entry) { llist_for_each_entry(trans, &net->trans_list, entry) {
if (trans->lchan == lchan && trans->tch_recv) { if (trans->conn && trans->conn->lchan == lchan && trans->tch_recv) {
DEBUGP(DCC, "pending tch_recv_mncc request\n"); DEBUGP(DCC, "pending tch_recv_mncc request\n");
tch_recv_mncc(net, trans->callref, 1); tch_recv_mncc(net, trans->callref, 1);
} }
@ -1285,11 +1282,11 @@ static int tch_bridge(struct gsm_network *net, u_int32_t *refs)
if (!trans1 || !trans2) if (!trans1 || !trans2)
return -EIO; return -EIO;
if (!trans1->lchan || !trans2->lchan) if (!trans1->conn || !trans2->conn)
return -EIO; return -EIO;
/* through-connect channel */ /* through-connect channel */
return tch_map(trans1->lchan, trans2->lchan); return tch_map(trans1->conn->lchan, trans2->conn->lchan);
} }
/* enable receive of channels to MNCC upqueue */ /* enable receive of channels to MNCC upqueue */
@ -1304,9 +1301,9 @@ static int tch_recv_mncc(struct gsm_network *net, u_int32_t callref, int enable)
trans = trans_find_by_callref(net, callref); trans = trans_find_by_callref(net, callref);
if (!trans) if (!trans)
return -EIO; return -EIO;
if (!trans->lchan) if (!trans->conn)
return 0; return 0;
lchan = trans->lchan; lchan = trans->conn->lchan;
bts = lchan->ts->trx->bts; bts = lchan->ts->trx->bts;
switch (bts->type) { switch (bts->type) {
@ -2502,7 +2499,7 @@ static int _gsm48_lchan_modify(struct gsm_trans *trans, void *arg)
{ {
struct gsm_mncc *mode = arg; struct gsm_mncc *mode = arg;
return gsm48_lchan_modify(trans->lchan, mode->lchan_mode); return gsm48_lchan_modify(trans->conn->lchan, mode->lchan_mode);
} }
static struct downstate { static struct downstate {
@ -2574,7 +2571,6 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg)
struct gsm_lchan *lchan = NULL; struct gsm_lchan *lchan = NULL;
struct gsm_bts *bts = NULL; struct gsm_bts *bts = NULL;
struct gsm_mncc *data = arg, rel; struct gsm_mncc *data = arg, rel;
struct gsm_subscriber_connection *conn;
/* handle special messages */ /* handle special messages */
switch(msg_type) { switch(msg_type) {
@ -2589,18 +2585,18 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg)
trans = trans_find_by_callref(net, data->callref); trans = trans_find_by_callref(net, data->callref);
if (!trans) if (!trans)
return -EIO; return -EIO;
if (!trans->lchan) if (!trans->conn)
return 0; return 0;
if (trans->lchan->type != GSM_LCHAN_TCH_F) if (trans->conn->lchan->type != GSM_LCHAN_TCH_F)
return 0; return 0;
bts = trans->lchan->ts->trx->bts; bts = trans->conn->lchan->ts->trx->bts;
switch (bts->type) { switch (bts->type) {
case GSM_BTS_TYPE_NANOBTS: case GSM_BTS_TYPE_NANOBTS:
if (!trans->lchan->abis_ip.rtp_socket) if (!trans->conn->lchan->abis_ip.rtp_socket)
return 0; return 0;
return rtp_send_frame(trans->lchan->abis_ip.rtp_socket, arg); return rtp_send_frame(trans->conn->lchan->abis_ip.rtp_socket, arg);
case GSM_BTS_TYPE_BS11: case GSM_BTS_TYPE_BS11:
return trau_send_frame(trans->lchan, arg); return trau_send_frame(trans->conn->lchan, arg);
default: default:
DEBUGP(DCC, "Unknown BTS type %u\n", bts->type); DEBUGP(DCC, "Unknown BTS type %u\n", bts->type);
} }
@ -2706,12 +2702,13 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg)
return 0; return 0;
} }
/* Assign lchan */ /* Assign lchan */
trans->lchan = lchan; trans->conn = &lchan->conn;
conn = &lchan->conn; use_subscr_con(trans->conn);
use_subscr_con(conn);
subscr_put(subscr); subscr_put(subscr);
} }
lchan = trans->lchan;
if (trans->conn)
lchan = trans->conn->lchan;
/* if paging did not respond yet */ /* if paging did not respond yet */
if (!lchan) { if (!lchan) {
@ -2730,12 +2727,11 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg)
return rc; return rc;
} }
conn = &lchan->conn;
DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) " DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) "
"Received '%s' from MNCC in state %d (%s)\n", "Received '%s' from MNCC in state %d (%s)\n",
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
trans->transaction_id, trans->transaction_id,
(conn->subscr)?(conn->subscr->extension):"-", (trans->conn->subscr)?(trans->conn->subscr->extension):"-",
get_mncc_name(msg_type), trans->cc.state, get_mncc_name(msg_type), trans->cc.state,
gsm48_cc_state_name(trans->cc.state)); gsm48_cc_state_name(trans->cc.state));
@ -2851,8 +2847,8 @@ static int gsm0408_rcv_cc(struct msgb *msg)
return -ENOMEM; return -ENOMEM;
} }
/* Assign transaction */ /* Assign transaction */
trans->lchan = lchan; trans->conn = &lchan->conn;
use_subscr_con(conn); use_subscr_con(trans->conn);
} }
/* find function for current state and message */ /* find function for current state and message */

View File

@ -57,7 +57,7 @@ int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans)
* work that the caller no longer has to do */ * work that the caller no longer has to do */
if (trans) { if (trans) {
gh->proto_discr = trans->protocol | (trans->transaction_id << 4); gh->proto_discr = trans->protocol | (trans->transaction_id << 4);
msg->lchan = trans->lchan; msg->lchan = trans->conn->lchan;
} }
if (msg->lchan) { if (msg->lchan) {

View File

@ -155,7 +155,7 @@ static int gsm411_cp_sendmsg(struct msgb *msg, struct gsm_trans *trans,
gh->msg_type = msg_type; gh->msg_type = msg_type;
/* assign the outgoing lchan */ /* assign the outgoing lchan */
msg->lchan = trans->lchan; msg->lchan = trans->conn->lchan;
/* mobile originating */ /* mobile originating */
switch (gh->msg_type) { switch (gh->msg_type) {
@ -770,7 +770,7 @@ static int gsm411_rx_rp_ack(struct msgb *msg, struct gsm_trans *trans,
static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans, static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans,
struct gsm411_rp_hdr *rph) struct gsm411_rp_hdr *rph)
{ {
struct gsm_network *net = trans->lchan->ts->trx->bts->network; struct gsm_network *net = trans->conn->lchan->ts->trx->bts->network;
struct gsm_sms *sms = trans->sms.sms; struct gsm_sms *sms = trans->sms.sms;
u_int8_t cause_len = rph->data[0]; u_int8_t cause_len = rph->data[0];
u_int8_t cause = rph->data[1]; u_int8_t cause = rph->data[1];
@ -941,8 +941,8 @@ int gsm0411_rcv_sms(struct msgb *msg, u_int8_t link_id)
trans->sms.is_mt = 0; trans->sms.is_mt = 0;
trans->sms.link_id = link_id; trans->sms.link_id = link_id;
trans->lchan = lchan; trans->conn = &lchan->conn;
use_subscr_con(&lchan->conn); use_subscr_con(trans->conn);
} }
switch(msg_type) { switch(msg_type) {
@ -1074,8 +1074,8 @@ int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms)
trans->sms.sms = sms; trans->sms.sms = sms;
trans->sms.link_id = UM_SAPI_SMS; /* FIXME: main or SACCH ? */ trans->sms.link_id = UM_SAPI_SMS; /* FIXME: main or SACCH ? */
trans->lchan = lchan; trans->conn = &lchan->conn;
use_subscr_con(&lchan->conn); use_subscr_con(trans->conn);
/* Hardcode SMSC Originating Address for now */ /* Hardcode SMSC Originating Address for now */
data = (u_int8_t *)msgb_put(msg, 8); data = (u_int8_t *)msgb_put(msg, 8);

View File

@ -227,7 +227,7 @@ static int ho_gsm48_ho_compl(struct gsm_lchan *new_lchan)
bsc_del_timer(&ho->T3103); bsc_del_timer(&ho->T3103);
/* update lchan pointer of transaction */ /* update lchan pointer of transaction */
trans_lchan_change(ho->old_lchan, new_lchan); trans_lchan_change(&ho->old_lchan->conn, &new_lchan->conn);
ho->old_lchan->state = LCHAN_S_INACTIVE; ho->old_lchan->state = LCHAN_S_INACTIVE;
lchan_auto_release(ho->old_lchan); lchan_auto_release(ho->old_lchan);

View File

@ -332,16 +332,16 @@ static int mncc_rcv_tchf(struct gsm_call *call, int msg_type,
remote_trans = trans_find_by_callref(call->net, call->remote_ref); remote_trans = trans_find_by_callref(call->net, call->remote_ref);
/* this shouldn't really happen */ /* this shouldn't really happen */
if (!remote_trans || !remote_trans->lchan) { if (!remote_trans || !remote_trans->conn) {
LOGP(DMNCC, LOGL_ERROR, "No transaction or transaction without lchan?!?\n"); LOGP(DMNCC, LOGL_ERROR, "No transaction or transaction without lchan?!?\n");
return -EIO; return -EIO;
} }
/* RTP socket of remote end has meanwhile died */ /* RTP socket of remote end has meanwhile died */
if (!remote_trans->lchan->abis_ip.rtp_socket) if (!remote_trans->conn->lchan->abis_ip.rtp_socket)
return -EIO; return -EIO;
return rtp_send_frame(remote_trans->lchan->abis_ip.rtp_socket, dfr); return rtp_send_frame(remote_trans->conn->lchan->abis_ip.rtp_socket, dfr);
} }

View File

@ -95,10 +95,10 @@ void trans_free(struct gsm_trans *trans)
break; break;
} }
if (trans->lchan) if (trans->conn)
put_subscr_con(&trans->lchan->conn); put_subscr_con(trans->conn);
if (!trans->lchan && trans->subscr && trans->subscr->net) { if (!trans->conn && trans->subscr && trans->subscr->net) {
/* Stop paging on all bts' */ /* Stop paging on all bts' */
paging_request_stop(NULL, trans->subscr, NULL); paging_request_stop(NULL, trans->subscr, NULL);
} }
@ -148,25 +148,22 @@ int trans_assign_trans_id(struct gsm_subscriber *subscr,
/* update all transactions to use a different LCHAN, e.g. /* update all transactions to use a different LCHAN, e.g.
* after handover has succeeded */ * after handover has succeeded */
int trans_lchan_change(struct gsm_lchan *lchan_old, int trans_lchan_change(struct gsm_subscriber_connection *conn_old,
struct gsm_lchan *lchan_new) struct gsm_subscriber_connection *conn_new)
{ {
struct gsm_network *net = lchan_old->ts->trx->bts->network; struct gsm_network *net = conn_old->lchan->ts->trx->bts->network;
struct gsm_trans *trans; struct gsm_trans *trans;
int num = 0; int num = 0;
llist_for_each_entry(trans, &net->trans_list, entry) { llist_for_each_entry(trans, &net->trans_list, entry) {
if (trans->lchan == lchan_old) { if (trans->conn == conn_old) {
struct gsm_subscriber_connection *conn;
/* drop old channel use count */ /* drop old channel use count */
conn = &trans->lchan->conn; put_subscr_con(conn_old);
put_subscr_con(conn);
/* assign new channel */ /* assign new channel */
trans->lchan = lchan_new; trans->conn = conn_new;
/* bump new channel use count */ /* bump new channel use count */
conn = &trans->lchan->conn; use_subscr_con(conn_new);
use_subscr_con(conn);
num++; num++;
} }
} }