Added segmentation of LLC PDUs into RLC data blocks.
diff --git a/bssgp.cpp b/bssgp.cpp
index dd773df..696e194 100644
--- a/bssgp.cpp
+++ b/bssgp.cpp
@@ -20,6 +20,7 @@
 #include <arpa/inet.h>
 #include <Threads.h>
 #include "GPRSSocket.h"
+#include "gsm_rlcmac.h"
 #include "bssgp.h"
 
 // TODO: We should move this parameters to config file.
@@ -39,7 +40,7 @@
 #define NS_HDR_LEN 4
 #define MAX_LEN_PDU 100
 #define IE_PDU 14
-#define BLOCK_DATA_LEN 16
+#define BLOCK_DATA_LEN 19
 
 #define BLOCK_LEN 23
 
@@ -53,12 +54,44 @@
 void *tall_bsc_ctx;
 
 // Send RLC data to OpenBTS.
-void sendRLC(uint32_t tlli, uint8_t *pdu, unsigned startIndex, unsigned endIndex)
+void sendRLC(uint32_t tlli, uint8_t *pdu, unsigned startIndex, unsigned endIndex, unsigned bsn, unsigned fbi)
 {
-	unsigned wp = 0;
+	unsigned spareLen = 0;
 	BitVector resultVector(BLOCK_LEN*8);
 	resultVector.unhex("2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b");
-	// TODO: Encode downlink RLC/MAC data block.
+	RlcMacDownlinkDataBlock_t * dataBlock = (RlcMacDownlinkDataBlock_t *)malloc(sizeof(RlcMacDownlinkDataBlock_t));
+	dataBlock->PAYLOAD_TYPE = 0;
+	dataBlock->RRBP = 0;
+	dataBlock->SP = 1;
+	dataBlock->USF = 1;
+	dataBlock->PR = 0;
+	dataBlock->TFI = 20;
+	dataBlock->FBI = fbi;
+	dataBlock->BSN = bsn;
+	if ((endIndex-startIndex) < 20)
+	{
+		dataBlock->E_1 = 0;
+		dataBlock->LENGTH_INDICATOR[0] = endIndex-startIndex;
+		dataBlock->M[0] = 0;
+		dataBlock->E[0] = 1;
+		spareLen = 19 - dataBlock->LENGTH_INDICATOR[0];
+	}
+	else
+	{
+		dataBlock->E_1 = 1; 
+	}
+	unsigned j = 0;
+	for(unsigned i = startIndex; i < endIndex; i++)
+	{
+		dataBlock->RLC_DATA[j] = pdu[i];
+		j++;
+	}
+	for(unsigned i = j; i < j + spareLen; i++)
+	{
+		dataBlock->RLC_DATA[i] = 0x2b;
+	}
+	encode_gsm_rlcmac_downlink_data(&resultVector, dataBlock);
+	free(dataBlock);
 	sendToOpenBTS(&resultVector);
 }
 
@@ -74,6 +107,7 @@
 	unsigned i = 0;
 	unsigned j = 0;
 	unsigned pduIndex = 0;
+	unsigned fbi = 0;
 	struct bssgp_ud_hdr *budh;
 
 	/* If traffic is received on a BVC that is marked as blocked, the
@@ -93,7 +127,7 @@
 		LOGP(DBSSGP, LOGL_NOTICE, "rx BSSGP TLLI=0x%08x \n", ntohl(budh->tlli));
 		for (i = 4; i < MAX_LEN_PDU; i++)
 		{
-			LOGP(DBSSGP, LOGL_NOTICE, "SERCH data = -0x%02x\n", budh ->data[i]);
+			//LOGP(DBSSGP, LOGL_NOTICE, "SERCH data = -0x%02x\n", budh ->data[i]);
 			if(budh ->data[i] == IE_PDU)
 			{
 				pduIndex = i+2;
@@ -102,12 +136,13 @@
 		}
 		for (i = pduIndex; i < pduIndex + (budh->data[pduIndex-1]&0x7f); i++)
 		{
-			LOGP(DBSSGP, LOGL_NOTICE, "-0x%02x\n", budh ->data[i]);
+			//LOGP(DBSSGP, LOGL_NOTICE, "-0x%02x\n", budh ->data[i]);
 			pdu[dataIndex] = budh ->data[i];
 			dataIndex++;
 		}
 		DEBUGP(DBSSGP, "BSSGP Catch from SGSN=%u octets. Send it to OpenBTS.\n", dataIndex);
-		if (dataIndex > BLOCK_DATA_LEN)
+		sendToGSMTAP(pdu,dataIndex);
+		if (dataIndex > BLOCK_DATA_LEN + 1)
 		{
 			int blockDataLen = BLOCK_DATA_LEN;
 			numBlocks = dataIndex/BLOCK_DATA_LEN;
@@ -122,16 +157,20 @@
 			{
 				if (i == numBlocks-1)
 				{
-					blockDataLen = ost;
+					if (ost > 0)
+					{
+						blockDataLen = ost;
+					}
+					fbi = 1;
 				}
-				endIndex = startIndex+blockDataLen;
-				sendRLC(ntohl(budh->tlli), pdu, startIndex, endIndex);
+				endIndex = startIndex + blockDataLen;
+				sendRLC(ntohl(budh->tlli), pdu, startIndex, endIndex, i, fbi);
 				startIndex += blockDataLen;
 			}
 		}
 		else
 		{
-			sendRLC(ntohl(budh->tlli), pdu,  0, dataIndex);
+			sendRLC(ntohl(budh->tlli), pdu, 0, dataIndex, 0, 1);
 		}
 		break;
 	case BSSGP_PDUT_PAGING_PS:
@@ -356,7 +395,7 @@
 		osmo_select_main(0);
 		if (i == 7)
 		{
-			bssgp_tx_bvc_reset(bctx, nsvc, bvci, cause);
+			bssgp_tx_bvc_reset(bctx, bvci, cause);
 		}
 		i++;
 	}