Improvement of TBF management.
Added functions for TBF allocation, establishment, data transfer and release management.
Modified TBF structure, added list for several LLC PDUs in one TBF.
Added function gprs_rlcmac_tx_llc_pdus() providing transmission of several LLC PDUs in one TBF to MS.
diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h
index eb651c6..7f9e3d7 100644
--- a/src/gprs_rlcmac.h
+++ b/src/gprs_rlcmac.h
@@ -32,10 +32,21 @@
 #define LLC_MAX_LEN 1543
 #define UL_RLC_DATA_BLOCK_LEN 23
 
+enum gprs_rlcmac_tbf_stage {
+	TBF_ESTABLISH,
+	TBF_DATA_TRANSFER,
+	TBF_RELEASE
+};
+
 enum gprs_rlcmac_tbf_state {
-	GPRS_RLCMAC_WAIT_DATA_SEQ_START,
-	GPRS_RLCMAC_WAIT_NEXT_DATA_BLOCK,
-	GPRS_RLCMAC_WAIT_NEXT_DATA_SEQ
+	WAIT_ESTABLISH,
+	CCCH_ESTABLISH,
+	PACCH_ESTABLISH,
+	FINISH_ESTABLISH,
+	WAIT_DATA_TRANSFER,
+	DATA_TRANSFER,
+	FINISH_DATA_TRANSFER,
+	RELEASE
 };
 
 enum gprs_rlcmac_tbf_direction {
@@ -43,12 +54,25 @@
 	GPRS_RLCMAC_UL_TBF
 };
 
+struct tbf_llc_pdu {
+	struct llist_head list;
+	uint8_t num;
+	uint8_t data[LLC_MAX_LEN];
+	uint16_t len;
+};
+
 struct gprs_rlcmac_tbf {
 	struct llist_head list;
 	enum gprs_rlcmac_tbf_state state;
+	enum gprs_rlcmac_tbf_stage stage;
 	enum gprs_rlcmac_tbf_direction direction;
+	struct gprs_rlcmac_tbf *next_tbf;
 	uint8_t tfi;
 	uint32_t tlli;
+	
+	struct llist_head llc_pdus;
+	struct tbf_llc_pdu llc_pdu;
+	uint8_t llc_pdu_list_len;
 	uint8_t rlc_data[LLC_MAX_LEN];
 	uint16_t data_index;
 	uint8_t bsn;
@@ -62,18 +86,6 @@
 	unsigned int num_fT_exp; /* number of consecutive fT expirations */
 };
 
-extern struct llist_head gprs_rlcmac_tbfs;
-
-int tfi_alloc();
-
-struct gprs_rlcmac_tbf *tbf_alloc(uint8_t tfi);
-
-static struct gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi);
-
-static struct gprs_rlcmac_tbf *tbf_by_tlli(uint8_t tlli);
-
-static void tbf_free(struct gprs_rlcmac_tbf *tbf);
-
 /* TS 44.060 Section 10.4.7 Table 10.4.7.1: Payload Type field */
 enum gprs_rlcmac_block_type {
 	GPRS_RLCMAC_DATA_BLOCK = 0x0,
@@ -82,6 +94,40 @@
 	GPRS_RLCMAC_RESERVED = 0x3
 };
 
+extern struct llist_head gprs_rlcmac_tbfs;
+
+int tfi_alloc();
+
+static struct gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi, gprs_rlcmac_tbf_direction dir);
+
+static struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, gprs_rlcmac_tbf_direction dir);
+
+static void tbf_free(struct gprs_rlcmac_tbf *tbf);
+
+static struct tbf_llc_pdu *tbf_llc_pdu_by_num(struct llist_head llc_pdus, uint8_t num);
+
+int tbf_add_llc_pdu(struct gprs_rlcmac_tbf *tbf, uint8_t *data, uint16_t llc_pdu_len);
+
+struct gprs_rlcmac_tbf *tbf_alloc(gprs_rlcmac_tbf_direction dir, uint32_t tlli = 0);
+
+int tbf_ul_establish(struct gprs_rlcmac_tbf *tbf, uint8_t ra, uint32_t Fn, uint16_t ta);
+
+int tbf_dl_establish(struct gprs_rlcmac_tbf *tbf, uint8_t *imsi = NULL);
+
+int tbf_ul_data_transfer(struct gprs_rlcmac_tbf *tbf, RlcMacUplinkDataBlock_t * ul_data_block);
+
+int tbf_dl_data_transfer(struct gprs_rlcmac_tbf *tbf, uint8_t *llc_pdu = NULL, uint16_t llc_pdu_len = 0);
+
+int tbf_ul_release(struct gprs_rlcmac_tbf *tbf);
+
+int tbf_dl_release(struct gprs_rlcmac_tbf *tbf);
+
+static void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, unsigned int seconds);
+
+static void tbf_gsm_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int fT, int frames);
+
+int write_immediate_assignment(bitvec * dest, uint8_t downlink, uint8_t ra, uint32_t fn, uint8_t ta, uint8_t tfi, uint32_t tlli = 0);
+
 void gprs_rlcmac_tx_ul_ack(uint8_t tfi, uint32_t tlli, RlcMacUplinkDataBlock_t * ul_data_block);
 
 void gprs_rlcmac_data_block_parse(gprs_rlcmac_tbf* tbf, RlcMacUplinkDataBlock_t * ul_data_block);
@@ -94,9 +140,7 @@
 
 int gprs_rlcmac_rcv_rach(uint8_t ra, uint32_t Fn, uint16_t ta);
 
-void gprs_rlcmac_tx_dl_data_block(uint32_t tlli, uint8_t tfi, uint8_t *pdu, int start_index, int end_index, uint8_t bsn, uint8_t fbi);
-
-int gprs_rlcmac_segment_llc_pdu(struct gprs_rlcmac_tbf *tbf);
+int gprs_rlcmac_tx_llc_pdus(struct gprs_rlcmac_tbf *tbf);
 
 void gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf);
 
@@ -104,5 +148,4 @@
 
 void gprs_rlcmac_packet_downlink_assignment(gprs_rlcmac_tbf *tbf);
 
-
 #endif // GPRS_RLCMAC_H