aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gsm_04_11.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/gsm_04_11.c')
-rw-r--r--openbsc/src/gsm_04_11.c89
1 files changed, 43 insertions, 46 deletions
diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c
index f12e05b1f..0c12f15f5 100644
--- a/openbsc/src/gsm_04_11.c
+++ b/openbsc/src/gsm_04_11.c
@@ -24,6 +24,7 @@
*/
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -63,7 +64,7 @@ static const struct value_string cp_cause_strs[] = {
{ GSM411_CP_CAUSE_SEMANT_INC_MSG, "Semantically Incorrect Message" },
{ GSM411_CP_CAUSE_INV_MAND_INF, "Invalid Mandatory Information" },
{ GSM411_CP_CAUSE_MSGTYPE_NOTEXIST, "Message Type doesn't exist" },
- { GSM411_CP_CAUSE_MSG_INCOMP_STATE,
+ { GSM411_CP_CAUSE_MSG_INCOMP_STATE,
"Message incompatible with protocol state" },
{ GSM411_CP_CAUSE_IE_NOTEXIST, "IE does not exist" },
{ GSM411_CP_CAUSE_PROTOCOL_ERR, "Protocol Error" },
@@ -121,16 +122,11 @@ struct msgb *gsm411_msgb_alloc(void)
"GSM 04.11");
}
-static int gsm411_sendmsg(struct msgb *msg, u_int8_t link_id)
+static int gsm411_sendmsg(struct gsm_subscriber_connection *conn, struct msgb *msg, u_int8_t link_id)
{
- if (msg->lchan)
- msg->trx = msg->lchan->ts->trx;
-
- msg->l3h = msg->data;
-
DEBUGP(DSMS, "GSM4.11 TX %s\n", hexdump(msg->data, msg->len));
-
- return rsl_data_request(msg, link_id);
+ msg->l3h = msg->data;
+ return gsm0808_submit_dtap(conn, msg, link_id);
}
/* SMC TC1* is expired */
@@ -154,9 +150,6 @@ static int gsm411_cp_sendmsg(struct msgb *msg, struct gsm_trans *trans,
gh->proto_discr = trans->protocol | (trans->transaction_id<<4);
gh->msg_type = msg_type;
- /* assign the outgoing lchan */
- msg->lchan = trans->lchan;
-
/* mobile originating */
switch (gh->msg_type) {
case GSM411_MT_CP_DATA:
@@ -179,7 +172,7 @@ static int gsm411_cp_sendmsg(struct msgb *msg, struct gsm_trans *trans,
DEBUGPC(DSMS, "trans=%x\n", trans->transaction_id);
- return gsm411_sendmsg(msg, trans->sms.link_id);
+ return gsm411_sendmsg(trans->conn, msg, trans->sms.link_id);
}
/* Prefix msg with a RP-DATA header and send as CP-DATA */
@@ -215,7 +208,7 @@ static u_int8_t unbcdify(u_int8_t value)
u_int8_t ret;
if ((value & 0x0F) > 9 || (value >> 4) > 9)
- LOGP(DSMS, LOGL_ERROR,
+ LOGP(DSMS, LOGL_ERROR,
"unbcdify got too big nibble: 0x%02X\n", value);
ret = (value&0x0F)*10;
@@ -509,11 +502,10 @@ static int gsm340_gen_tpdu(struct msgb *msg, struct gsm_sms *sms)
return msg->len - old_msg_len;
}
-/* process an incoming TPDU (called from RP-DATA)
- * return value > 0: RP CAUSE for ERROR; < 0: silent error; 0 = success */
-static int gsm340_rx_tpdu(struct msgb *msg)
+/* process an incoming TPDU (called from RP-DATA)
+ * return value > 0: RP CAUSE for ERROR; < 0: silent error; 0 = success */
+static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
- struct gsm_bts *bts = msg->lchan->ts->trx->bts;
u_int8_t *smsp = msgb_sms(msg);
struct gsm_sms *gsms;
u_int8_t sms_mti, sms_mms, sms_vpf, sms_alphabet, sms_rp;
@@ -522,7 +514,7 @@ static int gsm340_rx_tpdu(struct msgb *msg)
u_int8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */
int rc = 0;
- counter_inc(bts->network->stats.sms.submitted);
+ counter_inc(conn->bts->network->stats.sms.submitted);
gsms = sms_alloc();
if (!gsms)
@@ -575,7 +567,7 @@ static int gsm340_rx_tpdu(struct msgb *msg)
sms_vp = 0;
break;
default:
- LOGP(DSMS, LOGL_NOTICE,
+ LOGP(DSMS, LOGL_NOTICE,
"SMS Validity period not implemented: 0x%02x\n", sms_vpf);
return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
}
@@ -594,7 +586,7 @@ static int gsm340_rx_tpdu(struct msgb *msg)
}
}
- gsms->sender = subscr_get(msg->lchan->subscr);
+ gsms->sender = subscr_get(msg->lchan->conn.subscr);
LOGP(DSMS, LOGL_INFO, "RX SMS: Sender: %s, MTI: 0x%02x, VPF: 0x%02x, "
"MR: 0x%02x PID: 0x%02x, DCS: 0x%02x, DA: %s, "
@@ -602,7 +594,7 @@ static int gsm340_rx_tpdu(struct msgb *msg)
subscr_name(gsms->sender), sms_mti, sms_vpf, gsms->msg_ref,
gsms->protocol_id, gsms->data_coding_scheme, gsms->dest_addr,
gsms->user_data_len,
- sms_alphabet == DCS_7BIT_DEFAULT ? gsms->text :
+ sms_alphabet == DCS_7BIT_DEFAULT ? gsms->text :
hexdump(gsms->user_data, gsms->user_data_len));
gsms->validity_minutes = gsm340_validity_period(sms_vpf, sms_vp);
@@ -610,10 +602,10 @@ static int gsm340_rx_tpdu(struct msgb *msg)
dispatch_signal(SS_SMS, 0, gsms);
/* determine gsms->receiver based on dialled number */
- gsms->receiver = subscr_get_by_extension(bts->network, gsms->dest_addr);
+ gsms->receiver = subscr_get_by_extension(conn->bts->network, gsms->dest_addr);
if (!gsms->receiver) {
rc = 1; /* cause 1: unknown subscriber */
- counter_inc(bts->network->stats.sms.no_receiver);
+ counter_inc(conn->bts->network->stats.sms.no_receiver);
goto out;
}
@@ -687,7 +679,7 @@ static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans,
DEBUGP(DSMS, "DST(%u,%s)\n", dst_len, hexdump(dst, dst_len));
- rc = gsm340_rx_tpdu(msg);
+ rc = gsm340_rx_tpdu(trans->conn, msg);
if (rc == 0)
return gsm411_send_rp_ack(trans, rph->msg_ref);
else if (rc > 0)
@@ -753,14 +745,17 @@ static int gsm411_rx_rp_ack(struct msgb *msg, struct gsm_trans *trans,
trans->sms.sms = NULL;
/* check for more messages for this subscriber */
- sms = db_sms_get_unsent_for_subscr(msg->lchan->subscr);
+ assert(msg->lchan->conn.subscr == trans->subscr);
+
+ sms = db_sms_get_unsent_for_subscr(trans->subscr);
if (sms)
- gsm411_send_sms_lchan(msg->lchan, sms);
+ gsm411_send_sms_lchan(trans->conn, sms);
/* free the transaction here */
trans_free(trans);
/* release channel if done */
+#warning "BROKEN. The SAPI will be released automatically by the BSC"
if (!sms)
rsl_release_request(msg->lchan, trans->sms.link_id, 0);
@@ -770,7 +765,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,
struct gsm411_rp_hdr *rph)
{
- struct gsm_network *net = trans->lchan->ts->trx->bts->network;
+ struct gsm_network *net = trans->conn->bts->network;
struct gsm_sms *sms = trans->sms.sms;
u_int8_t cause_len = rph->data[0];
u_int8_t cause = rph->data[1];
@@ -780,7 +775,7 @@ static int gsm411_rx_rp_error(struct msgb *msg, struct gsm_trans *trans,
* the cause and take action depending on it */
LOGP(DSMS, LOGL_NOTICE, "%s: RX SMS RP-ERROR, cause %d:%d (%s)\n",
- subscr_name(msg->lchan->subscr), cause_len, cause,
+ subscr_name(trans->conn->subscr), cause_len, cause,
get_value_string(rp_cause_strs, cause));
if (!trans->sms.is_mt) {
@@ -833,11 +828,13 @@ static int gsm411_rx_rp_smma(struct msgb *msg, struct gsm_trans *trans,
dispatch_signal(SS_SMS, S_SMS_SMMA, trans->subscr);
/* check for more messages for this subscriber */
- sms = db_sms_get_unsent_for_subscr(msg->lchan->subscr);
+ assert(msg->lchan->conn.subscr == trans->subscr);
+ sms = db_sms_get_unsent_for_subscr(trans->subscr);
if (sms)
- gsm411_send_sms_lchan(msg->lchan, sms);
+ gsm411_send_sms_lchan(trans->conn, sms);
else
rsl_release_request(msg->lchan, trans->sms.link_id, 0);
+#warning "BROKEN: The SAPI=3 will be released automatically by the BSC"
return rc;
}
@@ -920,16 +917,16 @@ int gsm0411_rcv_sms(struct msgb *msg, u_int8_t link_id)
struct gsm_trans *trans;
int rc = 0;
- if (!lchan->subscr)
+ if (!lchan->conn.subscr)
return -EIO;
/* FIXME: send some error message */
DEBUGP(DSMS, "trans_id=%x ", transaction_id);
- trans = trans_find_by_id(lchan->subscr, GSM48_PDISC_SMS,
+ trans = trans_find_by_id(lchan->conn.subscr, GSM48_PDISC_SMS,
transaction_id);
if (!trans) {
DEBUGPC(DSMS, "(new) ");
- trans = trans_alloc(lchan->subscr, GSM48_PDISC_SMS,
+ trans = trans_alloc(lchan->conn.subscr, GSM48_PDISC_SMS,
transaction_id, new_callref++);
if (!trans) {
DEBUGPC(DSMS, "No memory for trans\n");
@@ -941,8 +938,8 @@ int gsm0411_rcv_sms(struct msgb *msg, u_int8_t link_id)
trans->sms.is_mt = 0;
trans->sms.link_id = link_id;
- trans->lchan = lchan;
- use_lchan(lchan);
+ trans->conn = &lchan->conn;
+ use_subscr_con(trans->conn);
}
switch(msg_type) {
@@ -961,7 +958,7 @@ int gsm0411_rcv_sms(struct msgb *msg, u_int8_t link_id)
if (i == transaction_id)
continue;
- ptrans = trans_find_by_id(lchan->subscr,
+ ptrans = trans_find_by_id(lchan->conn.subscr,
GSM48_PDISC_SMS, i);
if (!ptrans)
continue;
@@ -1041,7 +1038,7 @@ static u_int8_t tpdu_test[] = {
/* Take a SMS in gsm_sms structure and send it through an already
* existing lchan. We also assume that the caller ensured this lchan already
* has a SAPI3 RLL connection! */
-int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms)
+int gsm411_send_sms_lchan(struct gsm_subscriber_connection *conn, struct gsm_sms *sms)
{
struct msgb *msg = gsm411_msgb_alloc();
struct gsm_trans *trans;
@@ -1050,18 +1047,16 @@ int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms)
int transaction_id;
int rc;
- transaction_id = trans_assign_trans_id(lchan->subscr, GSM48_PDISC_SMS, 0);
+ transaction_id = trans_assign_trans_id(conn->subscr, GSM48_PDISC_SMS, 0);
if (transaction_id == -1) {
LOGP(DSMS, LOGL_ERROR, "No available transaction ids\n");
return -EBUSY;
}
- msg->lchan = lchan;
-
DEBUGP(DSMS, "send_sms_lchan()\n");
/* FIXME: allocate transaction with message reference */
- trans = trans_alloc(lchan->subscr, GSM48_PDISC_SMS,
+ trans = trans_alloc(conn->subscr, GSM48_PDISC_SMS,
transaction_id, new_callref++);
if (!trans) {
LOGP(DSMS, LOGL_ERROR, "No memory for trans\n");
@@ -1074,8 +1069,8 @@ int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms)
trans->sms.sms = sms;
trans->sms.link_id = UM_SAPI_SMS; /* FIXME: main or SACCH ? */
- trans->lchan = lchan;
- use_lchan(lchan);
+ trans->conn = conn;
+ use_subscr_con(trans->conn);
/* Hardcode SMSC Originating Address for now */
data = (u_int8_t *)msgb_put(msg, 8);
@@ -1112,7 +1107,7 @@ int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms)
DEBUGP(DSMS, "TX: SMS DELIVER\n");
- counter_inc(lchan->ts->trx->bts->network->stats.sms.delivered);
+ counter_inc(conn->bts->network->stats.sms.delivered);
return gsm411_rp_sendmsg(msg, trans, GSM411_MT_RP_DATA_MT, msg_ref);
/* FIXME: enter 'wait for RP-ACK' state, start TR1N */
@@ -1130,11 +1125,13 @@ static void rll_ind_cb(struct gsm_lchan *lchan, u_int8_t link_id,
switch (type) {
case BSC_RLLR_IND_EST_CONF:
- gsm411_send_sms_lchan(lchan, sms);
+#warning "BROKEN: The BSC will establish this transparently"
+ gsm411_send_sms_lchan(&lchan->conn, sms);
break;
case BSC_RLLR_IND_REL_IND:
case BSC_RLLR_IND_ERR_IND:
case BSC_RLLR_IND_TIMEOUT:
+#warning "BROKEN: We will need to handle SAPI n Reject"
sms_free(sms);
break;
}