diff options
Diffstat (limited to 'openbsc/src/gsm_04_08.c')
-rw-r--r-- | openbsc/src/gsm_04_08.c | 220 |
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 */ |