Added segmentation of LLC PDUs into RLC data blocks.

This commit is contained in:
Ivan Kluchnikov 2012-02-20 15:15:12 +04:00
parent 92ac6379aa
commit 8aa4c52d2e
2 changed files with 53 additions and 14 deletions

View File

@ -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 @@ struct sgsn_instance *sgsn;
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 @@ int gprs_bssgp_bss_rx_ptp(struct msgb *msg, struct tlv_parsed *tp, struct bssgp_
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 @@ int gprs_bssgp_bss_rx_ptp(struct msgb *msg, struct tlv_parsed *tp, struct bssgp_
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 @@ int gprs_bssgp_bss_rx_ptp(struct msgb *msg, struct tlv_parsed *tp, struct bssgp_
}
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 @@ int gprs_bssgp_bss_rx_ptp(struct msgb *msg, struct tlv_parsed *tp, struct bssgp_
{
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 @@ void RLCMACServer()
osmo_select_main(0);
if (i == 7)
{
bssgp_tx_bvc_reset(bctx, nsvc, bvci, cause);
bssgp_tx_bvc_reset(bctx, bvci, cause);
}
i++;
}

View File

@ -29,14 +29,14 @@ extern "C" {
#include <openbsc/gprs_bssgp.h>
#include <osmocom/core/application.h>
int bssgp_tx_bvc_reset(struct bssgp_bvc_ctx *bctx, struct gprs_nsvc * nsvc, uint16_t bvci, uint8_t cause);
int bssgp_tx_bvc_reset(struct bssgp_bvc_ctx *bctx, uint16_t bvci, uint8_t cause);
int bssgp_tx_ul_ud(struct bssgp_bvc_ctx *bctx, uint32_t tlli, const uint8_t *qos_profile, struct msgb *llc_pdu);
struct bssgp_bvc_ctx *btsctx_alloc(uint16_t bvci, uint16_t nsei);
}
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);
int gprs_bssgp_bss_rx_ptp(struct msgb *msg, struct tlv_parsed *tp, struct bssgp_bvc_ctx *bctx);