llc: Move all direct accesses to the frame into the llc structure

Add some todo items where we could add assertions now that I see
the constraints and invariants of this code.
diff --git a/src/llc.cpp b/src/llc.cpp
index f5daa1e..a4fd7af 100644
--- a/src/llc.cpp
+++ b/src/llc.cpp
@@ -22,8 +22,6 @@
 #include <tbf.h>
 #include <bts.h>
 
-#include <string.h>
-
 extern "C" {
 #include <osmocom/core/msgb.h>
 }
@@ -73,6 +71,7 @@
 
 void gprs_llc::update_frame(struct msgb *msg)
 {
+	/* TODO: assert that index is 0 now */
 	/* TODO: bounds check */
 	memcpy(frame, msg->data, msg->len);
 	length = msg->len;
diff --git a/src/llc.h b/src/llc.h
index 3144362..43c027e 100644
--- a/src/llc.h
+++ b/src/llc.h
@@ -19,6 +19,7 @@
 #pragma once
 
 #include <stdint.h>
+#include <string.h>
 
 #define LLC_MAX_LEN 1543
 
@@ -35,11 +36,25 @@
 
 	void update_frame(struct msgb *msg);
 	void put_frame(const uint8_t *data, size_t len);
+	void consume(uint8_t *data, size_t len);
 	void clear(BTS *bts);
 
+	uint16_t chunk_size() const;
+
 	uint8_t frame[LLC_MAX_LEN]; /* current DL or UL frame */
 	uint16_t index; /* current write/read position of frame */
 	uint16_t length; /* len of current DL LLC_frame, 0 == no frame */
 	struct llist_head queue; /* queued LLC DL data */
 };
 
+inline uint16_t gprs_llc::chunk_size() const
+{
+	return length - index;
+}
+
+inline void gprs_llc::consume(uint8_t *data, size_t len)
+{
+	/* copy and increment index */
+	memcpy(data, frame + index, len);
+	index += len;
+}
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 41aaf90..8803e54 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -1008,7 +1008,7 @@
 	delimiter = data; /* where next length header would be stored */
 	space = block_data - 3;
 	while (1) {
-		chunk = m_llc.length - m_llc.index;
+		chunk = m_llc.chunk_size();
 		/* if chunk will exceed block limit */
 		if (chunk > space) {
 			LOGP(DRLCMACDL, LOGL_DEBUG, "-- Chunk with length %d "
@@ -1018,9 +1018,7 @@
 			/* block is filled, so there is no extension */
 			*e_pointer |= 0x01;
 			/* fill only space */
-			memcpy(data, m_llc.frame + m_llc.index, space);
-			/* incement index */
-			m_llc.index += space;
+			m_llc.consume(data, space);
 			/* return data block as message */
 			break;
 		}
@@ -1037,7 +1035,7 @@
 			/* block is filled, so there is no extension */
 			*e_pointer |= 0x01;
 			/* fill space */
-			memcpy(data, m_llc.frame + m_llc.index, space);
+			m_llc.consume(data, space);
 			m_llc.reset();
 			/* final block */
 			rh->fbi = 1; /* we indicate final block */
@@ -1064,9 +1062,7 @@
 			li->li = 0; /* chunk fills the complete space */
 			// no need to set e_pointer nor increase delimiter
 			/* fill only space, which is 1 octet less than chunk */
-			memcpy(data, m_llc.frame + m_llc.index, space);
-			/* incement index */
-			m_llc.index += space;
+			m_llc.consume(data, space);
 			/* return data block as message */
 			break;
 		}
@@ -1086,8 +1082,8 @@
 		li->li = chunk; /* length of chunk */
 		e_pointer = delimiter; /* points to E of current delimiter */
 		delimiter++;
-		/* copy (rest of) LLC frame to space */
-		memcpy(data, m_llc.frame + m_llc.index, chunk);
+		/* copy (rest of) LLC frame to space and reset later */
+		m_llc.consume(data, chunk);
 		data += chunk;
 		space -= chunk;
 		LOGP(DRLCMACDL, LOGL_INFO, "Complete DL frame for %s"