libgb: don't call directly into GMM / LLC layer

Instead of direct function calls to individual functions, we now
generate primitives (osmo_prim) and send them to one
application-provided function "bssgp_prim_cb()"
diff --git a/openbsc/include/osmocom/gprs/gprs_bssgp.h b/openbsc/include/osmocom/gprs/gprs_bssgp.h
index 4fcdfb5..e060fc0 100644
--- a/openbsc/include/osmocom/gprs/gprs_bssgp.h
+++ b/openbsc/include/osmocom/gprs/gprs_bssgp.h
@@ -144,6 +144,7 @@
 /* Our implementation */
 
 #include <osmocom/gsm/gsm48.h>
+#include <osmocom/gsm/prim.h>
 
 /* gprs_bssgp_util.c */
 extern struct gprs_ns_inst *bssgp_nsi;
@@ -155,6 +156,40 @@
 /* Chapter 10.4.14: Status */
 int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);
 
+enum bssgp_prim {
+	PRIM_BSSGP_DL_UD,
+	PRIM_BSSGP_UL_UD,
+	PRIM_BSSGP_PTM_UD,
+
+	PRIM_BSSGP_GMM_SUSPEND,
+	PRIM_BSSGP_GMM_RESUME,
+	PRIM_BSSGP_GMM_PAGING,
+
+	PRIM_NM_FLUSH_LL,
+	PRIM_NM_LLC_DISCARDED,
+	PRIM_NM_BVC_RESET,
+	PRIM_NM_BVC_BLOCK,
+	PRIM_NM_BVC_UNBLOCK,
+};
+
+struct osmo_bssgp_prim {
+	struct osmo_prim_hdr oph;
+
+	/* common fields */
+	uint16_t nsei;
+	uint16_t bvci;
+	uint32_t tlli;
+	struct tlv_parsed *tp;
+	struct gprs_ra_id *ra_id;
+
+	/* specific fields */
+	union {
+		struct {
+			uint8_t *suspend_ref;
+		} resume;
+	} u;
+};
+
 /* gprs_bssgp.c */
 
 #define BVC_S_BLOCKED	0x0001
@@ -264,4 +299,6 @@
 int gprs_bssgp_vty_init(void);
 void gprs_bssgp_set_log_ss(int ss);
 
+int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
+
 #endif /* _GPRS_BSSGP_H */