From 8aa4c52d2e412eb92e27fbad58c3ac3697aefe15 Mon Sep 17 00:00:00 2001 From: Ivan Kluchnikov Date: Mon, 20 Feb 2012 15:15:12 +0400 Subject: [PATCH] Added segmentation of LLC PDUs into RLC data blocks. --- bssgp.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++----------- bssgp.h | 4 ++-- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/bssgp.cpp b/bssgp.cpp index dd773df4..696e194f 100644 --- a/bssgp.cpp +++ b/bssgp.cpp @@ -20,6 +20,7 @@ #include #include #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++; } diff --git a/bssgp.h b/bssgp.h index b8beea9f..1a6c1b1e 100644 --- a/bssgp.h +++ b/bssgp.h @@ -29,14 +29,14 @@ extern "C" { #include #include -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);