diff --git a/include/openbsc/gsm_04_11.h b/include/openbsc/gsm_04_11.h index 84751a326..1c044677f 100644 --- a/include/openbsc/gsm_04_11.h +++ b/include/openbsc/gsm_04_11.h @@ -20,8 +20,8 @@ #define GSM411_MT_RP_ERROR_MT 0x04 #define GSM411_MT_RP_SMMA_MO 0x05 -/* Chapter 8.1.1 */ -struct gsm411_rp_data_hdr { +/* Chapter 8.2.1 */ +struct gsm411_rp_hdr { u_int8_t len; u_int8_t msg_type; u_int8_t msg_ref; diff --git a/src/gsm_04_11.c b/src/gsm_04_11.c index c4ac286a2..8a0530c7e 100644 --- a/src/gsm_04_11.c +++ b/src/gsm_04_11.c @@ -31,10 +31,30 @@ #include #include +#include +#include #include #include #include +#define GSM411_ALLOC_SIZE 1024 +#define GSM411_ALLOC_HEADROOM 128 + +static struct msgb *gsm411_msgb_alloc(void) +{ + return msgb_alloc_headroom(GSM411_ALLOC_SIZE, GSM411_ALLOC_HEADROOM); +} + +static int gsm0411_sendmsg(struct msgb *msg) +{ + if (msg->lchan) + msg->trx = msg->lchan->ts->trx; + + msg->l3h = msg->data; + + return rsl_data_request(msg, 0); +} + static char *gsm411_7bit_decode(u_int8_t *user_data, u_int8_t length) { u_int8_t d_off = 0, b_off = 0; @@ -97,12 +117,54 @@ static int gsm411_sms_submit_from_msgb(struct msgb *msg) return 0; } +static int gsm411_send_rp_ack(struct gsm_lchan *lchan, u_int8_t msg_ref) +{ + struct msgb *msg = gsm411_msgb_alloc(); + struct gsm48_hdr *gh; + struct gsm411_rp_hdr *rp; + + msg->lchan = lchan; + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + gh->proto_discr = GSM48_PDISC_SMS; + gh->msg_type = GSM411_MT_CP_ACK; + + rp = (struct gsm411_rp_hdr *)msgb_put(msg, sizeof(*rp)); + rp->msg_type = GSM411_MT_RP_ACK_MT; + rp->msg_ref = msg_ref; + + DEBUGP(DSMS, "TX: SMS RP ACK\n"); + + return gsm0411_sendmsg(msg); +} + +static int gsm411_send_rp_error(struct gsm_lchan *lchan, u_int8_t msg_ref) +{ + struct msgb *msg = gsm411_msgb_alloc(); + struct gsm48_hdr *gh; + struct gsm411_rp_hdr *rp; + + msg->lchan = lchan; + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + gh->proto_discr = GSM48_PDISC_SMS; + gh->msg_type = GSM411_MT_CP_ERROR; + + rp = (struct gsm411_rp_hdr *)msgb_put(msg, sizeof(*rp)); + rp->msg_type = GSM411_MT_RP_ERROR_MT; + rp->msg_ref = msg_ref; + + DEBUGP(DSMS, "TX: SMS RP ERROR\n"); + + return gsm0411_sendmsg(msg); +} + static int gsm411_cp_data(struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); int rc = 0; - struct gsm411_rp_data_hdr *rp_data = (struct gsm411_rp_data_hdr*)&gh->data; + struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data; u_int8_t msg_type = rp_data->msg_type & 0x07; switch (msg_type) { @@ -111,6 +173,7 @@ static int gsm411_cp_data(struct msgb *msg) /* Skip SMSC no and RP-UD length */ msg->smsh = &rp_data->data[1] + rp_data->data[1] + 2; gsm411_sms_submit_from_msgb(msg); + gsm411_send_rp_ack(msg->lchan, rp_data->msg_ref); break; default: DEBUGP(DSMS, "Unimplemented RP type 0x%02x\n", msg_type); diff --git a/tests/sms/Makefile.am b/tests/sms/Makefile.am index c63990ea1..20a88947a 100644 --- a/tests/sms/Makefile.am +++ b/tests/sms/Makefile.am @@ -1,5 +1,12 @@ INCLUDES = $(all_includes) -I$(top_srcdir)/include noinst_PROGRAMS = sms_test -sms_test_SOURCES = sms_test.c $(top_srcdir)/src/gsm_04_11.c \ - $(top_srcdir)/src/debug.c $(top_srcdir)/src/msgb.c +sms_test_SOURCES = sms_test.c $(top_srcdir)/src/misdn.c \ + $(top_srcdir)/src/abis_rsl.c $(top_srcdir)/src/abis_nm.c \ + $(top_srcdir)/src/gsm_04_08.c $(top_srcdir)/src/gsm_data.c \ + $(top_srcdir)/src/gsm_subscriber.c $(top_srcdir)/src/msgb.c \ + $(top_srcdir)/src/select.c $(top_srcdir)/src/chan_alloc.c \ + $(top_srcdir)/src/timer.c $(top_srcdir)/src/debug.c \ + $(top_srcdir)/src/db.c $(top_srcdir)/src/gsm_04_11.c + +sms_test_LDADD = -ldl -ldbi