ACK sms-submit
diff --git a/include/openbsc/gsm_04_11.h b/include/openbsc/gsm_04_11.h
index 84751a3..1c04467 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 c4ac286..8a0530c 100644
--- a/src/gsm_04_11.c
+++ b/src/gsm_04_11.c
@@ -31,10 +31,30 @@
 
 #include <openbsc/msgb.h>
 #include <openbsc/debug.h>
+#include <openbsc/gsm_data.h>
+#include <openbsc/gsm_subscriber.h>
 #include <openbsc/gsm_04_11.h>
 #include <openbsc/gsm_04_08.h>
 #include <openbsc/abis_rsl.h>
 
+#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 @@
 	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 @@
 		/* 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 c63990e..20a8894 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