aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gsm_04_08.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/gsm_04_08.c')
-rw-r--r--openbsc/src/gsm_04_08.c220
1 files changed, 117 insertions, 103 deletions
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 5c0bc8be9..f8602a330 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -1,4 +1,4 @@
-/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
+/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
* 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
@@ -58,7 +58,7 @@ void *tall_locop_ctx;
int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi);
static int gsm48_tx_simple(struct gsm_lchan *lchan,
u_int8_t pdisc, u_int8_t msg_type);
-static void schedule_reject(struct gsm_lchan *lchan);
+static void schedule_reject(struct gsm_subscriber_connection *conn);
struct gsm_lai {
u_int16_t mcc;
@@ -96,34 +96,34 @@ static int authorize_subscriber(struct gsm_loc_updating_operation *loc,
}
}
-static void release_loc_updating_req(struct gsm_lchan *lchan)
+static void release_loc_updating_req(struct gsm_subscriber_connection *conn)
{
- if (!lchan->loc_operation)
+ if (!conn->loc_operation)
return;
- bsc_del_timer(&lchan->loc_operation->updating_timer);
- talloc_free(lchan->loc_operation);
- lchan->loc_operation = 0;
- put_lchan(lchan, 0);
+ bsc_del_timer(&conn->loc_operation->updating_timer);
+ talloc_free(conn->loc_operation);
+ conn->loc_operation = 0;
+ put_subscr_con(conn, 0);
}
-static void allocate_loc_updating_req(struct gsm_lchan *lchan)
+static void allocate_loc_updating_req(struct gsm_subscriber_connection *conn)
{
- use_lchan(lchan);
- release_loc_updating_req(lchan);
+ use_subscr_con(conn);
+ release_loc_updating_req(conn);
- lchan->loc_operation = talloc_zero(tall_locop_ctx,
+ conn->loc_operation = talloc_zero(tall_locop_ctx,
struct gsm_loc_updating_operation);
}
-static int gsm0408_authorize(struct gsm_lchan *lchan, struct msgb *msg)
+static int gsm0408_authorize(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
- if (authorize_subscriber(lchan->loc_operation, lchan->subscr)) {
+ if (authorize_subscriber(conn->loc_operation, conn->subscr)) {
int rc;
- db_subscriber_alloc_tmsi(lchan->subscr);
- rc = gsm0408_loc_upd_acc(msg->lchan, lchan->subscr->tmsi);
- if (lchan->ts->trx->bts->network->send_mm_info) {
+ db_subscriber_alloc_tmsi(conn->subscr);
+ rc = gsm0408_loc_upd_acc(msg->lchan, conn->subscr->tmsi);
+ if (msg->lchan->ts->trx->bts->network->send_mm_info) {
/* send MM INFO with network name */
rc = gsm48_tx_mm_info(msg->lchan);
}
@@ -131,9 +131,9 @@ static int gsm0408_authorize(struct gsm_lchan *lchan, struct msgb *msg)
/* call subscr_update after putting the loc_upd_acc
* in the transmit queue, since S_SUBSCR_ATTACHED might
* trigger further action like SMS delivery */
- subscr_update(lchan->subscr, msg->trx->bts,
+ subscr_update(conn->subscr, msg->trx->bts,
GSM_SUBSCRIBER_UPDATE_ATTACHED);
- release_loc_updating_req(lchan);
+ release_loc_updating_req(conn);
return rc;
}
@@ -156,14 +156,14 @@ static int gsm0408_handle_lchan_signal(unsigned int subsys, unsigned int signal,
if (!lchan)
return 0;
- release_loc_updating_req(lchan);
+ release_loc_updating_req(&lchan->conn);
/* Free all transactions that are associated with the released lchan */
/* FIXME: this is not neccessarily the right thing to do, we should
* only set trans->lchan to NULL and wait for another lchan to be
* established to the same MM entity (phone/subscriber) */
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);
}
@@ -173,11 +173,13 @@ static int gsm0408_handle_lchan_signal(unsigned int subsys, unsigned int signal,
/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
{
+ struct gsm_subscriber_connection *conn;
struct gsm_bts *bts = lchan->ts->trx->bts;
struct msgb *msg = gsm48_msgb_alloc();
struct gsm48_hdr *gh;
msg->lchan = lchan;
+ conn = &lchan->conn;
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
gh->proto_discr = GSM48_PDISC_MM;
@@ -185,8 +187,8 @@ int gsm0408_loc_upd_rej(struct gsm_lchan *lchan, u_int8_t cause)
gh->data[0] = cause;
LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT "
- "LAC=%u BTS=%u\n", lchan->subscr ?
- subscr_name(lchan->subscr) : "unknown",
+ "LAC=%u BTS=%u\n", conn->subscr ?
+ subscr_name(conn->subscr) : "unknown",
lchan->ts->trx->bts->location_area_code, lchan->ts->trx->bts->nr);
counter_inc(bts->network->stats.loc_upd_resp.reject);
@@ -243,6 +245,7 @@ static int mm_tx_identity_req(struct gsm_lchan *lchan, u_int8_t id_type)
/* Parse Chapter 9.2.11 Identity Response */
static int mm_rx_id_resp(struct msgb *msg)
{
+ struct gsm_subscriber_connection *conn;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm_lchan *lchan = msg->lchan;
struct gsm_bts *bts = lchan->ts->trx->bts;
@@ -254,50 +257,53 @@ static int mm_rx_id_resp(struct msgb *msg)
DEBUGP(DMM, "IDENTITY RESPONSE: mi_type=0x%02x MI(%s)\n",
mi_type, mi_string);
+ conn = &lchan->conn;
+
dispatch_signal(SS_SUBSCR, S_SUBSCR_IDENTITY, gh->data);
switch (mi_type) {
case GSM_MI_TYPE_IMSI:
/* look up subscriber based on IMSI, create if not found */
- if (!lchan->subscr) {
- lchan->subscr = subscr_get_by_imsi(net, mi_string);
- if (!lchan->subscr)
- lchan->subscr = db_create_subscriber(net, mi_string);
+ if (!conn->subscr) {
+ conn->subscr = subscr_get_by_imsi(net, mi_string);
+ if (!conn->subscr)
+ conn->subscr = db_create_subscriber(net, mi_string);
}
- if (lchan->loc_operation)
- lchan->loc_operation->waiting_for_imsi = 0;
+ if (conn->loc_operation)
+ conn->loc_operation->waiting_for_imsi = 0;
break;
case GSM_MI_TYPE_IMEI:
case GSM_MI_TYPE_IMEISV:
/* update subscribe <-> IMEI mapping */
- if (lchan->subscr) {
- db_subscriber_assoc_imei(lchan->subscr, mi_string);
- db_sync_equipment(&lchan->subscr->equipment);
+ if (conn->subscr) {
+ db_subscriber_assoc_imei(conn->subscr, mi_string);
+ db_sync_equipment(&conn->subscr->equipment);
}
- if (lchan->loc_operation)
- lchan->loc_operation->waiting_for_imei = 0;
+ if (conn->loc_operation)
+ conn->loc_operation->waiting_for_imei = 0;
break;
}
/* Check if we can let the mobile station enter */
- return gsm0408_authorize(lchan, msg);
+ return gsm0408_authorize(conn, msg);
}
static void loc_upd_rej_cb(void *data)
{
- struct gsm_lchan *lchan = data;
+ struct gsm_subscriber_connection *conn = data;
+ struct gsm_lchan *lchan = conn->lchan;
struct gsm_bts *bts = lchan->ts->trx->bts;
gsm0408_loc_upd_rej(lchan, bts->network->reject_cause);
- release_loc_updating_req(lchan);
+ release_loc_updating_req(conn);
}
-static void schedule_reject(struct gsm_lchan *lchan)
+static void schedule_reject(struct gsm_subscriber_connection *conn)
{
- lchan->loc_operation->updating_timer.cb = loc_upd_rej_cb;
- lchan->loc_operation->updating_timer.data = lchan;
- bsc_schedule_timer(&lchan->loc_operation->updating_timer, 5, 0);
+ conn->loc_operation->updating_timer.cb = loc_upd_rej_cb;
+ conn->loc_operation->updating_timer.data = conn;
+ bsc_schedule_timer(&conn->loc_operation->updating_timer, 5, 0);
}
static const char *lupd_name(u_int8_t type)
@@ -317,6 +323,7 @@ static const char *lupd_name(u_int8_t type)
/* Chapter 9.2.15: Receive Location Updating Request */
static int mm_rx_loc_upd_req(struct msgb *msg)
{
+ struct gsm_subscriber_connection *conn;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_loc_upd_req *lu;
struct gsm_subscriber *subscr = NULL;
@@ -327,6 +334,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
int rc;
lu = (struct gsm48_loc_upd_req *) gh->data;
+ conn = &lchan->conn;
mi_type = lu->mi[0] & GSM_MI_TYPE_MASK;
@@ -353,21 +361,21 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
* Pseudo Spoof detection: Just drop a second/concurrent
* location updating request.
*/
- if (lchan->loc_operation) {
+ if (conn->loc_operation) {
DEBUGPC(DMM, "ignoring request due an existing one: %p.\n",
- lchan->loc_operation);
+ conn->loc_operation);
gsm0408_loc_upd_rej(lchan, GSM48_REJECT_PROTOCOL_ERROR);
return 0;
}
- allocate_loc_updating_req(lchan);
+ allocate_loc_updating_req(&lchan->conn);
switch (mi_type) {
case GSM_MI_TYPE_IMSI:
DEBUGPC(DMM, "\n");
/* we always want the IMEI, too */
rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEI);
- lchan->loc_operation->waiting_for_imei = 1;
+ conn->loc_operation->waiting_for_imei = 1;
/* look up subscriber based on IMSI, create if not found */
subscr = subscr_get_by_imsi(bts->network, mi_string);
@@ -379,7 +387,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
DEBUGPC(DMM, "\n");
/* we always want the IMEI, too */
rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEI);
- lchan->loc_operation->waiting_for_imei = 1;
+ conn->loc_operation->waiting_for_imei = 1;
/* look up the subscriber based on TMSI, request IMSI if it fails */
subscr = subscr_get_by_tmsi(bts->network,
@@ -387,7 +395,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
if (!subscr) {
/* send IDENTITY REQUEST message to get IMSI */
rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMSI);
- lchan->loc_operation->waiting_for_imsi = 1;
+ conn->loc_operation->waiting_for_imsi = 1;
}
break;
case GSM_MI_TYPE_IMEI:
@@ -401,7 +409,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
}
/* schedule the reject timer */
- schedule_reject(lchan);
+ schedule_reject(conn);
if (!subscr) {
DEBUGPC(DRR, "<- Can't find any subscriber for this ID\n");
@@ -409,12 +417,12 @@ static int mm_rx_loc_upd_req(struct msgb *msg)
return -EINVAL;
}
- lchan->subscr = subscr;
- lchan->subscr->equipment.classmark1 = lu->classmark1;
+ conn->subscr = subscr;
+ conn->subscr->equipment.classmark1 = lu->classmark1;
/* check if we can let the subscriber into our network immediately
* or if we need to wait for identity responses. */
- return gsm0408_authorize(lchan, msg);
+ return gsm0408_authorize(conn, msg);
}
#if 0
@@ -563,7 +571,7 @@ static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan)
}
/* 9.2.6 CM service reject */
-static int gsm48_tx_mm_serv_rej(struct gsm_lchan *lchan,
+static int gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn,
enum gsm48_reject_value value)
{
struct msgb *msg = gsm48_msgb_alloc();
@@ -571,8 +579,8 @@ static int gsm48_tx_mm_serv_rej(struct gsm_lchan *lchan,
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
- msg->lchan = lchan;
- use_lchan(lchan);
+ msg->lchan = conn->lchan;
+ use_subscr_con(conn);
gh->proto_discr = GSM48_PDISC_MM;
gh->msg_type = GSM48_MT_MM_CM_SERV_REJ;
@@ -610,20 +618,20 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg)
DEBUGP(DMM, "<- CM SERVICE REQUEST ");
if (msg->data_len < sizeof(struct gsm48_service_request*)) {
DEBUGPC(DMM, "wrong sized message\n");
- return gsm48_tx_mm_serv_rej(msg->lchan,
+ return gsm48_tx_mm_serv_rej(&msg->lchan->conn,
GSM48_REJECT_INCORRECT_MESSAGE);
}
if (msg->data_len < req->mi_len + 6) {
DEBUGPC(DMM, "does not fit in packet\n");
- return gsm48_tx_mm_serv_rej(msg->lchan,
+ return gsm48_tx_mm_serv_rej(&msg->lchan->conn,
GSM48_REJECT_INCORRECT_MESSAGE);
}
mi_type = mi[0] & GSM_MI_TYPE_MASK;
if (mi_type != GSM_MI_TYPE_TMSI) {
DEBUGPC(DMM, "mi_type is not TMSI: %d\n", mi_type);
- return gsm48_tx_mm_serv_rej(msg->lchan,
+ return gsm48_tx_mm_serv_rej(&msg->lchan->conn,
GSM48_REJECT_INCORRECT_MESSAGE);
}
@@ -641,12 +649,12 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg)
/* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
if (!subscr)
- return gsm48_tx_mm_serv_rej(msg->lchan,
+ return gsm48_tx_mm_serv_rej(&msg->lchan->conn,
GSM48_REJECT_IMSI_UNKNOWN_IN_HLR);
- if (!msg->lchan->subscr)
- msg->lchan->subscr = subscr;
- else if (msg->lchan->subscr == subscr)
+ if (!msg->lchan->conn.subscr)
+ msg->lchan->conn.subscr = subscr;
+ else if (msg->lchan->conn.subscr == subscr)
subscr_put(subscr); /* lchan already has a ref, don't need another one */
else {
DEBUGP(DMM, "<- CM Channel already owned by someone else?\n");
@@ -744,8 +752,8 @@ static int gsm0408_rcv_mm(struct msgb *msg)
break;
case GSM48_MT_MM_TMSI_REALL_COMPL:
DEBUGP(DMM, "TMSI Reallocation Completed. Subscriber: %s\n",
- msg->lchan->subscr ?
- subscr_name(msg->lchan->subscr) :
+ msg->lchan->conn.subscr ?
+ subscr_name(msg->lchan->conn.subscr) :
"unknown subscriber");
break;
case GSM48_MT_MM_IMSI_DETACH_IND:
@@ -810,7 +818,7 @@ static int gsm48_rx_rr_pag_resp(struct msgb *msg)
static int gsm48_rx_rr_classmark(struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm_subscriber *subscr = msg->lchan->subscr;
+ struct gsm_subscriber *subscr = msg->lchan->conn.subscr;
unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
u_int8_t cm2_len, cm3_len = 0;
u_int8_t *cm2, *cm3 = NULL;
@@ -858,7 +866,7 @@ static int gsm48_rx_rr_status(struct msgb *msg)
{
struct gsm48_hdr *gh = msgb_l3(msg);
- DEBUGP(DRR, "STATUS rr_cause = %s\n",
+ DEBUGP(DRR, "STATUS rr_cause = %s\n",
rr_cause_name(gh->data[0]));
return 0;
@@ -891,7 +899,7 @@ static int gsm48_rx_rr_app_info(struct msgb *msg)
DEBUGP(DNM, "RX APPLICATION INFO id/flags=0x%02x apdu_len=%u apdu=%s",
apdu_id_flags, apdu_len, hexdump(apdu_data, apdu_len));
- return db_apdu_blob_store(msg->lchan->subscr, apdu_id_flags, apdu_len, apdu_data);
+ return db_apdu_blob_store(msg->lchan->conn.subscr, apdu_id_flags, apdu_len, apdu_data);
}
/* Chapter 9.1.16 Handover complete */
@@ -1050,19 +1058,19 @@ static void gsm48_stop_cc_timer(struct gsm_trans *trans)
trans->cc.Tcurrent = 0;
}
}
-
+
static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
int msg_type, struct gsm_mncc *mncc)
{
struct msgb *msg;
if (trans)
- if (trans->lchan)
+ if (trans->conn)
DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) "
"Sending '%s' to MNCC.\n",
- trans->lchan->ts->trx->bts->nr,
- trans->lchan->ts->trx->nr,
- trans->lchan->ts->nr, trans->transaction_id,
+ trans->conn->lchan->ts->trx->bts->nr,
+ trans->conn->lchan->ts->trx->nr,
+ trans->conn->lchan->ts->nr, trans->transaction_id,
(trans->subscr)?(trans->subscr->extension):"-",
get_mncc_name(msg_type));
else
@@ -1111,12 +1119,12 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans)
}
if (trans->cc.state != GSM_CSTATE_NULL)
new_cc_state(trans, GSM_CSTATE_NULL);
- if (trans->lchan)
- trau_mux_unmap(&trans->lchan->ts->e1_link, trans->callref);
+ if (trans->conn)
+ trau_mux_unmap(&trans->conn->lchan->ts->e1_link, trans->callref);
}
static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
-
+
/* call-back from paging the B-end of the connection */
static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
struct msgb *msg, void *_lchan, void *param)
@@ -1128,7 +1136,7 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
if (hooknum != GSM_HOOK_RR_PAGING)
return -EINVAL;
-
+
if (!subscr)
return -EINVAL;
net = subscr->net;
@@ -1139,7 +1147,7 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
/* check all tranactions (without lchan) for subscriber */
llist_for_each_entry_safe(transt, tmp, &net->trans_list, entry) {
- if (transt->subscr != subscr || transt->lchan)
+ if (transt->subscr != subscr || transt->conn)
continue;
switch (event) {
case GSM_PAGING_SUCCEEDED:
@@ -1148,9 +1156,9 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
DEBUGP(DCC, "Paging subscr %s succeeded!\n",
subscr->extension);
/* Assign lchan */
- if (!transt->lchan) {
- transt->lchan = lchan;
- use_lchan(lchan);
+ if (!transt->conn) {
+ transt->conn = &lchan->conn;
+ use_subscr_con(transt->conn);
}
/* send SETUP request to called party */
gsm48_cc_tx_setup(transt, &transt->cc.msg);
@@ -1195,7 +1203,7 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
* a tch_recv_mncc request pending */
net = lchan->ts->trx->bts->network;
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");
tch_recv_mncc(net, trans->callref, 1);
}
@@ -1268,11 +1276,11 @@ static int tch_bridge(struct gsm_network *net, u_int32_t *refs)
if (!trans1 || !trans2)
return -EIO;
- if (!trans1->lchan || !trans2->lchan)
+ if (!trans1->conn || !trans2->conn)
return -EIO;
/* 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 */
@@ -1287,9 +1295,9 @@ static int tch_recv_mncc(struct gsm_network *net, u_int32_t callref, int enable)
trans = trans_find_by_callref(net, callref);
if (!trans)
return -EIO;
- if (!trans->lchan)
+ if (!trans->conn)
return 0;
- lchan = trans->lchan;
+ lchan = trans->conn->lchan;
bts = lchan->ts->trx->bts;
switch (bts->type) {
@@ -2484,7 +2492,7 @@ static int _gsm48_lchan_modify(struct gsm_trans *trans, void *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 {
@@ -2570,18 +2578,18 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg)
trans = trans_find_by_callref(net, data->callref);
if (!trans)
return -EIO;
- if (!trans->lchan)
+ if (!trans->conn)
return 0;
- if (trans->lchan->type != GSM_LCHAN_TCH_F)
+ if (trans->conn->lchan->type != GSM_LCHAN_TCH_F)
return 0;
- bts = trans->lchan->ts->trx->bts;
+ bts = trans->conn->lchan->ts->trx->bts;
switch (bts->type) {
case GSM_BTS_TYPE_NANOBTS:
- if (!trans->lchan->abis_ip.rtp_socket)
+ if (!trans->conn->lchan->abis_ip.rtp_socket)
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:
- return trau_send_frame(trans->lchan, arg);
+ return trau_send_frame(trans->conn->lchan, arg);
default:
DEBUGP(DCC, "Unknown BTS type %u\n", bts->type);
}
@@ -2659,6 +2667,7 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg)
}
/* Find lchan */
lchan = lchan_for_subscr(subscr);
+
/* If subscriber has no lchan */
if (!lchan) {
/* find transaction with this subscriber already paging */
@@ -2686,16 +2695,18 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg)
return 0;
}
/* Assign lchan */
- trans->lchan = lchan;
- use_lchan(lchan);
+ trans->conn = &lchan->conn;
+ use_subscr_con(trans->conn);
subscr_put(subscr);
}
- lchan = trans->lchan;
+
+ if (trans->conn)
+ lchan = trans->conn->lchan;
/* if paging did not respond yet */
if (!lchan) {
DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
- "Received '%s' from MNCC in paging state\n",
+ "Received '%s' from MNCC in paging state\n",
(trans->subscr)?(trans->subscr->extension):"-",
get_mncc_name(msg_type));
mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
@@ -2713,7 +2724,7 @@ int mncc_send(struct gsm_network *net, int msg_type, void *arg)
"Received '%s' from MNCC in state %d (%s)\n",
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
trans->transaction_id,
- (lchan->subscr)?(lchan->subscr->extension):"-",
+ (trans->conn->subscr)?(trans->conn->subscr->extension):"-",
get_mncc_name(msg_type), trans->cc.state,
gsm48_cc_state_name(trans->cc.state));
@@ -2750,7 +2761,7 @@ static struct datastate {
GSM48_MT_CC_CALL_CONF, gsm48_cc_rx_call_conf},
{SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF), /* ???? | 5.2.2.3.2 */
GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting},
- {SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF) | SBIT(GSM_CSTATE_CALL_RECEIVED), /* (5.2.2.6) | 5.2.2.6 | 5.2.2.6 */
+ {SBIT(GSM_CSTATE_CALL_PRESENT) | SBIT(GSM_CSTATE_MO_TERM_CALL_CONF) | SBIT(GSM_CSTATE_CALL_RECEIVED), /* (5.2.2.6) | 5.2.2.6 | 5.2.2.6 */
GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect},
/* signalling during call */
{ALL_STATES - SBIT(GSM_CSTATE_NULL),
@@ -2789,6 +2800,7 @@ static struct datastate {
static int gsm0408_rcv_cc(struct msgb *msg)
{
+ struct gsm_subscriber_connection *conn;
struct gsm48_hdr *gh = msgb_l3(msg);
u_int8_t msg_type = gh->msg_type & 0xbf;
u_int8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4; /* flip */
@@ -2800,14 +2812,16 @@ static int gsm0408_rcv_cc(struct msgb *msg)
DEBUGP(DCC, "MSG 0x%2x not defined for PD error\n", msg_type);
return -EINVAL;
}
-
+
+ conn = &lchan->conn;
+
/* Find transaction */
- trans = trans_find_by_id(lchan->subscr, GSM48_PDISC_CC, transaction_id);
+ trans = trans_find_by_id(conn->subscr, GSM48_PDISC_CC, transaction_id);
DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) "
"Received '%s' from MS in state %d (%s)\n",
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
- transaction_id, (lchan->subscr)?(lchan->subscr->extension):"-",
+ transaction_id, (conn->subscr)?(conn->subscr->extension):"-",
gsm48_cc_msg_name(msg_type), trans?(trans->cc.state):0,
gsm48_cc_state_name(trans?(trans->cc.state):0));
@@ -2816,7 +2830,7 @@ static int gsm0408_rcv_cc(struct msgb *msg)
DEBUGP(DCC, "Unknown transaction ID %x, "
"creating new trans.\n", transaction_id);
/* Create transaction */
- trans = trans_alloc(lchan->subscr, GSM48_PDISC_CC,
+ trans = trans_alloc(conn->subscr, GSM48_PDISC_CC,
transaction_id, new_callref++);
if (!trans) {
DEBUGP(DCC, "No memory for trans.\n");
@@ -2826,8 +2840,8 @@ static int gsm0408_rcv_cc(struct msgb *msg)
return -ENOMEM;
}
/* Assign transaction */
- trans->lchan = lchan;
- use_lchan(lchan);
+ trans->conn = &lchan->conn;
+ use_subscr_con(trans->conn);
}
/* find function for current state and message */