SMS improvements

* send more pending messages after RP-ACK of DELIVER has been received
* send pending messages after RP-SMMA has been received
* clear the transaction when sending CP-ACK in MT/DELIVER case
* always use the same transaction ID (since my assumptions about
  SMS transactions were wrong)
* try to deliver messages through existing lchan rather than starting
  paging
* send pending SM's after LOCATION UPDATE ACCEPT has been sent
diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c
index 4ab06ec..9a5a08c 100644
--- a/openbsc/src/gsm_04_11.c
+++ b/openbsc/src/gsm_04_11.c
@@ -536,7 +536,14 @@
 	sms_free(sms);
 	trans->sms.sms = NULL;
 
-	trans_free(trans);
+	/* do not free the transaction here, this is done by sending CP-ACK */
+
+	/* check for more messages for this subscriber */
+	sms = db_sms_get_unsent_for_subscr(msg->lchan->subscr);
+	if (sms)
+		gsm411_send_sms_lchan(msg->lchan, sms);
+	else
+		rsl_release_request(msg->lchan, UM_SAPI_SMS);
 
 	return 0;
 }
@@ -584,15 +591,23 @@
 static int gsm411_rx_rp_smma(struct msgb *msg, struct gsm_trans *trans,
 			     struct gsm411_rp_hdr *rph)
 {
+	struct gsm_sms *sms;
 	int rc;
 
+	rc = gsm411_send_rp_ack(trans, rph->msg_ref);
+	trans->sms.rp_state = GSM411_RPS_IDLE;
+
 	/* MS tells us that it has memory for more SMS, we need
 	 * to check if we have any pending messages for it and then
 	 * transfer those */
 	dispatch_signal(SS_SMS, S_SMS_SMMA, trans->subscr);
 
-	rc = gsm411_send_rp_ack(trans, rph->msg_ref);
-	trans->sms.rp_state = GSM411_RPS_IDLE;
+	/* check for more messages for this subscriber */
+	sms = db_sms_get_unsent_for_subscr(msg->lchan->subscr);
+	if (sms)
+		gsm411_send_sms_lchan(msg->lchan, sms);
+	else
+		rsl_release_request(msg->lchan, UM_SAPI_SMS);
 
 	return rc;
 }
@@ -638,8 +653,15 @@
 static int gsm411_tx_cp_ack(struct gsm_trans *trans)
 {
 	struct msgb *msg = gsm411_msgb_alloc();
+	int rc;
 
-	return gsm411_cp_sendmsg(msg, trans, GSM411_MT_CP_ACK);
+	rc = gsm411_cp_sendmsg(msg, trans, GSM411_MT_CP_ACK);
+
+	if (trans->sms.is_mt) {
+		/* If this is a MT SMS DELIVER, we can clear transaction here */
+		trans->sms.cp_state = GSM411_CPS_IDLE;
+		trans_free(trans);
+	}
 }
 
 static int gsm411_tx_cp_error(struct gsm_trans *trans, u_int8_t cause)
@@ -744,16 +766,20 @@
 };
 #endif
 
-/* Take a SMS in gsm_sms structure and send it through lchan */
+/* 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)
 {
 	struct msgb *msg = gsm411_msgb_alloc();
 	struct gsm_trans *trans;
 	u_int8_t *data, *rp_ud_len;
 	u_int8_t msg_ref = 42;
-	u_int8_t transaction_id = 1;	/* FIXME: random */
+	u_int8_t transaction_id;
 	int rc;
 
+	transaction_id = 4; /* FIXME: we always use 4 for now */
+
 	msg->lchan = lchan;
 
 	DEBUGP(DSMS, "send_sms_lchan()\n");
@@ -813,7 +839,8 @@
 	/* FIXME: enter 'wait for RP-ACK' state, start TR1N */
 }
 
-/* RLL SAPI3 establish callback */
+/* RLL SAPI3 establish callback. Now we have a RLL connection and
+ * can deliver the actual message */
 static void rll_ind_cb(struct gsm_lchan *lchan, u_int8_t link_id,
 			void *_sms, enum bsc_rllr_ind type)
 {
@@ -834,7 +861,8 @@
 	}
 }
 
-/* paging callback */
+/* paging callback. Here we get called if paging a subscriber has
+ * succeeded or failed. */
 static int paging_cb_send_sms(unsigned int hooknum, unsigned int event,
 			      struct msgb *msg, void *_lchan, void *_sms)
 {
@@ -856,6 +884,7 @@
 			rc = -EIO;
 			break;
 		}
+		/* Establish a SAPI3 RLL connection for SMS */
 		rc = rll_establish(lchan, UM_SAPI_SMS, rll_ind_cb, sms);
 		break;
 	case GSM_PAGING_EXPIRED:
@@ -870,13 +899,20 @@
 	return rc;
 }
 
+/* high-level function to send a SMS to a given subscriber. The function
+ * will take care of paging the subscriber, establishing the RLL SAPI3
+ * connection, etc. */
 int gsm411_send_sms_subscr(struct gsm_subscriber *subscr,
 			   struct gsm_sms *sms)
 {
+	struct gsm_lchan *lchan;
+
 	/* check if we already have an open lchan to the subscriber.
 	 * if yes, send the SMS this way */
-	//if (subscr->lchan)
-		//return gsm411_send_sms_lchan(subscr->lchan, sms);
+	lchan = lchan_for_subscr(subscr);
+	if (lchan)
+		return rll_establish(lchan, UM_SAPI_SMS,
+				     rll_ind_cb, sms);
 
 	/* if not, we have to start paging */
 	paging_request(subscr->net, subscr, RSL_CHANNEED_SDCCH,
@@ -885,7 +921,36 @@
 	return 0;
 }
 
+static int subscr_sig_cb(unsigned int subsys, unsigned int signal,
+			 void *handler_data, void *signal_data)
+{
+	struct gsm_subscriber *subscr;
+	struct gsm_lchan *lchan;
+	struct gsm_sms *sms;
+
+	switch (signal) {
+	case S_SUBSCR_ATTACHED:
+		/* A subscriber has attached. Check if there are
+		 * any pending SMS for him to be delivered */
+		subscr = signal_data;
+		lchan = lchan_for_subscr(subscr);
+		if (!lchan)
+			break;
+		sms = db_sms_get_unsent_for_subscr(subscr);
+		if (!sms)
+			break;
+		/* Establish a SAPI3 RLL connection for SMS */
+		rll_establish(lchan, UM_SAPI_SMS, rll_ind_cb, sms);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static __attribute__((constructor)) void on_dso_load_sms(void)
 {
 	tall_gsms_ctx = talloc_named_const(tall_bsc_ctx, 1, "sms");
+
+	register_signal_handler(SS_SUBSCR, subscr_sig_cb, NULL);
 }