diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gprs_rlcmac.cpp | 25 | ||||
-rw-r--r-- | src/tbf.cpp | 33 | ||||
-rw-r--r-- | src/tbf.h | 1 |
3 files changed, 30 insertions, 29 deletions
diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index ea5ab4e2..0037e6d6 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -113,31 +113,6 @@ void debug_diagram(BTS *bts, int diag, const char *format, ...) } #endif -/* Send Uplink unit-data to SGSN. */ -int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf) -{ - uint8_t qos_profile[3]; - struct msgb *llc_pdu; - unsigned msg_len = NS_HDR_LEN + BSSGP_HDR_LEN + tbf->llc_index; - struct bssgp_bvc_ctx *bctx = gprs_bssgp_pcu_current_bctx(); - - LOGP(DBSSGP, LOGL_INFO, "LLC [PCU -> SGSN] %s len=%d\n", tbf_name(tbf), tbf->llc_index); - if (!bctx) { - LOGP(DBSSGP, LOGL_ERROR, "No bctx\n"); - return -EIO; - } - - llc_pdu = msgb_alloc_headroom(msg_len, msg_len,"llc_pdu"); - uint8_t *buf = msgb_push(llc_pdu, TL16V_GROSS_LEN(sizeof(uint8_t)*tbf->llc_index)); - tl16v_put(buf, BSSGP_IE_LLC_PDU, sizeof(uint8_t)*tbf->llc_index, tbf->llc_frame); - qos_profile[0] = QOS_PROFILE >> 16; - qos_profile[1] = QOS_PROFILE >> 8; - qos_profile[2] = QOS_PROFILE; - bssgp_tx_ul_ud(bctx, tbf->tlli(), qos_profile, llc_pdu); - - return 0; -} - int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len, const char *imsi) { diff --git a/src/tbf.cpp b/src/tbf.cpp index e571f703..60123884 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -892,8 +892,7 @@ int gprs_rlcmac_tbf::assemble_forward_llc(uint8_t *data, uint8_t len) /* send frame to SGSN */ LOGP(DRLCMACUL, LOGL_INFO, "%s complete UL frame len=%d\n", tbf_name(this) , this->llc_index); - gprs_rlcmac_tx_ul_ud(this); - this->llc_index = 0; /* reset frame space */ + snd_ul_ud(); /* also check if CV==0, because the frame may fill up the * block precisely, then it is also complete. normally the * frame would be extended into the next block with a 0-length @@ -903,8 +902,7 @@ int gprs_rlcmac_tbf::assemble_forward_llc(uint8_t *data, uint8_t len) LOGP(DRLCMACUL, LOGL_INFO, "%s complete UL frame " "that fits precisely in last block: " "len=%d\n", tbf_name(this), this->llc_index); - gprs_rlcmac_tx_ul_ud(this); - this->llc_index = 0; /* reset frame space */ + snd_ul_ud(); } } @@ -1844,6 +1842,33 @@ int gprs_rlcmac_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t len return 0; } +/* Send Uplink unit-data to SGSN. */ +int gprs_rlcmac_tbf::snd_ul_ud() +{ + uint8_t qos_profile[3]; + struct msgb *llc_pdu; + unsigned msg_len = NS_HDR_LEN + BSSGP_HDR_LEN + llc_index; + struct bssgp_bvc_ctx *bctx = gprs_bssgp_pcu_current_bctx(); + + LOGP(DBSSGP, LOGL_INFO, "LLC [PCU -> SGSN] %s len=%d\n", tbf_name(this), llc_index); + if (!bctx) { + LOGP(DBSSGP, LOGL_ERROR, "No bctx\n"); + llc_index = 0; /* reset frame space */ + return -EIO; + } + + llc_pdu = msgb_alloc_headroom(msg_len, msg_len,"llc_pdu"); + uint8_t *buf = msgb_push(llc_pdu, TL16V_GROSS_LEN(sizeof(uint8_t)*llc_index)); + tl16v_put(buf, BSSGP_IE_LLC_PDU, sizeof(uint8_t)*llc_index, llc_frame); + qos_profile[0] = QOS_PROFILE >> 16; + qos_profile[1] = QOS_PROFILE >> 8; + qos_profile[2] = QOS_PROFILE; + bssgp_tx_ul_ud(bctx, tlli(), qos_profile, llc_pdu); + + llc_index = 0; /* reset frame space */ + return 0; +} + const char *tbf_name(gprs_rlcmac_tbf *tbf) { static char buf[40]; @@ -105,6 +105,7 @@ struct gprs_rlcmac_tbf { struct msgb *create_ul_ass(uint32_t fn); struct msgb *create_ul_ack(uint32_t fn); int snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb); + int snd_ul_ud(); /* blocks were acked */ int rcv_data_block_acknowledged(const uint8_t *data, size_t len, int8_t rssi); |