gprs: Use PURGE MS messages

When a subscriber entry is going to be deleted by SGSN and when the
subscriber info has been obtained from a remote peer via GSUP, the
peer should be informed before the entry is really deleted. For this
purpose, MAP defines the PURGE MS procedure (see GSM 09.02, 19.1.4).

This patch adds support for the PURGE_MS_REQ/_ERR/_RES messages and
invokes the procedure when the subscriber entry is going to be
removed. This only applies if GSUP is being used, the Update
Location procedure has been completed successfully, and the
subscriber has not been cancelled. The removal of the entry is
delayed until a PURGE_MS_RES or PURGE_MS_ERR message is received.

Note that GSM 09.02, 19.1.4.4 implies that the subscriber data is not
to be removed when the procedure fails which is not the way the
feature has been implemented.

Note that handling 'P-TMSI freezing' is not implemented.

Ticket: OW#1338
Sponsored-by: On-Waves ehf
diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c
index d612652..8181061 100644
--- a/openbsc/tests/sgsn/sgsn_test.c
+++ b/openbsc/tests/sgsn/sgsn_test.c
@@ -1109,12 +1109,16 @@
 
 int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
 {
-	struct gprs_gsup_message to_peer;
-	struct gprs_gsup_message from_peer;
+	struct gprs_gsup_message to_peer = {0};
+	struct gprs_gsup_message from_peer = {0};
 	struct msgb *reply_msg;
+	int rc;
 
 	/* Simulate the GSUP peer */
-	gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
+	rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
+	OSMO_ASSERT(rc >= 0);
+	OSMO_ASSERT(to_peer.imsi[0] != 0);
+	strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
 
 	/* This invalidates the pointers in to_peer */
 	msgb_free(msg);
@@ -1129,13 +1133,13 @@
 		return my_subscr_request_auth_info_gsup_auth(NULL);
 
 	case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
-		/* TODO: send RES/ERR */
-		return 0;
+		from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
+		break;
 
 	default:
 		if ((to_peer.message_type & 0b00000011) == 0) {
 			/* Unhandled request */
-			/* TODO: send error(NOT_IMPL) */
+			/* Send error(NOT_IMPL) */
 			from_peer.message_type = to_peer.message_type + 1;
 			from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
 			break;