gb: Add bssgp_msgb_copy function

This function originates from openbsc/src/gprs but is just specific
to BSSGP/Gb on the same level like bssgp_msgb_alloc.

This commit puts the former gprs_msgb_copy function beside
bssgp_msgb_alloc.

Renamed function:

  gprs_msgb_copy -> bssgp_msgb_copy

Sponsored-by: On-Waves ehf
diff --git a/src/gb/gprs_bssgp_util.c b/src/gb/gprs_bssgp_util.c
index 3c42e4d..19ae23a 100644
--- a/src/gb/gprs_bssgp_util.c
+++ b/src/gb/gprs_bssgp_util.c
@@ -79,6 +79,36 @@
 	return msg;
 }
 
+struct msgb *bssgp_msgb_copy(const struct msgb *msg, const char *name)
+{
+	struct libgb_msgb_cb *old_cb, *new_cb;
+	struct msgb *new_msg;
+
+	new_msg = msgb_copy(msg, name);
+	if (!new_msg)
+		return NULL;
+
+	/* copy GB specific data */
+	old_cb = LIBGB_MSGB_CB(msg);
+	new_cb = LIBGB_MSGB_CB(new_msg);
+
+	if (old_cb->bssgph)
+		new_cb->bssgph = new_msg->_data + (old_cb->bssgph - msg->_data);
+	if (old_cb->llch)
+		new_cb->llch = new_msg->_data + (old_cb->llch - msg->_data);
+
+	/* bssgp_cell_id is a pointer into the old msgb, so we need to make
+	 * it a pointer into the new msgb */
+	if (old_cb->bssgp_cell_id)
+		new_cb->bssgp_cell_id = new_msg->_data +
+			(old_cb->bssgp_cell_id - msg->_data);
+	new_cb->nsei = old_cb->nsei;
+	new_cb->bvci = old_cb->bvci;
+	new_cb->tlli = old_cb->tlli;
+
+	return new_msg;
+}
+
 /* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */
 int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
 			 uint16_t bvci, uint16_t ns_bvci)
diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map
index 43ebbf8..75406c0 100644
--- a/src/gb/libosmogb.map
+++ b/src/gb/libosmogb.map
@@ -6,6 +6,7 @@
 bssgp_fc_init;
 bssgp_fc_ms_init;
 bssgp_msgb_alloc;
+bssgp_msgb_copy;
 bssgp_msgb_tlli_put;
 bssgp_parse_cell_id;
 bssgp_tx_bvc_block;