aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gb_proxy.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-06-08 18:14:37 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-06-09 21:40:44 +0800
commit62d97986a3170f6ccc7e0963a32cc4cf8f8da3c2 (patch)
tree9825ad99a34120308b0cdd34d5f09f6a02bd8ad1 /openbsc/src/gprs/gb_proxy.c
parent62eaf54e7a4325bf2ddc3b568f10d51ba34472f0 (diff)
GPRS: Copy the content of the msgb instead of creating one that points to the other
Right now the memcpy with the data will copy data to itself as the new_msg->data and msg->data are the same due the previous copying of the header which included copying the list entry.. We allocate a message as big as the current one, then we have to set all pointers by looking of how far they are away from the msg->_data and add that to the new pointers. Also copy the OpenBSC/GPRS specific CB data, also do the same for calculating the offset to the data... At the end we should end up with a copy...
Diffstat (limited to 'openbsc/src/gprs/gb_proxy.c')
-rw-r--r--openbsc/src/gprs/gb_proxy.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 936b10227..a95929b91 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -122,16 +122,38 @@ static void peer_free(struct gbprox_peer *peer)
/* FIXME: this needs to go to libosmocore/msgb.c */
static struct msgb *msgb_copy(const struct msgb *msg, const char *name)
{
+ struct openbsc_msgb_cb *old_cb, *new_cb;
struct msgb *new_msg;
- new_msg = msgb_alloc_headroom(msg->data_len, NS_ALLOC_HEADROOM, name);
+ new_msg = msgb_alloc(msg->data_len, name);
if (!new_msg)
return NULL;
- /* copy header */
- memcpy(new_msg, msg, sizeof(*new_msg));
/* copy data */
- memcpy(new_msg->data, msg->data, new_msg->data_len);
+ memcpy(new_msg->_data, msg->_data, new_msg->data_len);
+
+ /* copy header */
+ new_msg->len = msg->len;
+ new_msg->data += msg->data - msg->_data;
+ new_msg->head += msg->head - msg->_data;
+ new_msg->tail += msg->tail - msg->_data;
+
+ new_msg->l1h = new_msg->_data + (msg->l1h - msg->_data);
+ new_msg->l2h = new_msg->_data + (msg->l2h - msg->_data);
+ new_msg->l3h = new_msg->_data + (msg->l3h - msg->_data);
+ new_msg->l4h = new_msg->_data + (msg->l4h - msg->_data);
+
+ /* copy GB specific data */
+ old_cb = OBSC_MSGB_CB(msg);
+ new_cb = OBSC_MSGB_CB(new_msg);
+
+ new_cb->bssgph = new_msg->_data + (old_cb->bssgph - msg->_data);
+ new_cb->llch = new_msg->_data + (old_cb->llch - msg->_data);
+
+ new_cb->bssgp_cell_id = old_cb->bssgp_cell_id;
+ new_cb->nsei = old_cb->nsei;
+ new_cb->bvci = old_cb->bvci;
+ new_cb->tlli = old_cb->tlli;
return new_msg;
}