emu: Add a crash re-producer for the SGSN (and the concept of tests)

Introduce the concept of tests that will be ran one after the other.
This new test will send static message that will lead to the opening
of a PDP context. At this point one should use ping with a large
packet size and suspend/stop the emulator. Once the NS connection is
considered dead the SGSN will crash with a double free.

Reproduce:
0.) Add IMSI 901700000003094 to the ACL
1.) Stop/Suspend the emulation process so the NS Alive times out
2.) Use ping IP -s 2048

This will create a double free...

 #4  0xb7bb2646 in talloc_abort_double_free () at talloc.c:175
 #5  0xb7bbd41a in talloc_chunk_from_ptr (ptr=0x8091208) at talloc.c:190
 #6  _talloc_free (ptr=0x8091208) at talloc.c:517
 #7  talloc_free (ptr=ptr@entry=0x8091208) at talloc.c:990
 #8  0xb7bb319b in msgb_free (m=m@entry=0x8091208) at msgb.c:72
 #9  0x0804db54 in sndcp_send_ud_frag (fs=0xbfffcc6c) at gprs_sndcp.c:423
 #10 sndcp_unitdata_req (msg=msg@entry=0x808eed8, lle=0x808fbc8, nsapi=5 '\005',
    mmcontext=mmcontext@entry=0x80903e8) at gprs_sndcp.c:471
diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp
index f4d38cd..b68b856 100644
--- a/tests/emu/pcu_emu.cpp
+++ b/tests/emu/pcu_emu.cpp
@@ -24,6 +24,9 @@
 #include <pcu_vty.h>
 }
 
+#include "gprs_tests.h"
+
+
 #include <gprs_bssgp_pcu.h>
 #include <gprs_rlcmac.h>
 
@@ -31,6 +34,8 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 
+static int current_test;
+
 /* Extern data to please the underlying code */
 void *tall_pcu_ctx;
 struct gprs_rlcmac_bts *gprs_rlcmac_bts;
@@ -39,6 +44,24 @@
 extern void test_replay_gprs_attach(struct gprs_bssgp_pcu *pcu);
 extern void test_replay_gprs_data(struct gprs_bssgp_pcu *, struct msgb *, struct tlv_parsed *);
 
+extern void test_pdp_activation_start(struct gprs_bssgp_pcu *pcu);
+extern void test_pdp_activation_data(struct gprs_bssgp_pcu *, struct msgb *, struct tlv_parsed*);
+
+struct gprs_test all_tests[] = {
+	gprs_test("gprs_attach_with_tmsi",
+			"A simple test that verifies that N(U) is "
+			"increasing across various messages. This makes "
+			"sure that no new LLE/LLME is created on the fly.",
+			test_replay_gprs_attach,
+			test_replay_gprs_data),
+	gprs_test("gprs_full_attach_pdp_activation",
+			"A simple test to do a GPRS attach and open a PDP "
+			"context. Then goes to sleep and waits for you to ping "
+			"the connection and hopefully re-produce a crash.",
+			test_pdp_activation_start,
+			test_pdp_activation_data),
+};
+
 struct gprs_rlcmac_bts *create_bts()
 {
 	struct gprs_rlcmac_bts *bts;
@@ -68,12 +91,12 @@
 static void bvci_unblocked(struct gprs_bssgp_pcu *pcu)
 {
 	printf("BVCI unblocked. We can begin with test cases.\n");
-	test_replay_gprs_attach(pcu);
+	all_tests[current_test].start(pcu);
 }
 
 static void bssgp_data(struct gprs_bssgp_pcu *pcu, struct msgb *msg, struct tlv_parsed *tp)
 {
-	test_replay_gprs_data(pcu, msg, tp);
+	all_tests[current_test].data(pcu, msg, tp);
 }
 
 void create_and_connect_bssgp(struct gprs_rlcmac_bts *bts,
@@ -112,6 +135,21 @@
 	return EXIT_SUCCESS;
 }
 
+
+/*
+ * Test handling..
+ */
+void gprs_test_success(struct gprs_bssgp_pcu *pcu)
+{
+	current_test += 1;
+	if (current_test >= ARRAY_SIZE(all_tests)) {
+		printf("All tests executed.\n");
+		exit(EXIT_SUCCESS);
+	}
+
+	all_tests[current_test].start(pcu);
+}
+
 /*
  * stubs that should not be reached
  */