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 <arpa/inet.h>
#include <Threads.h> #include <Threads.h>
#include "GPRSSocket.h" #include "GPRSSocket.h"
#include "gsm_rlcmac.h"
#include "bssgp.h" #include "bssgp.h"
// TODO: We should move this parameters to config file. // TODO: We should move this parameters to config file.
@ -39,7 +40,7 @@
#define NS_HDR_LEN 4 #define NS_HDR_LEN 4
#define MAX_LEN_PDU 100 #define MAX_LEN_PDU 100
#define IE_PDU 14 #define IE_PDU 14
#define BLOCK_DATA_LEN 16 #define BLOCK_DATA_LEN 19
#define BLOCK_LEN 23 #define BLOCK_LEN 23
@ -53,12 +54,44 @@ struct sgsn_instance *sgsn;
void *tall_bsc_ctx; void *tall_bsc_ctx;
// Send RLC data to OpenBTS. // 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); BitVector resultVector(BLOCK_LEN*8);
resultVector.unhex("2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); 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); 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 i = 0;
unsigned j = 0; unsigned j = 0;
unsigned pduIndex = 0; unsigned pduIndex = 0;
unsigned fbi = 0;
struct bssgp_ud_hdr *budh; struct bssgp_ud_hdr *budh;
/* If traffic is received on a BVC that is marked as blocked, the /* 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)); LOGP(DBSSGP, LOGL_NOTICE, "rx BSSGP TLLI=0x%08x \n", ntohl(budh->tlli));
for (i = 4; i < MAX_LEN_PDU; i++) 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) if(budh ->data[i] == IE_PDU)
{ {
pduIndex = i+2; 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++) 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]; pdu[dataIndex] = budh ->data[i];
dataIndex++; dataIndex++;
} }
DEBUGP(DBSSGP, "BSSGP Catch from SGSN=%u octets. Send it to OpenBTS.\n", 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; int blockDataLen = BLOCK_DATA_LEN;
numBlocks = dataIndex/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) if (i == numBlocks-1)
{ {
blockDataLen = ost; if (ost > 0)
{
blockDataLen = ost;
}
fbi = 1;
} }
endIndex = startIndex+blockDataLen; endIndex = startIndex + blockDataLen;
sendRLC(ntohl(budh->tlli), pdu, startIndex, endIndex); sendRLC(ntohl(budh->tlli), pdu, startIndex, endIndex, i, fbi);
startIndex += blockDataLen; startIndex += blockDataLen;
} }
} }
else else
{ {
sendRLC(ntohl(budh->tlli), pdu, 0, dataIndex); sendRLC(ntohl(budh->tlli), pdu, 0, dataIndex, 0, 1);
} }
break; break;
case BSSGP_PDUT_PAGING_PS: case BSSGP_PDUT_PAGING_PS:
@ -356,7 +395,7 @@ void RLCMACServer()
osmo_select_main(0); osmo_select_main(0);
if (i == 7) if (i == 7)
{ {
bssgp_tx_bvc_reset(bctx, nsvc, bvci, cause); bssgp_tx_bvc_reset(bctx, bvci, cause);
} }
i++; i++;
} }

View File

@ -29,14 +29,14 @@ extern "C" {
#include <openbsc/gprs_bssgp.h> #include <openbsc/gprs_bssgp.h>
#include <osmocom/core/application.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); 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); 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); int gprs_bssgp_bss_rx_ptp(struct msgb *msg, struct tlv_parsed *tp, struct bssgp_bvc_ctx *bctx);