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++;
}