Modified gprs_rlcmac_data_block_parse() function.
Changed the internal logic of the function. Fixed handling for case with several LLC PDU in one data block.
diff --git a/gprs_rlcmac.cpp b/gprs_rlcmac.cpp
index 2e0f991..26d6a8d 100644
--- a/gprs_rlcmac.cpp
+++ b/gprs_rlcmac.cpp
@@ -424,56 +424,86 @@
 
 void gprs_rlcmac_data_block_parse(gprs_rlcmac_tbf* tbf, RlcMacUplinkDataBlock_t * ul_data_block)
 {
-	unsigned block_data_len = 0;
-	unsigned data_octet_num = 0;
+	// 1. Count the number of octets in header and number of LLC PDU in uplink data block.
+	unsigned data_block_hdr_len = 3; // uplink data block header length: 3 mandatory octets
+	unsigned llc_pdu_num = 0; // number of LLC PDU in data block
+
+	
 	if (ul_data_block->E_1 == 0) // Extension octet follows immediately
 	{
-		block_data_len = ul_data_block->LENGTH_INDICATOR[0];
-		// New LLC PDU starts after the current LLC PDU and continues until
-		// the end of the RLC information field, no more extension octets.
-		if ((ul_data_block->M[0] == 1)&&(ul_data_block->E[0] == 1))
+		unsigned i = -1;
+		do
 		{
-			for (unsigned i = tbf->data_index;  i < tbf->data_index + block_data_len; i++)
+			i++;
+			data_block_hdr_len += 1;
+			llc_pdu_num++;
+			// New LLC PDU starts after the current LLC PDU and continues until
+			// the end of the RLC information field, no more extension octets.
+			if ((ul_data_block->M[i] == 1)&&(ul_data_block->E[i] == 1))
 			{
-				tbf->rlc_data[i] = ul_data_block->RLC_DATA[data_octet_num];
-				data_octet_num++;
+				llc_pdu_num++;
 			}
-			tbf->data_index += block_data_len;
-			gsmtap_send_llc(tbf->rlc_data, tbf->data_index);
-			gprs_rlcmac_tx_ul_ud(tbf);
-			tbf->data_index = 0;
-			block_data_len = 19 - block_data_len;
-			if(ul_data_block->TI == 1) // TLLI field is present
-				block_data_len -= 4;
-			for (unsigned i = tbf->data_index;  i < tbf->data_index + block_data_len; i++)
-			{
-				tbf->rlc_data[i] = ul_data_block->RLC_DATA[data_octet_num];
-				data_octet_num++;
-			}
-			tbf->data_index += block_data_len;
-			return;
-		}
+		} while(ul_data_block->E[i] == 0); // there is another extension octet, which delimits the new LLC PDU
 	}
 	else
 	{
-		block_data_len = 20; // RLC data length without 3 header octets.
-		if(ul_data_block->TI == 1) // TLLI field is present
+		llc_pdu_num++;
+	}
+	if(ul_data_block->TI == 1) // TLLI field is present
+	{
+		tbf->tlli = ul_data_block->TLLI;
+		data_block_hdr_len += 4; // TLLI length : 4 octets
+		if (ul_data_block->PI == 1) // PFI is present if TI field indicates presence of TLLI
 		{
-			tbf->tlli = ul_data_block->TLLI;
-			block_data_len -= 4; // TLLI length
-			if (ul_data_block->PI == 1) // PFI is present if TI field indicates presence of TLLI
+			data_block_hdr_len += 1; // PFI length : 1 octet
+		}
+	}
+	
+	// 2. Extract all LLC PDU from uplink data block and send them to SGSN.
+	unsigned llc_pdu_len = 0;
+	unsigned data_octet_num = 0;
+
+	for (unsigned num = 0; num < llc_pdu_num; num ++)
+	{
+		if (ul_data_block->E_1 == 0) // Extension octet follows immediately
+		{
+			llc_pdu_len = ul_data_block->LENGTH_INDICATOR[num];
+		}
+		else
+		{
+			llc_pdu_len = UL_RLC_DATA_BLOCK_LEN - data_block_hdr_len;
+		}
+		
+		for (unsigned i = tbf->data_index; i < tbf->data_index + llc_pdu_len; i++)
+		{
+			tbf->rlc_data[i] = ul_data_block->RLC_DATA[data_octet_num];
+			data_octet_num++;
+		}
+		tbf->data_index += llc_pdu_len;
+		
+		if (ul_data_block->E_1 == 0) // Extension octet follows immediately
+		{
+			// New LLC PDU starts after the current LLC PDU 
+			if (ul_data_block->M[num] == 1)
 			{
-				block_data_len -= 1; // PFI length
+				gsmtap_send_llc(tbf->rlc_data, tbf->data_index);
+				gprs_rlcmac_tx_ul_ud(tbf);
+				tbf->data_index = 0;
+				// New LLC PDU continues until the end of the RLC information field, no more extension octets.
+				if ((ul_data_block->E[num] == 1))
+				{
+					llc_pdu_len = UL_RLC_DATA_BLOCK_LEN - data_block_hdr_len - data_octet_num;
+					for (unsigned i = tbf->data_index; i < tbf->data_index + llc_pdu_len; i++)
+					{
+						tbf->rlc_data[i] = ul_data_block->RLC_DATA[data_octet_num];
+						data_octet_num++;
+					}
+					tbf->data_index += llc_pdu_len;
+					num++;
+				}
 			}
 		}
 	}
-
-	for (unsigned i = tbf->data_index;  i < tbf->data_index + block_data_len; i++)
-	{
-		tbf->rlc_data[i] = ul_data_block->RLC_DATA[data_octet_num];
-		data_octet_num++;
-	}
-	tbf->data_index += block_data_len;
 }
 
 /* Received Uplink RLC data block. */