This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
lynxis lazus gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/1753 remove pcu own bitvector implementation use osmocom bitvec which is exact the same, but use a pointer instead of a reference. Change-Id: Id8f797631d89aa12b6e48efb2dc153a3e2f059f7 --- M src/Makefile.am D src/bitvector.cpp D src/bitvector.h M src/bts.cpp A src/bts.cpp.orig M src/csn1.cpp M src/csn1.h M src/egprs_rlc_compression.cpp M src/encoding.cpp M src/gprs_bssgp_pcu.cpp M src/gprs_rlcmac.cpp M src/gprs_rlcmac.h M src/gsm_rlcmac.cpp M src/pcu_main.cpp M src/tbf.cpp M src/tbf_ul.cpp M tests/rlcmac/RLCMACTest.cpp M tests/tbf/TbfTest.cpp M tests/types/TypesTest.cpp 19 files changed, 2,222 insertions(+), 644 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/53/1753/1 diff --git a/src/Makefile.am b/src/Makefile.am index 7cc239b..97de06d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,7 +46,6 @@ gprs_ms.cpp \ gprs_ms_storage.cpp \ gsm_timer.cpp \ - bitvector.cpp \ pcu_l1_if.cpp \ pcu_vty.c \ pcu_vty_functions.cpp \ @@ -80,7 +79,6 @@ gprs_ms_storage.h \ pcu_l1_if.h \ gsm_timer.h \ - bitvector.h \ pcu_vty.h \ pcu_vty_functions.h \ tbf.h \ diff --git a/src/bitvector.cpp b/src/bitvector.cpp deleted file mode 100644 index dcb3baf..0000000 --- a/src/bitvector.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* bitvector.cpp - * - * Copyright (C) 2012 Ivan Klyuchnikov - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*! \addtogroup bitvector - * @{ - */ - -/*! \file bitvector.cpp - * \brief Additional functions for Osmocom bit vector abstraction. - */ - -#include <bitvector.h> -extern "C" { -#include <osmocom/core/talloc.h> -} - -void *bv_tall_ctx; - -struct bitvec *bitvec_alloc(unsigned size) -{ - struct bitvec *bv = talloc_zero(bv_tall_ctx, struct bitvec); - bv->data_len = size; - bv->cur_bit = 0; - bv->data = talloc_zero_array(bv_tall_ctx, uint8_t, size); - return bv; -} - -void bitvec_free(struct bitvec *bv) -{ - talloc_free(bv->data); - talloc_free(bv); -} - -unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer) -{ - unsigned int i = 0; - for (i = 0; i < bv->data_len; i++) - { - buffer[i] = bv->data[i]; - } - return i; -} - -unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer) -{ - unsigned int i = 0; - for (i = 0; i < bv->data_len; i++) - { - bv->data[i] = buffer[i]; - } - return i; -} - - -int bitvec_unhex(struct bitvec *bv, const char* src) -{ - unsigned val; - unsigned write_index = 0; - unsigned digits = bv->data_len*2; - for (unsigned i=0; i<digits; i++) { - if (sscanf(src+i, "%1x", &val) < 1) { - return 1; - } - bitvec_write_field(bv, write_index,val, 4); - } - return 0; -} - -uint64_t bitvec_read_field(struct bitvec *bv, unsigned& read_index, unsigned len) -{ - unsigned int i; - uint64_t ui = 0; - bv->cur_bit = read_index; - - for (i = 0; i < len; i++) { - int bit = bitvec_get_bit_pos((const struct bitvec *)bv, bv->cur_bit); - if (bit < 0) - return bit; - if (bit) - ui |= ((uint64_t)1 << (len - i - 1)); - bv->cur_bit++; - } - read_index += len; - return ui; -} - - -int bitvec_write_field_lh(struct bitvec *bv, unsigned& write_index, - uint64_t val, unsigned len) -{ - unsigned int i; - int rc; - bv->cur_bit = write_index; - for (i = 0; i < len; i++) { - bit_value bit = L; - if (val & ((uint64_t)1 << (len - i - 1))) - bit = H; - rc = bitvec_set_bit(bv, bit); - if (rc) - return rc; - } - write_index += len; - return 0; -} diff --git a/src/bitvector.h b/src/bitvector.h deleted file mode 100644 index 246824d..0000000 --- a/src/bitvector.h +++ /dev/null @@ -1,52 +0,0 @@ -/* bitvector.h - * - * Copyright (C) 2012 Ivan Klyuchnikov - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef BITVECTOR_H -#define BITVECTOR_H - -/*! \defgroup bitvector Bit vectors - * @{ - */ - -/*! \file bitvector.h - * \brief Additional functions for Osmocom bit vector abstraction. - */ - -extern "C" { -#include <osmocom/core/bitvec.h> -} - -struct bitvec *bitvec_alloc(unsigned size); -void bitvec_free(struct bitvec *bv); -int bitvec_unhex(struct bitvec *bv, const char* src); -unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer); -unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer); -uint64_t bitvec_read_field(struct bitvec *bv, unsigned& read_index, unsigned len); -int bitvec_write_field_lh(struct bitvec *bv, unsigned& write_index, uint64_t val, unsigned len); - - -static inline int bitvec_write_field(struct bitvec *bv, unsigned& write_index, uint64_t val, unsigned len) -{ - /* Call the libosmocore variant */ - return ::bitvec_write_field(bv, &write_index, val, len); -} - -/*! }@ */ - -#endif // BITVECTOR_H diff --git a/src/bts.cpp b/src/bts.cpp index 21e9d96..e857380 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -618,7 +618,7 @@ tsc = tbf->tsc(); } } - bitvec *immediate_assignment = bitvec_alloc(22) /* without plen */; + bitvec *immediate_assignment = bitvec_alloc(22, tall_pcu_ctx) /* without plen */; bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); @@ -758,7 +758,7 @@ unsigned int ts = tbf->first_ts; LOGP(DRLCMAC, LOGL_INFO, "TX: START %s Immediate Assignment Downlink (PCH)\n", tbf_name(tbf)); - bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */ + bitvec *immediate_assignment = bitvec_alloc(22, tall_pcu_ctx); /* without plen */ bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); /* use request reference that has maximum distance to current time, * so the assignment will not conflict with possible RACH requests. */ @@ -856,7 +856,7 @@ talloc_free(pag); return NULL; } - bitvec *pag_vec = bitvec_alloc(23); + bitvec *pag_vec = bitvec_alloc(23, tall_pcu_ctx); if (!pag_vec) { msgb_free(msg); talloc_free(pag); @@ -1577,7 +1577,7 @@ rc = rcv_data_block(data, fn, meas, cs); break; case GPRS_RLCMAC_CONTROL_BLOCK: - block = bitvec_alloc(len); + block = bitvec_alloc(len, tall_pcu_ctx); if (!block) return -ENOMEM; bitvec_unpack(block, data); diff --git a/src/bts.cpp.orig b/src/bts.cpp.orig new file mode 100644 index 0000000..08ea05d --- /dev/null +++ b/src/bts.cpp.orig @@ -0,0 +1,1748 @@ +/* + * Copyright (C) 2013 by Holger Hans Peter Freyther + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <bts.h> +#include <poll_controller.h> +#include <tbf.h> +#include <encoding.h> +#include <decoding.h> +#include <rlc.h> +#include <pcu_l1_if.h> + +#include <gprs_rlcmac.h> +#include <gprs_debug.h> + +extern "C" { + #include <osmocom/core/talloc.h> + #include <osmocom/core/msgb.h> + #include <osmocom/core/stats.h> + #include <osmocom/gsm/protocol/gsm_04_08.h> +} + +#include <arpa/inet.h> + +#include <errno.h> +#include <string.h> + +extern void *tall_pcu_ctx; + +static BTS s_bts; + +/** + * For gcc-4.4 compat do not use extended initializer list but keep the + * order from the enum here. Once we support GCC4.7 and up we can change + * the code below. + */ +static const struct rate_ctr_desc bts_ctr_description[] = { + { "tbf.dl.alloc", "TBF DL Allocated "}, + { "tbf.dl.freed", "TBF DL Freed "}, + { "tbf.dl.aborted", "TBF DL Aborted "}, + { "tbf.ul.alloc", "TBF UL Allocated "}, + { "tbf.ul.freed", "TBF UL Freed "}, + { "tbf.ul.aborted", "TBF UL Aborted "}, + { "tbf.reused", "TBF Reused "}, + { "tbf.alloc.algo-a", "TBF Alloc Algo A "}, + { "tbf.alloc.algo-b", "TBF Alloc Algo B "}, + { "tbf.failed.egprs-only", "TBF Failed EGPRS-only"}, + { "rlc.sent", "RLC Sent "}, + { "rlc.resent", "RLC Resent "}, + { "rlc.restarted", "RLC Restarted "}, + { "rlc.stalled", "RLC Stalled "}, + { "rlc.nacked", "RLC Nacked "}, + { "rlc.final_block_resent", "RLC Final Blk resent "}, + { "rlc.ass.timedout", "RLC Assign Timeout "}, + { "rlc.ass.failed", "RLC Assign Failed "}, + { "rlc.ack.timedout", "RLC Ack Timeout "}, + { "rlc.ack.failed", "RLC Ack Failed "}, + { "rlc.rel.timedout", "RLC Release Timeout "}, + { "rlc.late-block", "RLC Late Block "}, + { "rlc.sent-dummy", "RLC Sent Dummy "}, + { "rlc.sent-control", "RLC Sent Control "}, + { "rlc.dl_bytes", "RLC DL Bytes "}, + { "rlc.dl_payload_bytes", "RLC DL Payload Bytes "}, + { "rlc.ul_bytes", "RLC UL Bytes "}, + { "rlc.ul_payload_bytes", "RLC UL Payload Bytes "}, + { "decode.errors", "Decode Errors "}, + { "sba.allocated", "SBA Allocated "}, + { "sba.freed", "SBA Freed "}, + { "sba.timedout", "SBA Timeout "}, + { "llc.timeout", "Timedout Frames "}, + { "llc.dropped", "Dropped Frames "}, + { "llc.scheduled", "Scheduled Frames "}, + { "llc.dl_bytes", "RLC encapsulated PDUs"}, + { "llc.ul_bytes", "full PDUs received "}, + { "rach.requests", "RACH requests "}, + { "11bit_rach.requests", "11BIT_RACH requests "}, + { "spb.uplink_first_segment", "First seg of UL SPB "}, + { "spb.uplink_second_segment", "Second seg of UL SPB "}, + { "spb.downlink_first_segment", "First seg of DL SPB "}, + { "spb.downlink_second_segment","Second seg of DL SPB "}, + { "immediate.assignment_UL", "Immediate Assign UL "}, + { "immediate.assignment_rej", "Immediate Assign Rej "}, + { "immediate.assignment_DL", "Immediate Assign DL "}, + { "channel.request_description","Channel Request Desc "}, + { "pkt.ul_assignment", "Packet UL Assignment "}, + { "pkt.access_reject", "Packet Access Reject "}, + { "pkt.dl_assignment", "Packet DL Assignment "}, + { "ul.control", "UL control Block "}, + { "ul.assignment_poll_timeout", "UL Assign Timeout "}, + { "ul.assignment_failed", "UL Assign Failed "}, + { "dl.assignment_timeout", "DL Assign Timeout "}, + { "dl.assignment_failed", "DL Assign Failed "}, + { "pkt.ul_ack_nack_timeout", "PUAN Poll Timeout "}, + { "pkt.ul_ack_nack_failed", "PUAN poll Failed "}, + { "pkt.dl_ack_nack_timeout", "PDAN poll Timeout "}, + { "pkt.dl_ack_nack_failed", "PDAN poll Failed "}, + { "gprs.downlink_cs1", "CS1 downlink "}, + { "gprs.downlink_cs2", "CS2 downlink "}, + { "gprs.downlink_cs3", "CS3 downlink "}, + { "gprs.downlink_cs4", "CS4 downlink "}, + { "egprs.downlink_mcs1", "MCS1 downlink "}, + { "egprs.downlink_mcs2", "MCS2 downlink "}, + { "egprs.downlink_mcs3", "MCS3 downlink "}, + { "egprs.downlink_mcs4", "MCS4 downlink "}, + { "egprs.downlink_mcs5", "MCS5 downlink "}, + { "egprs.downlink_mcs6", "MCS6 downlink "}, + { "egprs.downlink_mcs7", "MCS7 downlink "}, + { "egprs.downlink_mcs8", "MCS8 downlink "}, + { "egprs.downlink_mcs9", "MCS9 downlink "}, + { "gprs.uplink_cs1", "CS1 Uplink "}, + { "gprs.uplink_cs2", "CS2 Uplink "}, + { "gprs.uplink_cs3", "CS3 Uplink "}, + { "gprs.uplink_cs4", "CS4 Uplink "}, + { "egprs.uplink_mcs1", "MCS1 Uplink "}, + { "egprs.uplink_mcs2", "MCS2 Uplink "}, + { "egprs.uplink_mcs3", "MCS3 Uplink "}, + { "egprs.uplink_mcs4", "MCS4 Uplink "}, + { "egprs.uplink_mcs5", "MCS5 Uplink "}, + { "egprs.uplink_mcs6", "MCS6 Uplink "}, + { "egprs.uplink_mcs7", "MCS7 Uplink "}, + { "egprs.uplink_mcs8", "MCS8 Uplink "}, + { "egprs.uplink_mcs9", "MCS9 Uplink "}, +}; + +static const struct rate_ctr_group_desc bts_ctrg_desc = { + "bts", + "BTS Statistics", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(bts_ctr_description), + bts_ctr_description, +}; + +static const struct osmo_stat_item_desc bts_stat_item_description[] = { + { "ms.present", "MS Present ", + OSMO_STAT_ITEM_NO_UNIT, 4, 0}, +}; + +static const struct osmo_stat_item_group_desc bts_statg_desc = { + "bts", + "BTS Statistics", + OSMO_STATS_CLASS_GLOBAL, + ARRAY_SIZE(bts_stat_item_description), + bts_stat_item_description, +}; + +BTS* BTS::main_bts() +{ + return &s_bts; +} + +struct gprs_rlcmac_bts *BTS::bts_data() +{ + return &m_bts; +} + +struct gprs_rlcmac_bts *bts_main_data() +{ + return BTS::main_bts()->bts_data(); +} + +struct rate_ctr_group *bts_main_data_stats() +{ + return BTS::main_bts()->rate_counters(); +} + +BTS::BTS() + : m_cur_fn(0) + , m_cur_blk_fn(-1) + , m_pollController(*this) + , m_sba(*this) + , m_ms_store(this) +{ + memset(&m_bts, 0, sizeof(m_bts)); + m_bts.bts = this; + + /* initialize back pointers */ + for (size_t trx_no = 0; trx_no < ARRAY_SIZE(m_bts.trx); ++trx_no) { + struct gprs_rlcmac_trx *trx = &m_bts.trx[trx_no]; + trx->trx_no = trx_no; + trx->bts = this; + + for (size_t ts_no = 0; ts_no < ARRAY_SIZE(trx->pdch); ++ts_no) { + struct gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no]; + pdch->ts_no = ts_no; + pdch->trx = trx; + } + } + + m_ratectrs = rate_ctr_group_alloc(tall_pcu_ctx, &bts_ctrg_desc, 0); + m_statg = osmo_stat_item_group_alloc(tall_pcu_ctx, &bts_statg_desc, 0); +} + +BTS::~BTS() +{ + /* this can cause counter updates and must not be left to the + * m_ms_store's destructor */ + m_ms_store.cleanup(); + + rate_ctr_group_free(m_ratectrs); + osmo_stat_item_group_free(m_statg); +} + + +void BTS::set_current_frame_number(int fn) +{ + /* The UL frame numbers lag 3 behind the DL frames and the data + * indication is only sent after all 4 frames of the block have been + * received. Sometimes there is an idle frame between the end of one + * and start of another frame (every 3 blocks). So the timeout should + * definitely be there if we're more than 8 frames past poll_fn. Let's + * stay on the safe side and say 13 or more. An additional delay can + * happen due to the block processing time in the DSP, so the delay of + * decoded blocks relative to the timing clock can be much larger. + * Values up to 50 frames have been observed under load. */ + const static int max_delay = 60; + + m_cur_fn = fn; + m_pollController.expireTimedout(m_cur_fn, max_delay); +} + +void BTS::set_current_block_frame_number(int fn, unsigned max_delay) +{ + int delay = 0; + const int late_block_delay_thresh = 13; + const int fn_update_ok_min_delay = -500; + const int fn_update_ok_max_delay = 0; + + /* frame numbers in the received blocks are assumed to be strongly + * monotonic. */ + if (m_cur_blk_fn >= 0) { + int delta = (fn + 2715648 * 3 / 2 - m_cur_blk_fn) % 2715648 - 2715648/2; + if (delta <= 0) + return; + } + + /* Check block delay vs. the current frame number */ + if (current_frame_number() != 0) + delay = (fn + 2715648 * 3 / 2 - current_frame_number()) % 2715648 + - 2715648/2; + if (delay <= -late_block_delay_thresh) { + LOGP(DRLCMAC, LOGL_NOTICE, + "Late RLC block, FN delta: %d FN: %d curFN: %d\n", + delay, fn, current_frame_number()); + rlc_late_block(); + } + + m_cur_blk_fn = fn; + if (delay < fn_update_ok_min_delay || delay > fn_update_ok_max_delay || + current_frame_number() == 0) + m_cur_fn = fn; + + m_pollController.expireTimedout(fn, max_delay); +} + +int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv) +{ + uint8_t l, trx, ts, any_tbf = 0; + struct gprs_rlcmac_tbf *tbf; + LListHead<gprs_rlcmac_tbf> *pos; + struct gprs_rlcmac_paging *pag; + uint8_t slot_mask[8]; + int8_t first_ts; /* must be signed */ + + LListHead<gprs_rlcmac_tbf> *tbfs_lists[] = { + &m_ul_tbfs, + &m_dl_tbfs, + NULL + }; + + + LOGP(DRLCMAC, LOGL_INFO, "Add RR paging: chan-needed=%d MI=%s\n", + chan_needed, osmo_hexdump(identity_lv + 1, identity_lv[0])); + + /* collect slots to page + * Mark slots for every TBF, but only mark one of it. + * Mark only the first slot found. + * Don't mark, if TBF uses a different slot that is already marked. */ + memset(slot_mask, 0, sizeof(slot_mask)); + for (l = 0; tbfs_lists[l]; l++) { + llist_for_each(pos, tbfs_lists[l]) { + tbf = pos->entry(); + first_ts = -1; + for (ts = 0; ts < 8; ts++) { + if (tbf->pdch[ts]) { + /* remember the first slot found */ + if (first_ts < 0) + first_ts = ts; + /* break, if we already marked a slot */ + if ((slot_mask[tbf->trx->trx_no] & (1 << ts))) + break; + } + } + /* mark first slot found, if none is marked already */ + if (ts == 8 && first_ts >= 0) { + LOGP(DRLCMAC, LOGL_DEBUG, "- %s uses " + "TRX=%d TS=%d, so we mark\n", + tbf_name(tbf), + tbf->trx->trx_no, first_ts); + slot_mask[tbf->trx->trx_no] |= (1 << first_ts); + } else + LOGP(DRLCMAC, LOGL_DEBUG, "- %s uses " + "already marked TRX=%d TS=%d\n", + tbf_name(tbf), + tbf->trx->trx_no, ts); + } + } + + /* Now we have a list of marked slots. Every TBF uses at least one + * of these slots. */ + + /* schedule paging to all marked slots */ + for (trx = 0; trx < 8; trx++) { + if (slot_mask[trx] == 0) + continue; + for (ts = 0; ts < 8; ts++) { + if ((slot_mask[trx] & (1 << ts))) { + /* schedule */ + pag = talloc_zero(tall_pcu_ctx, + struct gprs_rlcmac_paging); + if (!pag) + return -ENOMEM; + pag->chan_needed = chan_needed; + memcpy(pag->identity_lv, identity_lv, + identity_lv[0] + 1); + m_bts.trx[trx].pdch[ts].add_paging(pag); + LOGP(DRLCMAC, LOGL_INFO, "Paging on PACCH of " + "TRX=%d TS=%d\n", trx, ts); + any_tbf = 1; + } + } + } + + if (!any_tbf) + LOGP(DRLCMAC, LOGL_INFO, "No paging, because no TBF\n"); + + return 0; +} + +gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) +{ + struct gprs_rlcmac_dl_tbf *tbf; + LListHead<gprs_rlcmac_tbf> *pos; + + /* only one TBF can poll on specific TS/FN, because scheduler can only + * schedule one downlink control block (with polling) at a FN per TS */ + llist_for_each(pos, &m_dl_tbfs) { + tbf = as_dl_tbf(pos->entry()); + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx->trx_no == trx + && tbf->poll_ts == ts) { + return tbf; + } + } + return NULL; +} +gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) +{ + struct gprs_rlcmac_ul_tbf *tbf; + LListHead<gprs_rlcmac_tbf> *pos; + + /* only one TBF can poll on specific TS/FN, because scheduler can only + * schedule one downlink control block (with polling) at a FN per TS */ + llist_for_each(pos, &m_ul_tbfs) { + tbf = as_ul_tbf(pos->entry()); + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx->trx_no == trx + && tbf->poll_ts == ts) { + return tbf; + } + } + return NULL; +} + +/* lookup downlink TBF Entity (by TFI) */ +gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts) +{ + if (trx >= 8 || ts >= 8) + return NULL; + + return m_bts.trx[trx].pdch[ts].dl_tbf_by_tfi(tfi); +} + +/* lookup uplink TBF Entity (by TFI) */ +gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_tfi(uint8_t tfi, uint8_t trx, uint8_t ts) +{ + if (trx >= 8 || ts >= 8) + return NULL; + + return m_bts.trx[trx].pdch[ts].ul_tbf_by_tfi(tfi); +} + +/* + * Search for free TFI and return TFI, TRX. + * This method returns the first TFI that is currently not used in any PDCH of + * a TRX. The first TRX that contains such an TFI is returned. Negative values + * indicate errors. + */ +int BTS::tfi_find_free(enum gprs_rlcmac_tbf_direction dir, + uint8_t *_trx, int8_t use_trx) +{ + struct gprs_rlcmac_pdch *pdch; + uint32_t free_tfis; + bool has_pdch = false; + uint8_t trx_from, trx_to, trx, ts, tfi; + + if (use_trx >= 0 && use_trx < 8) + trx_from = trx_to = use_trx; + else { + trx_from = 0; + trx_to = 7; + } + + /* find a TFI that is unused on all PDCH */ + for (trx = trx_from; trx <= trx_to; trx++) { + bool trx_has_pdch = false; + + free_tfis = 0xffffffff; + + for (ts = 0; ts < 8; ts++) { + pdch = &m_bts.trx[trx].pdch[ts]; + if (!pdch->is_enabled()) + continue; + free_tfis &= ~pdch->assigned_tfi(dir); + trx_has_pdch = true; + has_pdch = true; + } + if (trx_has_pdch && free_tfis) + break; + + free_tfis = 0; + } + if (!has_pdch) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH available.\n"); + return -EINVAL; + } + + if (!free_tfis) { + LOGP(DRLCMAC, LOGL_NOTICE, "No TFI available.\n"); + return -EBUSY; + } + + + LOGP(DRLCMAC, LOGL_DEBUG, + "Searching for first unallocated TFI: TRX=%d\n", trx); + + /* find the first */ + for (tfi = 0; tfi < 32; tfi++) { + if (free_tfis & 1 << tfi) + break; + } + + OSMO_ASSERT(tfi < 32); + + LOGP(DRLCMAC, LOGL_DEBUG, " Found TFI=%d.\n", tfi); + *_trx = trx; + return tfi; +} + +int BTS::rcv_imm_ass_cnf(const uint8_t *data, uint32_t fn) +{ + struct gprs_rlcmac_dl_tbf *dl_tbf = NULL; + uint8_t plen; + uint32_t tlli; + GprsMs *ms; + + /* move to IA Rest Octets */ + plen = data[0] >> 2; + data += 1 + plen; + + if ((*data & 0xf0) != 0xd0) { + LOGP(DRLCMAC, LOGL_ERROR, "Got IMM.ASS confirm, but rest " + "octets do not start with bit sequence 'HH01' " + "(Packet Downlink Assignment)\n"); + return -EINVAL; + } + + /* get TLLI from downlink assignment */ + tlli = (*data++) << 28; + tlli |= (*data++) << 20; + tlli |= (*data++) << 12; + tlli |= (*data++) << 4; + tlli |= (*data++) >> 4; + + ms = ms_by_tlli(tlli); + if (ms) + dl_tbf = ms->dl_tbf(); + if (!dl_tbf) { + LOGP(DRLCMAC, LOGL_ERROR, "Got IMM.ASS confirm, but TLLI=%08x " + "does not exit\n", tlli); + return -EINVAL; + } + + LOGP(DRLCMAC, LOGL_DEBUG, "Got IMM.ASS confirm for TLLI=%08x\n", tlli); + + if (dl_tbf->m_wait_confirm) + tbf_timer_start(dl_tbf, 1, Tassign_agch); + + return 0; +} + +int BTS::rcv_imm_ass_cnf_dt(uint32_t tlli, uint32_t fn) +{ + GprsMs *ms; + struct gprs_rlcmac_dl_tbf *dl_tbf = NULL; + + ms = ms_by_tlli(tlli); + if (ms) + dl_tbf = ms->dl_tbf(); + if (!dl_tbf) { + LOGP(DRLCMAC, LOGL_ERROR, "Got IMM.ASS confirm, but TLLI=%08x " + "does not exit\n", tlli); + return -EINVAL; + } + + LOGP(DRLCMAC, LOGL_DEBUG, "Got IMM.ASS confirm for TLLI=%08x\n", tlli); + + if (dl_tbf->m_wait_confirm) + tbf_timer_start(dl_tbf, 1, Tassign_agch); + + return 0; +} + +int BTS::rcv_rach(uint16_t ra, uint32_t Fn, int16_t qta, uint8_t is_11bit, + enum ph_burst_type burst_type) +{ + struct gprs_rlcmac_ul_tbf *tbf = NULL; + uint8_t trx_no, ts_no = 0; + uint8_t sb = 0; + uint32_t sb_fn = 0; + int rc = 0; + int plen; + uint8_t usf = 7; + uint8_t tsc = 0, ta = qta2ta(qta); + uint16_t ms_class = 0; + uint16_t priority = 0; + bool failure = false; + + rach_frame(); + + /* Santizize frame number */ + Fn = Fn % 42432; + + /* Restore the full frame number + * (See also 3GPP TS 44.018, section 10.5.2.38) */ + Fn = Fn + m_cur_fn - m_cur_fn % 42432; + + if (is_11bit) + rach_frame_11bit(); + + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF on RACH, " + "so we provide one \n" + "ra=0x%02x Fn=%u qta=%d is_11bit=%d:\n", ra, Fn, qta, is_11bit); + + sb = is_single_block(ra, burst_type, is_11bit, &ms_class, &priority); + + if (sb) { + rc = sba()->alloc(&trx_no, &ts_no, &sb_fn, ta); + if (rc < 0) { + failure = true; + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource for " + "single block allocation." + "sending Immediate " + "Assignment Uplink (AGCH) reject\n"); + } else { + tsc = m_bts.trx[trx_no].pdch[ts_no].tsc; + + LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] RACH " + " qbit-ta=%d ra=0x%02x, Fn=%d (%d,%d,%d)," + " SBFn=%d\n", + qta, ra, + Fn, (Fn / (26 * 51)) % 32, Fn % 51, Fn % 26, + sb_fn); + LOGP(DRLCMAC, LOGL_INFO, "TX: Immediate Assignment " + "Uplink (AGCH)\n"); + } + } else { + // Create new TBF + #warning "Copy and paste with other routines.." + + if (is_11bit) { + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, + ms_class, 1); + } else { + /* set class to 0, since we don't know the multislot + * class yet */ + tbf = tbf_alloc_ul_tbf(&m_bts, NULL, -1, 0, 0, 1); + } + + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource sending " + "Immediate Assignment Uplink (AGCH) " + "reject\n"); + rc = -EBUSY; + failure = true; + } else { + tbf->set_ta(ta); + tbf->set_state(GPRS_RLCMAC_FLOW); + tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH); + tbf_timer_start(tbf, 3169, m_bts.t3169, 0); + LOGP(DRLCMAC, LOGL_DEBUG, "%s [UPLINK] START\n", + tbf_name(tbf)); + LOGP(DRLCMAC, LOGL_DEBUG, "%s RX: [PCU <- BTS] RACH " + "qbit-ta=%d ra=0x%02x, Fn=%d " + " (%d,%d,%d)\n", + tbf_name(tbf), + qta, ra, Fn, (Fn / (26 * 51)) % 32, + Fn % 51, Fn % 26); + LOGP(DRLCMAC, LOGL_INFO, "%s TX: START Immediate " + "Assignment Uplink (AGCH)\n", + tbf_name(tbf)); + trx_no = tbf->trx->trx_no; + ts_no = tbf->first_ts; + usf = tbf->m_usf[ts_no]; + tsc = tbf->tsc(); + } + } + bitvec *immediate_assignment = bitvec_alloc(22) /* without plen */; + bitvec_unhex(immediate_assignment, + "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); + + + if (failure) { + plen = Encoding::write_immediate_assignment_reject( + immediate_assignment, ra, Fn, + burst_type); + immediate_assignment_reject(); + } + else { + LOGP(DRLCMAC, LOGL_DEBUG, + " - TRX=%d (%d) TS=%d TA=%d TSC=%d TFI=%d USF=%d\n", + trx_no, m_bts.trx[trx_no].arfcn, ts_no, ta, tsc, + tbf ? tbf->tfi() : -1, usf); + + plen = Encoding::write_immediate_assignment( + tbf, immediate_assignment, 0, ra, Fn, ta, + m_bts.trx[trx_no].arfcn, ts_no, tsc, usf, 0, sb_fn, + m_bts.alpha, m_bts.gamma, -1, burst_type, sb); + } + + if (plen >= 0) { + immediate_assignment_ul_tbf(); + pcu_l1if_tx_agch(immediate_assignment, plen); + } + + bitvec_free(immediate_assignment); + + return rc; +} + +uint8_t BTS::is_single_block(uint16_t ra, enum ph_burst_type burst_type, + uint8_t is_11bit, uint16_t *ms_class, uint16_t *priority) +{ + uint8_t sb = 0, val = 0; + + if (!is_11bit && (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase " + "access\n"); + sb = 1; + } + + } else if (is_11bit && + ((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || + (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { + + val = !!(ra & (1 << 10)); + + if (!val) { + if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH " + "received. MS requests single phase " + "access but we force two phase " + "access\n"); + sb = 1; + } else { + sb = 0; + *ms_class = (ra & 0x3e0) >> 5; + *priority = (ra & 0x18) >> 3; + } + + } else { + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS 11 bit RACH received." + "MS requests single block allocation\n"); + sb = 1; + } + + } else if (is_11bit && + (burst_type == GSM_L1_BURST_TYPE_ACCESS_0)) { + LOGP(DRLCMAC, LOGL_ERROR, + "Error: GPRS 11 bit RACH not supported\n"); + + } else if (burst_type == GSM_L1_BURST_TYPE_NONE) { + LOGP(DRLCMAC, LOGL_DEBUG, "pcu has not received burst type " + "from bts \n"); + + if ((ra & 0xf8) == 0x70) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single block " + "allocation\n"); + sb = 1; + } else if (m_bts.force_two_phase) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests single " + "phase access, but we force two phase " + "access\n"); + sb = 1; + } + } + + return sb; +} + +/* depending on the current TBF, we assign on PACCH or AGCH */ +void BTS::trigger_dl_ass( + struct gprs_rlcmac_dl_tbf *dl_tbf, + struct gprs_rlcmac_tbf *old_tbf) +{ + /* stop pending timer */ + dl_tbf->stop_timer(); + + /* check for downlink tbf: */ + if (old_tbf) { + LOGP(DRLCMAC, LOGL_DEBUG, "Send dowlink assignment on " + "PACCH, because %s exists\n", tbf_name(old_tbf)); + old_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; + + old_tbf->was_releasing = old_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE); + + /* change state */ + dl_tbf->set_state(GPRS_RLCMAC_ASSIGN); + if (!(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) + dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); + /* start timer */ + tbf_timer_start(dl_tbf, 0, Tassign_pacch); + } else { + uint32_t tlli = ntohl(dl_tbf->tlli()); + LOGP(DRLCMAC, LOGL_DEBUG, "Send dowlink assignment for %s on PCH, no TBF exist (IMSI=%s)\n", tbf_name(dl_tbf), dl_tbf->imsi()); + dl_tbf->was_releasing = dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE); + /* change state */ + dl_tbf->set_state(GPRS_RLCMAC_ASSIGN); + dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH); + /* send immediate assignment */ + /* FIXME TLLI != P-TMSI, but our sgsn use TLLI == P-TMSI */ + gprs_rlcmac_paging_request((uint8_t *)&tlli, sizeof(dl_tbf->tlli()), dl_tbf->imsi()); + dl_tbf->bts->snd_dl_ass(dl_tbf, 0, dl_tbf->imsi()); + dl_tbf->m_wait_confirm = 1; + /* start timer */ + tbf_timer_start(dl_tbf, 0, Tassign_pacch); + + } +} + +void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, uint8_t poll, const char *imsi) +{ + int plen; + unsigned int ts = tbf->first_ts; + + LOGP(DRLCMAC, LOGL_INFO, "TX: START %s Immediate Assignment Downlink (PCH)\n", tbf_name(tbf)); + bitvec *immediate_assignment = bitvec_alloc(22); /* without plen */ + bitvec_unhex(immediate_assignment, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); + /* use request reference that has maximum distance to current time, + * so the assignment will not conflict with possible RACH requests. */ + LOGP(DRLCMAC, LOGL_DEBUG, " - TRX=%d (%d) TS=%d TA=%d pollFN=%d\n", + tbf->trx->trx_no, tbf->trx->arfcn, + ts, tbf->ta(), poll ? tbf->poll_fn : -1); + plen = Encoding::write_immediate_assignment(tbf, immediate_assignment, 1, 125, + (tbf->pdch[ts]->last_rts_fn + 21216) % 2715648, tbf->ta(), + tbf->trx->arfcn, ts, tbf->tsc(), 7, poll, + tbf->poll_fn, m_bts.alpha, m_bts.gamma, -1); + if (plen >= 0) { + immediate_assignment_dl_tbf(); + if (this->bts_data()->use_direct_tlli) + pcu_l1if_tx_agch_dt(tbf->tlli(), immediate_assignment, plen); + else + pcu_l1if_tx_agch(immediate_assignment, plen); + } + + bitvec_free(immediate_assignment); +} + + +GprsMs *BTS::ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class) +{ + GprsMs *ms; + ms = ms_store().create_ms(); + + ms->set_timeout(m_bts.ms_idle_sec); + ms->set_ms_class(ms_class); + ms->set_egprs_ms_class(egprs_ms_class); + + return ms; +} + +/* + * PDCH code below. TODO: move to a separate file + */ + +void gprs_rlcmac_pdch::enable() +{ + /* TODO: Check if there are still allocated resources.. */ + INIT_LLIST_HEAD(&paging_list); + m_is_enabled = 1; +} + +void gprs_rlcmac_pdch::disable() +{ + /* TODO.. kick free_resources once we know the TRX/TS we are on */ + m_is_enabled = 0; +} + +void gprs_rlcmac_pdch::free_resources() +{ + struct gprs_rlcmac_paging *pag; + + /* we are not enabled. there should be no resources */ + if (!is_enabled()) + return; + + /* kick all TBF on slot */ + gprs_rlcmac_tbf::free_all(this); + + /* flush all pending paging messages */ + while ((pag = dequeue_paging())) + talloc_free(pag); + + trx->bts->sba()->free_resources(this); +} + +struct gprs_rlcmac_paging *gprs_rlcmac_pdch::dequeue_paging() +{ + struct gprs_rlcmac_paging *pag; + + if (llist_empty(&paging_list)) + return NULL; + pag = llist_entry(paging_list.next, struct gprs_rlcmac_paging, list); + llist_del(&pag->list); + + return pag; +} + +struct msgb *gprs_rlcmac_pdch::packet_paging_request() +{ + struct gprs_rlcmac_paging *pag; + struct msgb *msg; + unsigned wp = 0, len; + + /* no paging, no message */ + pag = dequeue_paging(); + if (!pag) + return NULL; + + LOGP(DRLCMAC, LOGL_DEBUG, "Scheduling paging\n"); + + /* alloc message */ + msg = msgb_alloc(23, "pag ctrl block"); + if (!msg) { + talloc_free(pag); + return NULL; + } + bitvec *pag_vec = bitvec_alloc(23); + if (!pag_vec) { + msgb_free(msg); + talloc_free(pag); + return NULL; + } + wp = Encoding::write_packet_paging_request(pag_vec); + + /* loop until message is full */ + while (pag) { + /* try to add paging */ + if ((pag->identity_lv[1] & 0x07) == 4) { + /* TMSI */ + LOGP(DRLCMAC, LOGL_DEBUG, "- TMSI=0x%08x\n", + ntohl(*((uint32_t *)(pag->identity_lv + 1)))); + len = 1 + 1 + 1 + 32 + 2 + 1; + if (pag->identity_lv[0] != 5) { + LOGP(DRLCMAC, LOGL_ERROR, "TMSI paging with " + "MI != 5 octets!\n"); + goto continue_next; + } + } else { + /* MI */ + LOGP(DRLCMAC, LOGL_DEBUG, "- MI=%s\n", + osmo_hexdump(pag->identity_lv + 1, + pag->identity_lv[0])); + len = 1 + 1 + 1 + 4 + (pag->identity_lv[0]<<3) + 2 + 1; + if (pag->identity_lv[0] > 8) { + LOGP(DRLCMAC, LOGL_ERROR, "Paging with " + "MI > 8 octets!\n"); + goto continue_next; + } + } + if (wp + len > 184) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Does not fit, so schedule " + "next time\n"); + /* put back paging record, because does not fit */ + llist_add_tail(&pag->list, &paging_list); + break; + } + Encoding::write_repeated_page_info(pag_vec, wp, pag->identity_lv[0], + pag->identity_lv + 1, pag->chan_needed); + +continue_next: + talloc_free(pag); + pag = dequeue_paging(); + } + + bitvec_pack(pag_vec, msgb_put(msg, 23)); + RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); + LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Paging Request +++++++++++++++++++++++++\n"); + decode_gsm_rlcmac_downlink(pag_vec, mac_control_block); + LOGPC(DCSN1, LOGL_NOTICE, "\n"); + LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- TX : Packet Paging Request -------------------------\n"); + bitvec_free(pag_vec); + talloc_free(mac_control_block); + + return msg; +} + +void gprs_rlcmac_pdch::add_paging(struct gprs_rlcmac_paging *pag) +{ + llist_add(&pag->list, &paging_list); +} + +void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, uint32_t fn) +{ + struct gprs_rlcmac_tbf *tbf, *new_tbf; + uint32_t tlli = 0; + + tlli = packet->TLLI; + tbf = bts()->ul_tbf_by_poll_fn(fn, trx_no(), ts_no); + if (!tbf) + tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no); + + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "RX: [PCU <- BTS] PACKET CONTROL ACK with " + "unknown FN=%u TLLI=0x%08x (TRX %d TS %d)\n", + fn, tlli, trx_no(), ts_no); + return; + } + tbf->update_ms(tlli, GPRS_RLCMAC_UL_TBF); + + LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] %s Packet Control Ack\n", tbf_name(tbf)); + tbf->poll_state = GPRS_RLCMAC_POLL_NONE; + + /* check if this control ack belongs to packet uplink ack */ + if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_WAIT_ACK) { + LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] END %s\n", tbf_name(tbf)); + tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; + if ((tbf->state_flags & + (1 << GPRS_RLCMAC_FLAG_TO_UL_ACK))) { + tbf->state_flags &= + ~(1 << GPRS_RLCMAC_FLAG_TO_UL_ACK); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink " + "ack for UL %s\n", tbf_name(tbf)); + } + tbf_free(tbf); + return; + } + if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_WAIT_ACK) { + LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [UPLINK] DOWNLINK ASSIGNED %s\n", tbf_name(tbf)); + /* reset N3105 */ + tbf->n3105 = 0; + tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; + + new_tbf = tbf->ms() ? tbf->ms()->dl_tbf() : NULL; + if (!new_tbf) { + LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but DL " + "TBF is gone TLLI=0x%08x\n", tlli); + return; + } + if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE) && + tbf->direction == new_tbf->direction) + tbf_free(tbf); + + if ((new_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { + /* We now know that the PACCH really existed */ + LOGP(DRLCMAC, LOGL_INFO, + "The TBF has been confirmed on the PACCH, " + "changed type from CCCH to PACCH for %s\n", + tbf_name(new_tbf)); + new_tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); + new_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); + } + new_tbf->set_state(GPRS_RLCMAC_FLOW); + /* stop pending assignment timer */ + new_tbf->stop_timer(); + if ((new_tbf->state_flags & + (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) { + new_tbf->state_flags &= + ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink " + "assignment for %s\n", tbf_name(new_tbf)); + } + tbf_assign_control_ts(new_tbf); + return; + } + if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) { + LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] UPLINK ASSIGNED %s\n", tbf_name(tbf)); + /* reset N3105 */ + tbf->n3105 = 0; + tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE; + + new_tbf = tbf->ms() ? tbf->ms()->ul_tbf() : NULL; + if (!new_tbf) { + LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but UL " + "TBF is gone TLLI=0x%08x\n", tlli); + return; + } + if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE) && + tbf->direction == new_tbf->direction) + tbf_free(tbf); + + new_tbf->set_state(GPRS_RLCMAC_FLOW); + if ((new_tbf->state_flags & + (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) { + new_tbf->state_flags &= + ~(1 << GPRS_RLCMAC_FLAG_TO_UL_ASS); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink " + "assignment for UL %s\n", tbf_name(new_tbf)); + } + tbf_assign_control_ts(new_tbf); + /* there might be LLC packets waiting in the queue, but the DL + * TBF might have been released while the UL TBF has been + * established */ + if (new_tbf->ms()->need_dl_tbf()) + new_tbf->establish_dl_tbf_on_pacch(); + + return; + } + LOGP(DRLCMAC, LOGL_ERROR, "Error: received PACET CONTROL ACK " + "at no request\n"); +} + +static void get_rx_qual_meas(struct pcu_l1_meas *meas, uint8_t rx_qual_enc) +{ + static const int16_t rx_qual_map[] = { + 0, /* 0,14 % */ + 0, /* 0,28 % */ + 1, /* 0,57 % */ + 1, /* 1,13 % */ + 2, /* 2,26 % */ + 5, /* 4,53 % */ + 9, /* 9,05 % */ + 18, /* 18,10 % */ + }; + + meas->set_ms_rx_qual(rx_qual_map[ + OSMO_MIN(rx_qual_enc, ARRAY_SIZE(rx_qual_map)-1) + ]); +} + +static void get_meas(struct pcu_l1_meas *meas, + const Packet_Resource_Request_t *qr) +{ + unsigned i; + + meas->set_ms_c_value(qr->C_VALUE); + if (qr->Exist_SIGN_VAR) + meas->set_ms_sign_var((qr->SIGN_VAR + 2) / 4); /* SIGN_VAR * 0.25 dB */ + + for (i = 0; i < OSMO_MIN(ARRAY_SIZE(qr->Slot), ARRAY_SIZE(meas->ts)); i++) + { + if (qr->Slot[i].Exist) { + LOGP(DRLCMAC, LOGL_INFO, + "Packet resource request: i_level[%d] = %d\n", + i, qr->Slot[i].I_LEVEL); + meas->set_ms_i_level(i, -2 * qr->Slot[i].I_LEVEL); + } + } +} + +static void get_meas(struct pcu_l1_meas *meas, + const Channel_Quality_Report_t *qr) +{ + unsigned i; + + get_rx_qual_meas(meas, qr->RXQUAL); + meas->set_ms_c_value(qr->C_VALUE); + meas->set_ms_sign_var((qr->SIGN_VAR + 2) / 4); /* SIGN_VAR * 0.25 dB */ + + for (i = 0; i < OSMO_MIN(ARRAY_SIZE(qr->Slot), ARRAY_SIZE(meas->ts)); i++) + { + if (qr->Slot[i].Exist) { + LOGP(DRLCMAC, LOGL_INFO, + "Channel quality report: i_level[%d] = %d\n", + i, qr->Slot[i].I_LEVEL_TN); + meas->set_ms_i_level(i, -2 * qr->Slot[i].I_LEVEL_TN); + } + } +} + +void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_nack, uint32_t fn) +{ + int8_t tfi = 0; /* must be signed */ + struct gprs_rlcmac_dl_tbf *tbf; + int rc; + struct pcu_l1_meas meas; + int num_blocks; + uint8_t bits_data[RLC_GPRS_WS/8]; + bitvec bits; + int bsn_begin, bsn_end; + char show_bits[RLC_GPRS_WS + 1]; + + tfi = ack_nack->DOWNLINK_TFI; + tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "RX: [PCU <- BTS] PACKET DOWNLINK ACK with " + "unknown FN=%u TFI=%d (TRX %d TS %d)\n", + fn, tfi, trx_no(), ts_no); + return; + } + if (tbf->tfi() != tfi) { + LOGP(DRLCMAC, LOGL_NOTICE, "RX: [PCU <- BTS] PACKET DOWNLINK ACK with " + "wrong TFI=%d, ignoring!\n", tfi); + return; + } + tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK); + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) { + tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink ack " + "for %s\n", tbf_name(tbf)); + } + /* reset N3105 */ + tbf->n3105 = 0; + tbf->stop_t3191(); + LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] %s Packet Downlink Ack/Nack\n", tbf_name(tbf)); + tbf->poll_state = GPRS_RLCMAC_POLL_NONE; + + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + num_blocks = Decoding::decode_gprs_acknack_bits( + &ack_nack->Ack_Nack_Description, &bits, + &bsn_begin, &bsn_end, &tbf->m_window); + + LOGP(DRLCMAC, LOGL_DEBUG, + "Got GPRS DL ACK bitmap: SSN: %d, BSN %d to %d - 1 (%d blocks), " + "\"%s\"\n", + ack_nack->Ack_Nack_Description.STARTING_SEQUENCE_NUMBER, + bsn_begin, bsn_end, num_blocks, + (Decoding::extract_rbb(&bits, show_bits), show_bits)); + + rc = tbf->rcvd_dl_ack( + ack_nack->Ack_Nack_Description.FINAL_ACK_INDICATION, + bsn_begin, &bits); + if (rc == 1) { + tbf_free(tbf); + return; + } + /* check for channel request */ + if (ack_nack->Exist_Channel_Request_Description) { + + bts()->channel_request_description(); + + /* This call will register the new TBF with the MS on success */ + gprs_rlcmac_ul_tbf *ul_tbf = tbf_alloc_ul(bts_data(), + tbf->trx->trx_no, + tbf->ms_class(), tbf->ms()->egprs_ms_class(), + tbf->tlli(), tbf->ta(), tbf->ms()); + + /* schedule uplink assignment or reject*/ + if (ul_tbf) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack " + "message, so we provide one:\n"); + tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; + } else { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack " + "message, so we pacekt access reject:\n"); + tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ; + } + } + /* get measurements */ + if (tbf->ms()) { + get_meas(&meas, &ack_nack->Channel_Quality_Report); + tbf->ms()->update_l1_meas(&meas); + } +} + +void gprs_rlcmac_pdch::rcv_control_egprs_dl_ack_nack(EGPRS_PD_AckNack_t *ack_nack, uint32_t fn) +{ + int8_t tfi = 0; /* must be signed */ + struct gprs_rlcmac_dl_tbf *tbf; + struct pcu_l1_meas meas; + int rc; + int num_blocks; + uint8_t bits_data[RLC_EGPRS_MAX_WS/8]; + char show_bits[RLC_EGPRS_MAX_WS + 1]; + bitvec bits; + int bsn_begin, bsn_end; + + tfi = ack_nack->DOWNLINK_TFI; + tbf = bts()->dl_tbf_by_poll_fn(fn, trx_no(), ts_no); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "EGPRS PACKET DOWNLINK ACK with " + "unknown FN=%u TFI=%d (TRX %d TS %d)\n", + fn, tfi, trx_no(), ts_no); + return; + } + if (tbf->tfi() != tfi) { + LOGP(DRLCMAC, LOGL_NOTICE, "EGPRS PACKET DOWNLINK ACK with " + "wrong TFI=%d, ignoring!\n", tfi); + return; + } + tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_DL_ACK); + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) { + tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ACK); + LOGP(DRLCMAC, LOGL_NOTICE, "Recovered EGPRS downlink ack " + "for %s\n", tbf_name(tbf)); + } + /* reset N3105 */ + tbf->n3105 = 0; + tbf->stop_t3191(); + LOGP(DRLCMAC, LOGL_DEBUG, + "RX: [PCU <- BTS] %s EGPRS Packet Downlink Ack/Nack\n", + tbf_name(tbf)); + tbf->poll_state = GPRS_RLCMAC_POLL_NONE; + + LOGP(DRLCMAC, LOGL_DEBUG, "EGPRS ACK/NACK: " + "ut: %d, final: %d, bow: %d, eow: %d, ssn: %d, have_crbb: %d, " + "urbb_len:%d, %p, %p, %d, %d, win: %d-%d, urbb: %s\n", + (int)ack_nack->EGPRS_AckNack.UnionType, + (int)ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, + (int)ack_nack->EGPRS_AckNack.Desc.BEGINNING_OF_WINDOW, + (int)ack_nack->EGPRS_AckNack.Desc.END_OF_WINDOW, + (int)ack_nack->EGPRS_AckNack.Desc.STARTING_SEQUENCE_NUMBER, + (int)ack_nack->EGPRS_AckNack.Desc.Exist_CRBB, + (int)ack_nack->EGPRS_AckNack.Desc.URBB_LENGTH, + (void *)&ack_nack->EGPRS_AckNack.UnionType, + (void *)&ack_nack->EGPRS_AckNack.Desc, + (int)offsetof(EGPRS_AckNack_t, Desc), + (int)offsetof(EGPRS_AckNack_w_len_t, Desc), + tbf->m_window.v_a(), + tbf->m_window.v_s(), + osmo_hexdump((const uint8_t *)&ack_nack->EGPRS_AckNack.Desc.URBB, + sizeof(ack_nack->EGPRS_AckNack.Desc.URBB))); + + bits.data = bits_data; + bits.data_len = sizeof(bits_data); + bits.cur_bit = 0; + + num_blocks = Decoding::decode_egprs_acknack_bits( + &ack_nack->EGPRS_AckNack.Desc, &bits, + &bsn_begin, &bsn_end, &tbf->m_window); + + LOGP(DRLCMAC, LOGL_DEBUG, + "Got EGPRS DL ACK bitmap: SSN: %d, BSN %d to %d - 1 (%d blocks), " + "\"%s\"\n", + ack_nack->EGPRS_AckNack.Desc.STARTING_SEQUENCE_NUMBER, + bsn_begin, bsn_end, num_blocks, + (Decoding::extract_rbb(&bits, show_bits), show_bits) + ); + + rc = tbf->rcvd_dl_ack( + ack_nack->EGPRS_AckNack.Desc.FINAL_ACK_INDICATION, + bsn_begin, &bits); + if (rc == 1) { + tbf_free(tbf); + return; + } + + /* check for channel request */ + if (ack_nack->Exist_ChannelRequestDescription) { + + bts()->channel_request_description(); + + /* This call will register the new TBF with the MS on success */ + gprs_rlcmac_ul_tbf *ul_tbf = tbf_alloc_ul(bts_data(), + tbf->trx->trx_no, + tbf->ms_class(), tbf->ms()->egprs_ms_class(), + tbf->tlli(), tbf->ta(), tbf->ms()); + + /* schedule uplink assignment or reject*/ + if (ul_tbf) { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack " + "message, so we provide one:\n"); + tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; + } else { + LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack " + "message, so we send packet access reject:\n"); + tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS_REJ; + } + } + + /* get measurements */ + if (tbf->ms()) { + /* TODO: Implement Measurements parsing for EGPRS */ + /* + get_meas(&meas, &ack_nack->Channel_Quality_Report); + tbf->ms()->update_l1_meas(&meas); + */ + } +} + +void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, uint32_t fn) +{ + struct gprs_rlcmac_sba *sba; + + if (request->ID.UnionType) { + struct gprs_rlcmac_ul_tbf *ul_tbf = NULL; + struct gprs_rlcmac_dl_tbf *dl_tbf = NULL; + uint32_t tlli = request->ID.u.TLLI; + uint8_t ms_class = 0; + uint8_t egprs_ms_class = 0; + uint8_t ta = GSM48_TA_INVALID; + struct pcu_l1_meas meas; + + GprsMs *ms = bts()->ms_by_tlli(tlli); + /* Keep the ms, even if it gets idle temporarily */ + GprsMs::Guard guard(ms); + + if (ms) { + ul_tbf = ms->ul_tbf(); + dl_tbf = ms->dl_tbf(); + ta = ms->ta(); + } + + LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] Resource Request over PDCH\n"); + + /* We got a RACH so the MS was in packet idle mode and thus + * didn't have any active TBFs */ + if (ul_tbf) { + LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " + "TLLI=0x%08x while %s still " + "exists. Killing pending UL TBF\n", + tlli, tbf_name(ul_tbf)); + tbf_free(ul_tbf); + ul_tbf = NULL; + } + + if (dl_tbf) { + LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " + "TLLI=0x%08x while %s still exists. " + "Release pending DL TBF\n", tlli, + tbf_name(dl_tbf)); + tbf_free(dl_tbf); + dl_tbf = NULL; + } + LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] MS requests UL TBF " + "in packet resource request of single " + "block, so we provide one:\n"); + sba = bts()->sba()->find(this, fn); + if (!sba) { + LOGP(DRLCMAC, LOGL_NOTICE, "MS requests UL TBF " + "in packet resource request of single " + "block, but there is no resource request " + "scheduled!\n"); + } else { + ta = sba->ta; + bts()->sba()->free_sba(sba); + } + if (request->Exist_MS_Radio_Access_capability) { + ms_class = Decoding::get_ms_class_by_capability( + &request->MS_Radio_Access_capability); + egprs_ms_class = + Decoding::get_egprs_ms_class_by_capability( + &request->MS_Radio_Access_capability); + } + if (!ms_class) + LOGP(DRLCMAC, LOGL_NOTICE, "MS does not give us a class.\n"); + if (egprs_ms_class) + LOGP(DRLCMAC, LOGL_NOTICE, + "MS supports EGPRS multislot class %d.\n", + egprs_ms_class); + ul_tbf = tbf_alloc_ul(bts_data(), trx_no(), ms_class, + egprs_ms_class, tlli, ta, ms); + if (!ul_tbf) + return; + + /* set control ts to current MS's TS, until assignment complete */ + LOGP(DRLCMAC, LOGL_DEBUG, "Change control TS to %d until assinment is complete.\n", ts_no); + ul_tbf->control_ts = ts_no; + /* schedule uplink assignment */ + ul_tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; + + /* get capabilities */ + if (ul_tbf->ms()) + ul_tbf->ms()->set_egprs_ms_class(egprs_ms_class); + + /* get measurements */ + if (ul_tbf->ms()) { + get_meas(&meas, request); + ul_tbf->ms()->update_l1_meas(&meas); + } + return; + } + + if (request->ID.u.Global_TFI.UnionType) { + struct gprs_rlcmac_dl_tbf *dl_tbf; + int8_t tfi = request->ID.u.Global_TFI.u.DOWNLINK_TFI; + dl_tbf = bts()->dl_tbf_by_tfi(tfi, trx_no(), ts_no); + if (!dl_tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown downlink TFI=%d\n", tfi); + return; + } + LOGP(DRLCMAC, LOGL_ERROR, + "RX: [PCU <- BTS] %s FIXME: Packet resource request\n", + tbf_name(dl_tbf)); + } else { + struct gprs_rlcmac_ul_tbf *ul_tbf; + int8_t tfi = request->ID.u.Global_TFI.u.UPLINK_TFI; + ul_tbf = bts()->ul_tbf_by_tfi(tfi, trx_no(), ts_no); + if (!ul_tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "PACKET RESSOURCE REQ unknown uplink TFI=%d\n", tfi); + return; + } + LOGP(DRLCMAC, LOGL_ERROR, + "RX: [PCU <- BTS] %s FIXME: Packet resource request\n", + tbf_name(ul_tbf)); + } +} + +void gprs_rlcmac_pdch::rcv_measurement_report(Packet_Measurement_Report_t *report, uint32_t fn) +{ + struct gprs_rlcmac_sba *sba; + + LOGP(DRLCMAC, LOGL_DEBUG, "RX: [PCU <- BTS] Measurement Report\n"); + sba = bts()->sba()->find(this, fn); + if (!sba) { + LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement " + "in packet resource request of single " + "block, but there is no resource request " + "scheduled! TLLI=0x%08x\n", report->TLLI); + } else { + GprsMs *ms = bts()->ms_store().get_ms(report->TLLI); + if (!ms) + LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement " + "but TLLI 0x%08x is unknown\n", report->TLLI); + else + ms->set_ta(sba->ta); + + bts()->sba()->free_sba(sba); + } + gprs_rlcmac_meas_rep(report); +} + +/* Received Uplink RLC control block. */ +int gprs_rlcmac_pdch::rcv_control_block( + bitvec *rlc_block, uint32_t fn) +{ + RlcMacUplink_t * ul_control_block = (RlcMacUplink_t *)talloc_zero(tall_pcu_ctx, RlcMacUplink_t); + LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ RX : Uplink Control Block +++++++++++++++++++++++++\n"); + decode_gsm_rlcmac_uplink(rlc_block, ul_control_block); + LOGPC(DCSN1, LOGL_NOTICE, "\n"); + LOGP(DRLCMAC, LOGL_DEBUG, "------------------------- RX : Uplink Control Block -------------------------\n"); + bts()->rlc_rcvd_control(); + switch (ul_control_block->u.MESSAGE_TYPE) { + case MT_PACKET_CONTROL_ACK: + rcv_control_ack(&ul_control_block->u.Packet_Control_Acknowledgement, fn); + break; + case MT_PACKET_DOWNLINK_ACK_NACK: + rcv_control_dl_ack_nack(&ul_control_block->u.Packet_Downlink_Ack_Nack, fn); + break; + case MT_EGPRS_PACKET_DOWNLINK_ACK_NACK: + rcv_control_egprs_dl_ack_nack(&ul_control_block->u.Egprs_Packet_Downlink_Ack_Nack, fn); + break; + case MT_PACKET_RESOURCE_REQUEST: + rcv_resource_request(&ul_control_block->u.Packet_Resource_Request, fn); + break; + case MT_PACKET_MEASUREMENT_REPORT: + rcv_measurement_report(&ul_control_block->u.Packet_Measurement_Report, fn); + break; + case MT_PACKET_UPLINK_DUMMY_CONTROL_BLOCK: + /* ignoring it. change the SI to not force sending these? */ + break; + default: + bts()->decode_error(); + LOGP(DRLCMAC, LOGL_NOTICE, + "RX: [PCU <- BTS] unknown control block(%d) received\n", + ul_control_block->u.MESSAGE_TYPE); + } + talloc_free(ul_control_block); + return 1; +} + + +/* received RLC/MAC block from L1 */ +int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, + struct pcu_l1_meas *meas) +{ + GprsCodingScheme cs = GprsCodingScheme::getBySizeUL(len); + if (!cs) { + bts()->decode_error(); + LOGP(DRLCMACUL, LOGL_ERROR, "Dropping data block with invalid" + "length: %d)\n", len); + return -EINVAL; + } + + bts()->rlc_ul_bytes(len); + + LOGP(DRLCMACUL, LOGL_DEBUG, "Got RLC block, coding scheme: %s, " + "length: %d (%d))\n", cs.name(), len, cs.usedSizeUL()); + + if (cs.isGprs()) + return rcv_block_gprs(data, fn, meas, cs); + + if (cs.isEgprs()) + return rcv_data_block(data, fn, meas, cs); + + bts()->decode_error(); + LOGP(DRLCMACUL, LOGL_ERROR, "Unsupported coding scheme %s\n", + cs.name()); + return -EINVAL; +} + +/*! \brief process egprs and gprs data blocks */ +int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint32_t fn, + struct pcu_l1_meas *meas, GprsCodingScheme cs) +{ + int rc; + struct gprs_rlc_data_info rlc_dec; + struct gprs_rlcmac_ul_tbf *tbf; + unsigned len = cs.sizeUL(); + + /* These are always data blocks, since EGPRS still uses CS-1 for + * control blocks (see 44.060, section 10.3, 1st par.) + */ + if (cs.isEgprs()) { + if (!bts()->bts_data()->egprs_enabled) { + LOGP(DRLCMACUL, LOGL_ERROR, + "Got %s RLC block but EGPRS is not enabled\n", + cs.name()); + return -EINVAL; + } + } + + LOGP(DRLCMACUL, LOGL_DEBUG, " UL data: %s\n", osmo_hexdump(data, len)); + rc = Decoding::rlc_parse_ul_data_header(&rlc_dec, data, cs); + if (rc < 0) { + LOGP(DRLCMAC, LOGL_ERROR, + "Got %s RLC block but header parsing has failed\n", + cs.name()); + bts()->decode_error(); + return rc; + } + + LOGP(DRLCMACUL, LOGL_INFO, + "Got %s RLC block: " + "R=%d, SI=%d, TFI=%d, CPS=%d, RSB=%d, " + "rc=%d\n", + cs.name(), + rlc_dec.r, rlc_dec.si, rlc_dec.tfi, rlc_dec.cps, rlc_dec.rsb, + rc); + + /* find TBF inst from given TFI */ + tbf = ul_tbf_by_tfi(rlc_dec.tfi); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "UL DATA unknown TFI=%d\n", + rlc_dec.tfi); + return 0; + } + LOGP(DRLCMAC, LOGL_DEBUG, "[RX: PCU <- BTS] %s UL data\n", tbf->name()); + + return tbf->rcv_data_block_acknowledged(&rlc_dec, data, meas); +} + +int gprs_rlcmac_pdch::rcv_block_gprs(uint8_t *data, uint32_t fn, + struct pcu_l1_meas *meas, GprsCodingScheme cs) +{ + unsigned payload = data[0] >> 6; + bitvec *block; + int rc = 0; + unsigned len = cs.maxBytesUL(); + + switch (payload) { + case GPRS_RLCMAC_DATA_BLOCK: + rc = rcv_data_block(data, fn, meas, cs); + break; + case GPRS_RLCMAC_CONTROL_BLOCK: + block = bitvec_alloc(len); + if (!block) + return -ENOMEM; + bitvec_unpack(block, data); + rc = rcv_control_block(block, fn); + bitvec_free(block); + break; + case GPRS_RLCMAC_CONTROL_BLOCK_OPT: + LOGP(DRLCMAC, LOGL_NOTICE, "GPRS_RLCMAC_CONTROL_BLOCK_OPT block payload is not supported.\n"); + break; + default: + LOGP(DRLCMAC, LOGL_NOTICE, "Unknown RLCMAC block payload(%u).\n", payload); + rc = -EINVAL; + } + + return rc; +} + +void bts_update_tbf_ta(const char *p, uint32_t fn, uint8_t trx_no, uint8_t ts, + uint8_t ta) +{ + struct gprs_rlcmac_ul_tbf *tbf = + bts_main_data()->bts->ul_tbf_by_poll_fn(fn, trx_no, ts); + if (!tbf) + LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to " + "unknown UL TBF on TRX = %d, TS = %d, FN = %d\n", + p, ta, trx_no, ts, fn); + else if (tbf->ta() != ta) { + LOGP(DL1IF, LOGL_INFO, "[%s] Updating TA %u -> %u on " + "TRX = %d, TS = %d, FN = %d\n", + p, tbf->ta(), ta, trx_no, ts, fn); + tbf->set_ta(ta); + } +} + +gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_from_list_by_tfi( + LListHead<gprs_rlcmac_tbf> *tbf_list, uint8_t tfi, + enum gprs_rlcmac_tbf_direction dir) +{ + gprs_rlcmac_tbf *tbf; + LListHead<gprs_rlcmac_tbf> *pos; + + llist_for_each(pos, tbf_list) { + tbf = pos->entry(); + if (tbf->tfi() != tfi) + continue; + if (!tbf->pdch[ts_no]) + continue; + return tbf; + } + return NULL; +} + +gprs_rlcmac_ul_tbf *gprs_rlcmac_pdch::ul_tbf_by_tfi(uint8_t tfi) +{ + return as_ul_tbf(tbf_by_tfi(tfi, GPRS_RLCMAC_UL_TBF)); +} + +gprs_rlcmac_dl_tbf *gprs_rlcmac_pdch::dl_tbf_by_tfi(uint8_t tfi) +{ + return as_dl_tbf(tbf_by_tfi(tfi, GPRS_RLCMAC_DL_TBF)); +} + +/* lookup TBF Entity (by TFI) */ +gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_by_tfi(uint8_t tfi, + enum gprs_rlcmac_tbf_direction dir) +{ + struct gprs_rlcmac_tbf *tbf; + + if (tfi >= 32) + return NULL; + + tbf = m_tbfs[dir][tfi]; + + if (!tbf) + return NULL; + + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING)) { + return tbf; + } + + return NULL; +} + +void gprs_rlcmac_pdch::attach_tbf(gprs_rlcmac_tbf *tbf) +{ + gprs_rlcmac_ul_tbf *ul_tbf; + + if (m_tbfs[tbf->direction][tbf->tfi()]) + LOGP(DRLCMAC, LOGL_ERROR, "PDCH(TS %d, TRX %d): " + "%s has not been detached, overwriting it\n", + ts_no, trx_no(), + m_tbfs[tbf->direction][tbf->tfi()]->name()); + + m_num_tbfs[tbf->direction] += 1; + if (tbf->direction == GPRS_RLCMAC_UL_TBF) { + ul_tbf = as_ul_tbf(tbf); + m_assigned_usf |= 1 << ul_tbf->m_usf[ts_no]; + } + m_assigned_tfi[tbf->direction] |= 1UL << tbf->tfi(); + m_tbfs[tbf->direction][tbf->tfi()] = tbf; + + LOGP(DRLCMAC, LOGL_INFO, "PDCH(TS %d, TRX %d): Attaching %s, %d TBFs, " + "USFs = %02x, TFIs = %08x.\n", + ts_no, trx_no(), tbf->name(), m_num_tbfs[tbf->direction], + m_assigned_usf, m_assigned_tfi[tbf->direction]); +} + +void gprs_rlcmac_pdch::detach_tbf(gprs_rlcmac_tbf *tbf) +{ + gprs_rlcmac_ul_tbf *ul_tbf; + + OSMO_ASSERT(m_num_tbfs[tbf->direction] > 0); + + m_num_tbfs[tbf->direction] -= 1; + if (tbf->direction == GPRS_RLCMAC_UL_TBF) { + ul_tbf = as_ul_tbf(tbf); + m_assigned_usf &= ~(1 << ul_tbf->m_usf[ts_no]); + } + m_assigned_tfi[tbf->direction] &= ~(1UL << tbf->tfi()); + m_tbfs[tbf->direction][tbf->tfi()] = NULL; + + LOGP(DRLCMAC, LOGL_INFO, "PDCH(TS %d, TRX %d): Detaching %s, %d TBFs, " + "USFs = %02x, TFIs = %08x.\n", + ts_no, trx_no(), tbf->name(), m_num_tbfs[tbf->direction], + m_assigned_usf, m_assigned_tfi[tbf->direction]); +} + +void gprs_rlcmac_pdch::reserve(enum gprs_rlcmac_tbf_direction dir) +{ + m_num_reserved[dir] += 1; +} + +void gprs_rlcmac_pdch::unreserve(enum gprs_rlcmac_tbf_direction dir) +{ + OSMO_ASSERT(m_num_reserved[dir] > 0); + m_num_reserved[dir] -= 1; +} + +void gprs_rlcmac_trx::reserve_slots(enum gprs_rlcmac_tbf_direction dir, + uint8_t slots) +{ + unsigned i; + for (i = 0; i < ARRAY_SIZE(pdch); i += 1) + if (slots & (1 << i)) + pdch[i].reserve(dir); +} + +void gprs_rlcmac_trx::unreserve_slots(enum gprs_rlcmac_tbf_direction dir, + uint8_t slots) +{ + unsigned i; + for (i = 0; i < ARRAY_SIZE(pdch); i += 1) + if (slots & (1 << i)) + pdch[i].unreserve(dir); +} diff --git a/src/csn1.cpp b/src/csn1.cpp index a1698a5..6203a44 100644 --- a/src/csn1.cpp +++ b/src/csn1.cpp @@ -64,15 +64,15 @@ readIndex -= relative_bit_offset; if (bit_shift >= 0) { - result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> bit_shift; + result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> bit_shift; readIndex-= bit_shift; result &= maskBits[no_of_bits]; } else { - guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) & maskBits[8 - relative_bit_offset]; + guint8 hight_part = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) & maskBits[8 - relative_bit_offset]; hight_part = (guint8) (hight_part << (-bit_shift)); - result = (0x2B ^ ((guint8)bitvec_read_field(vector, readIndex, 8))) >> (8 + bit_shift); + result = (0x2B ^ ((guint8)bitvec_read_field(vector, &readIndex, 8))) >> (8 + bit_shift); readIndex = readIndex - (8 - (-bit_shift)); result |= hight_part; } @@ -133,7 +133,7 @@ static gboolean existNextElement(bitvec *vector, unsigned& readIndex, guint8 Tag) { - guint8 res = bitvec_read_field(vector, readIndex, 1); + guint8 res = bitvec_read_field(vector, &readIndex, 1); if (Tag == STANDARD_TAG) { return (res > 0); @@ -167,7 +167,7 @@ if (remaining_bits_len > 0) { pui8 = pui8DATA(data, pDescr->offset); - *pui8 = bitvec_read_field(vector, readIndex, 1); + *pui8 = bitvec_read_field(vector, &readIndex, 1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); /* end add the bit value to protocol tree */ } @@ -202,21 +202,21 @@ { if (no_of_bits <= 8) { - guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits); + guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits); pui8 = pui8DATA(data, pDescr->offset); *pui8 = ui8; LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); } else if (no_of_bits <= 16) { - guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits); + guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits); pui16 = pui16DATA(data, pDescr->offset); *pui16 = ui16; LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16); } else if (no_of_bits <= 32) { - guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits); + guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits); pui32 = pui32DATA(data, pDescr->offset); *pui32 = ui32; LOGPC(DCSN1, LOGL_NOTICE, "%s = 0x%08x | ", pDescr->sz , *pui32); @@ -264,21 +264,21 @@ { if (no_of_bits <= 8) { - guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits); + guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits); pui8 = pui8DATA(data, pDescr->offset); *pui8 = ui8 + (guint8)pDescr->descr.value; LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); } else if (no_of_bits <= 16) { - guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits); + guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits); pui16 = pui16DATA(data, pDescr->offset); *pui16 = ui16 + (guint16)pDescr->descr.value; LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16); } else if (no_of_bits <= 32) { - guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits); + guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits); pui32 = pui32DATA(data, pDescr->offset); *pui32 = ui32 + (guint16)pDescr->descr.value; LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32); @@ -308,7 +308,7 @@ remaining_bits_len -= no_of_bits; if (no_of_bits <= 8) { - guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits); + guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits); pui8 = pui8DATA(data, pDescr->offset); *pui8 = ui8; LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); @@ -347,7 +347,7 @@ pui8 = pui8DATA(data, pDescr->offset); do { - *pui8 = bitvec_read_field(vector, readIndex, no_of_bits); + *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; bit_offset += no_of_bits; @@ -401,7 +401,7 @@ LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz); csnStreamInit(&arT, bit_offset, remaining_bits_len); - Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8); + Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8); if (Status >= 0) { pui8 += nSize; @@ -430,7 +430,7 @@ { for(unsigned ib = 0; ib < 4; ib++) { - guint8 ui8 = bitvec_read_field(vector, readIndex, 8); + guint8 ui8 = bitvec_read_field(vector, &readIndex, 8); pui8 = pui8DATA(data, pDescr->offset+ib); *pui8 = ui8; LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8); @@ -440,7 +440,7 @@ { for(unsigned ib = 0; ib < 8; ib++) { - guint8 ui8 = bitvec_read_field(vector, readIndex, 8); + guint8 ui8 = bitvec_read_field(vector, &readIndex, 8); pui8 = pui8DATA(data, pDescr->offset+ib); *pui8 = ui8; LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8); @@ -467,7 +467,7 @@ csnStream_t arT = *ar; LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz); csnStreamInit(&arT, bit_offset, remaining_bits_len); - Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset)); + Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset)); LOGPC(DCSN1, LOGL_NOTICE, ": End %s | ", pDescr->sz); if (Status >= 0) { @@ -493,7 +493,7 @@ while (count > 0) { guint8 no_of_bits = pChoice->bits; - guint8 value = bitvec_read_field(vector, readIndex, no_of_bits); + guint8 value = bitvec_read_field(vector, &readIndex, no_of_bits); if (value == pChoice->value) { CSN_DESCR descr[2]; @@ -510,7 +510,7 @@ remaining_bits_len -= no_of_bits; csnStreamInit(&arT, bit_offset, remaining_bits_len); - Status = csnStreamDecoder(&arT, descr, vector, readIndex, data); + Status = csnStreamDecoder(&arT, descr, vector, readIndex, data); if (Status >= 0) { @@ -541,7 +541,7 @@ guint8 length_len = pDescr->i; gint16 Status = -1; - guint8 length = bitvec_read_field(vector, readIndex, length_len); + guint8 length = bitvec_read_field(vector, &readIndex, length_len); LOGPC(DCSN1, LOGL_NOTICE, "%s length = %d | ", pDescr->sz , (int)length); bit_offset += length_len; @@ -550,7 +550,7 @@ csnStreamInit(&arT, bit_offset, length); arT.direction = 1; LOGPC(DCSN1, LOGL_NOTICE, "ptr = %p | offset = %d | ", (void *)data, (int)pDescr->offset); - Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset)); + Status = serialize(&arT, vector, readIndex, pvDATA(data, pDescr->offset)); if (Status >= 0) { @@ -595,7 +595,7 @@ } else { - index |= bitvec_read_field(vector, readIndex, 1); + index |= bitvec_read_field(vector, &readIndex, 1); } remaining_bits_len--; bit_offset++; @@ -618,7 +618,7 @@ { pui8 = pui8DATA(data, pDescr->offset); *pui8 = 0x00; - if (bitvec_read_field(vector, readIndex, 1) > 0) + if (bitvec_read_field(vector, &readIndex, 1) > 0) { *pui8 = 0x01; } @@ -644,21 +644,21 @@ if (no_of_bits <= 8) { - guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits); + guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits); pui8 = pui8DATA(data, pDescr->offset); *pui8 = ui8; LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); } else if (no_of_bits <= 16) { - guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits); + guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits); pui16 = pui16DATA(data, pDescr->offset); *pui16 = ui16; LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16); } else if (no_of_bits <= 32) { - guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits); + guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits); pui32 = pui32DATA(data, pDescr->offset); *pui32 = ui32; LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32); @@ -686,21 +686,21 @@ { if (no_of_bits <= 8) { - guint8 ui8 = bitvec_read_field(vector, readIndex, no_of_bits); + guint8 ui8 = bitvec_read_field(vector, &readIndex, no_of_bits); pui8 = pui8DATA(data, pDescr->offset); *pui8 = ui8 + (guint8)pDescr->descr.value; LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); } else if (no_of_bits <= 16) { - guint16 ui16 = bitvec_read_field(vector, readIndex, no_of_bits); + guint16 ui16 = bitvec_read_field(vector, &readIndex, no_of_bits); pui16 = pui16DATA(data, pDescr->offset); *pui16 = ui16 + (guint16)pDescr->descr.value; LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16); } else if (no_of_bits <= 32) { - guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits); + guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits); pui32 = pui32DATA(data, pDescr->offset); *pui32 = ui32 + (guint16)pDescr->descr.value; LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32); @@ -728,7 +728,7 @@ { if (no_of_bits <= 8) { - guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits); + guint8 ui8 = get_masked_bits8(vector, readIndex, bit_offset, no_of_bits); pui8 = pui8DATA(data, pDescr->offset); *pui8 = ui8; LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); @@ -767,7 +767,7 @@ while (nCount > 0) { - *pui8 = bitvec_read_field(vector, readIndex, no_of_bits); + *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; bit_offset += no_of_bits; @@ -780,7 +780,7 @@ while (nCount > 0) { - *pui16 = bitvec_read_field(vector, readIndex, no_of_bits); + *pui16 = bitvec_read_field(vector, &readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , *pui16); pui16++; bit_offset += no_of_bits; @@ -830,7 +830,7 @@ { LOGPC(DCSN1, LOGL_NOTICE, "%s | ", pDescr->sz); csnStreamInit(&arT, bit_offset, remaining_bits_len); - Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8); + Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8); if (Status >= 0) { pui8 += nSize; @@ -856,13 +856,13 @@ if (no_of_bits <= 32) { - guint32 ui32 = bitvec_read_field(vector, readIndex, no_of_bits); + guint32 ui32 = bitvec_read_field(vector, &readIndex, no_of_bits); pui32 = pui32DATA(data, pDescr->offset); *pui32 = ui32; } else if (no_of_bits <= 64) { - guint64 ui64 = bitvec_read_field(vector, readIndex, no_of_bits); + guint64 ui64 = bitvec_read_field(vector, &readIndex, no_of_bits); pui64 = pui64DATA(data, pDescr->offset); *pui64 = ui64; LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64); @@ -888,7 +888,7 @@ csnStream_t arT = *ar; LOGPC(DCSN1, LOGL_NOTICE, " : %s | ", pDescr->sz); csnStreamInit(&arT, bit_offset, remaining_bits_len); - Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset)); + Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pvDATA(data, pDescr->offset)); LOGPC(DCSN1, LOGL_NOTICE, " : End %s | ", pDescr->sz); if (Status >= 0) { @@ -923,11 +923,11 @@ if (CSN_EXIST_LH == pDescr->type) { - fExist = get_masked_bits8(vector, readIndex, bit_offset, 1); + fExist = get_masked_bits8(vector, readIndex, bit_offset, 1); } else { - fExist = bitvec_read_field(vector, readIndex, 1); + fExist = bitvec_read_field(vector, &readIndex, 1); } *pui8 = fExist; @@ -966,7 +966,7 @@ /* the "regular" M_NEXT_EXIST description element */ fExist = 0x00; - if (bitvec_read_field(vector, readIndex, 1)) + if (bitvec_read_field(vector, &readIndex, 1)) { fExist = 0x01; } @@ -1059,7 +1059,7 @@ if (nB1 > 0) { /* take care of the first byte - it will be right aligned */ - *pui8 = bitvec_read_field(vector, readIndex, nB1); + *pui8 = bitvec_read_field(vector, &readIndex, nB1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= nB1; @@ -1069,7 +1069,7 @@ /* remaining no_of_bits is a multiple of 8 or 0 */ while (no_of_bits > 0) { - *pui8 = bitvec_read_field(vector, readIndex, 8); + *pui8 = bitvec_read_field(vector, &readIndex, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; @@ -1113,14 +1113,14 @@ while (no_of_bits >= 8) { - *pui8 = bitvec_read_field(vector, readIndex, 8); + *pui8 = bitvec_read_field(vector, &readIndex, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; } if (no_of_bits > 0) { - *pui8 = bitvec_read_field(vector, readIndex, no_of_bits); + *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; bit_offset += no_of_bits; @@ -1144,13 +1144,13 @@ guint8 bits_to_handle = remaining_bits_len%8; if (bits_to_handle > 0) { - LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, readIndex, bits_to_handle)); + LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, &readIndex, bits_to_handle)); remaining_bits_len -= bits_to_handle; bit_offset += bits_to_handle; } else if (bits_to_handle == 0) { - LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, readIndex, 8)); + LOGPC(DCSN1, LOGL_NOTICE, "%" PRIu64 "|", bitvec_read_field(vector, &readIndex, 8)); remaining_bits_len -= 8; bit_offset += 8; } @@ -1191,7 +1191,7 @@ while (count > 0) { readIndex -= 8; - *pui8 = bitvec_read_field(vector, readIndex, 8); + *pui8 = bitvec_read_field(vector, &readIndex, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; bit_offset += 8; @@ -1217,14 +1217,14 @@ pui8 = pui8DATA(data, pDescr->offset); - while (existNextElement(vector, readIndex, Tag)) + while (existNextElement(vector, readIndex, Tag)) { /* tag control shows existence of next list elements */ LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz); bit_offset++; remaining_bits_len--; /* extract and store no_of_bits long element from bitstream */ - *pui8 = bitvec_read_field(vector, readIndex, no_of_bits); + *pui8 = bitvec_read_field(vector, &readIndex, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; remaining_bits_len -= no_of_bits; @@ -1238,7 +1238,7 @@ bit_offset += no_of_bits; } - LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1)); + LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, &readIndex, 1)); /* existNextElement() returned FALSE, 1 bit consumed */ bit_offset++; @@ -1258,7 +1258,7 @@ guint8 ElementCount = 0; pui8 = pui8DATA(data, pDescr->offset); - while (existNextElement(vector, readIndex, Tag)) + while (existNextElement(vector, readIndex, Tag)) { /* tag control shows existence of next list elements */ LOGPC(DCSN1, LOGL_NOTICE, "%s = Exist | ", pDescr->sz); /* existNextElement() returned TRUE, 1 bit consumed */ @@ -1270,7 +1270,7 @@ csnStream_t arT = *ar; gint16 Status; csnStreamInit(&arT, bit_offset, remaining_bits_len); - Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8); + Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8); if (Status >= 0) { /* successful completion */ @@ -1290,7 +1290,7 @@ } } - LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, readIndex, 1)); + LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)bitvec_read_field(vector, &readIndex, 1)); /* existNextElement() returned FALSE, 1 bit consumed */ bit_offset++; @@ -1331,7 +1331,7 @@ LOGPC(DCSN1, LOGL_NOTICE, "%s { | ", pDescr->sz); csnStreamInit(&arT, bit_offset, remaining_bits_len); - Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8); + Status = csnStreamDecoder(&arT, (const CSN_DESCR*)pDescr->descr.ptr, vector, readIndex, pui8); if (Status >= 0) { /* successful completion */ @@ -1351,7 +1351,7 @@ /* control of next element's tag */ LOGPC(DCSN1, LOGL_NOTICE, "%s } | ", pDescr->sz); - EndOfList = !(existNextElement(vector, readIndex, Tag)); + EndOfList = !(existNextElement(vector, readIndex, Tag)); bit_offset++; remaining_bits_len--; /* 1 bit consumed (tag) */ @@ -1372,7 +1372,7 @@ if (no_of_bits <= 32) { - ui32 = bitvec_read_field(vector, readIndex, no_of_bits); + ui32 = bitvec_read_field(vector, &readIndex, no_of_bits); } else { @@ -1449,7 +1449,7 @@ if (remaining_bits_len > 0) { pui8 = pui8DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui8, 1); + bitvec_write_field(vector, &writeIndex, *pui8, 1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); /* end add the bit value to protocol tree */ } @@ -1483,19 +1483,19 @@ if (no_of_bits <= 8) { pui8 = pui8DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui8, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); } else if (no_of_bits <= 16) { pui16 = pui16DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui16, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16); } else if (no_of_bits <= 32) { pui32 = pui32DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui32, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32); } else @@ -1528,19 +1528,19 @@ if (no_of_bits <= 8) { pui8 = pui8DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value)); } else if (no_of_bits <= 16) { pui16 = pui16DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value)); } else if (no_of_bits <= 32) { pui32 = pui32DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value)); } else @@ -1569,12 +1569,12 @@ if (no_of_bits <= 8) { pui8 = pui8DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui8, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits); // TODO : Change get_masked_bits8() writeIndex -= no_of_bits; guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits); writeIndex -= no_of_bits; - bitvec_write_field(vector, writeIndex, ui8, no_of_bits); + bitvec_write_field(vector, &writeIndex, ui8, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); } @@ -1612,7 +1612,7 @@ pui8 = pui8DATA(data, pDescr->offset); do { - bitvec_write_field(vector, writeIndex, *pui8, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; bit_offset += no_of_bits; @@ -1697,7 +1697,7 @@ for(unsigned ib = 0; ib < 4; ib++) { pui8 = pui8DATA(data, pDescr->offset+ib); - bitvec_write_field(vector, writeIndex, *pui8, 8); + bitvec_write_field(vector, &writeIndex, *pui8, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8); } } @@ -1706,7 +1706,7 @@ for(unsigned ib = 0; ib < 8; ib++) { pui8 = pui8DATA(data, pDescr->offset+ib); - bitvec_write_field(vector, writeIndex, *pui8, 8); + bitvec_write_field(vector, &writeIndex, *pui8, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s[%u] = %u | ", pDescr->sz , ib, (unsigned)*pui8); } } @@ -1761,7 +1761,7 @@ guint8 no_of_bits = pChoice->bits; guint8 value = pChoice->value; LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pChoice->descr.sz , (unsigned)value); - bitvec_write_field(vector, writeIndex, value, no_of_bits); + bitvec_write_field(vector, &writeIndex, value, no_of_bits); CSN_DESCR descr[2]; gint16 Status; @@ -1807,7 +1807,7 @@ csnStreamInit(&arT, bit_offset, remaining_bits_len); Status = serialize(&arT, vector, writeIndex, pvDATA(data, pDescr->offset)); - bitvec_write_field(vector, lengthIndex, writeIndex-lengthIndex-length_len, length_len); + bitvec_write_field(vector, &lengthIndex, writeIndex-lengthIndex-length_len, length_len); LOGPC(DCSN1, LOGL_NOTICE, "%s length = %u | ", pDescr->sz , (unsigned)(writeIndex-lengthIndex)); if (Status >= 0) @@ -1846,7 +1846,7 @@ /* Assign UnionType */ pui8 = pui8DATA(data, pDescr->offset); //read index from data and write to vector - bitvec_write_field(vector, writeIndex, *pui8, Bits); + bitvec_write_field(vector, &writeIndex, *pui8, Bits); //decode index writeIndex -= Bits; @@ -1861,7 +1861,7 @@ } else { - index |= bitvec_read_field(vector, writeIndex, 1); + index |= bitvec_read_field(vector, &writeIndex, 1); } remaining_bits_len--; @@ -1870,7 +1870,7 @@ } writeIndex -= Bits; - bitvec_write_field(vector, writeIndex, index, Bits); + bitvec_write_field(vector, &writeIndex, index, Bits); /* script index to continue on, limited in case we do not have a power of 2 */ @@ -1883,7 +1883,7 @@ case CSN_BIT: { pui8 = pui8DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui8, 1); + bitvec_write_field(vector, &writeIndex, *pui8, 1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); remaining_bits_len -= 1; bit_offset++; @@ -1907,19 +1907,19 @@ if (no_of_bits <= 8) { pui8 = pui8DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui8, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); } else if (no_of_bits <= 16) { pui16 = pui16DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui16, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui16, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui16); } else if (no_of_bits <= 32) { pui32 = pui32DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui32, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32); } else @@ -1946,19 +1946,19 @@ if (no_of_bits <= 8) { pui8 = pui8DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui8 - (guint8)pDescr->descr.value, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(*pui8 - (guint8)pDescr->descr.value)); } else if (no_of_bits <= 16) { pui16 = pui16DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui16 - (guint16)pDescr->descr.value, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned short)(*pui16 - (guint16)pDescr->descr.value)); } else if (no_of_bits <= 32) { pui32 = pui32DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui32 - (guint16)pDescr->descr.value, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , (unsigned int)(*pui32 - (guint16)pDescr->descr.value)); } else @@ -1987,12 +1987,12 @@ if (no_of_bits <= 8) { pui8 = pui8DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui8, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits); // TODO : Change get_masked_bits8() writeIndex -= no_of_bits; guint8 ui8 = get_masked_bits8(vector, writeIndex, bit_offset, no_of_bits); writeIndex -= no_of_bits; - bitvec_write_field(vector, writeIndex, ui8, no_of_bits); + bitvec_write_field(vector, &writeIndex, ui8, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); } @@ -2030,7 +2030,7 @@ pui8 = pui8DATA(data, pDescr->offset); do { - bitvec_write_field(vector, writeIndex, *pui8, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; bit_offset += no_of_bits; @@ -2112,13 +2112,13 @@ if (no_of_bits <= 32) { pui32 = pui32DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui32, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui32, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %d | ", pDescr->sz , *pui32); } else if (no_of_bits <= 64) { pui64 = pui64DATA(data, pDescr->offset); - bitvec_write_field(vector, writeIndex, *pui64, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui64, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %lu | ", pDescr->sz , *pui64); } else @@ -2176,7 +2176,7 @@ unsigned exist = 0; pui8 = pui8DATA(data, pDescr->offset); exist = *pui8; - bitvec_write_field(vector, writeIndex, *pui8, 1); + bitvec_write_field(vector, &writeIndex, *pui8, 1); writeIndex--; if (CSN_EXIST_LH == pDescr->type) { @@ -2184,10 +2184,10 @@ } else { - fExist = bitvec_read_field(vector, writeIndex, 1); + fExist = bitvec_read_field(vector, &writeIndex, 1); } writeIndex--; - bitvec_write_field(vector, writeIndex, fExist, 1); + bitvec_write_field(vector, &writeIndex, fExist, 1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz, (unsigned)fExist); pDescr++; remaining_bits_len -= 1; @@ -2217,7 +2217,7 @@ break; } - bitvec_write_field(vector, writeIndex, *pui8, 1); + bitvec_write_field(vector, &writeIndex, *pui8, 1); fExist = *pui8; LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); remaining_bits_len -= 1; @@ -2257,11 +2257,11 @@ } /* the "regular" M_NEXT_EXIST_LH description element */ - bitvec_write_field(vector, writeIndex, *pui8, 1); + bitvec_write_field(vector, &writeIndex, *pui8, 1); writeIndex--; fExist = get_masked_bits8(vector,writeIndex, bit_offset, 1); writeIndex--; - bitvec_write_field(vector, writeIndex, fExist, 1); + bitvec_write_field(vector, &writeIndex, fExist, 1); pui8++; remaining_bits_len -= 1; @@ -2310,7 +2310,7 @@ if (nB1 > 0) { /* take care of the first byte - it will be right aligned */ - bitvec_write_field(vector, writeIndex, *pui8, nB1); + bitvec_write_field(vector, &writeIndex, *pui8, nB1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= nB1; @@ -2320,7 +2320,7 @@ /* remaining no_of_bits is a multiple of 8 or 0 */ while (no_of_bits > 0) { - bitvec_write_field(vector, writeIndex, *pui8, 8); + bitvec_write_field(vector, &writeIndex, *pui8, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; @@ -2366,14 +2366,14 @@ while (no_of_bits > 0) { - bitvec_write_field(vector, writeIndex, *pui8, 8); + bitvec_write_field(vector, &writeIndex, *pui8, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= 8; } if (nB1 > 0) { - bitvec_write_field(vector, writeIndex, *pui8, nB1); + bitvec_write_field(vector, &writeIndex, *pui8, nB1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; no_of_bits -= nB1; @@ -2405,14 +2405,14 @@ * < padding bits > ::= { null | 0 < spare padding > ! < Ignore : 1 bit** = < no string > > } ; */ guint8 fl = filler&(0xff>>(8-bits_to_handle + 1)); - bitvec_write_field(vector, writeIndex, fl, bits_to_handle); + bitvec_write_field(vector, &writeIndex, fl, bits_to_handle); LOGPC(DCSN1, LOGL_NOTICE, "%u|", fl); remaining_bits_len -= bits_to_handle; bit_offset += bits_to_handle; } else if (bits_to_handle == 0) { - bitvec_write_field(vector, writeIndex, filler, 8); + bitvec_write_field(vector, &writeIndex, filler, 8); LOGPC(DCSN1, LOGL_NOTICE, "%u|", filler); remaining_bits_len -= 8; bit_offset += 8; @@ -2453,7 +2453,7 @@ while (count > 0) { - bitvec_write_field(vector, writeIndex, *pui8, 8); + bitvec_write_field(vector, &writeIndex, *pui8, 8); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; bit_offset += 8; @@ -2480,13 +2480,13 @@ ElementCount = *pui8DATA(data, (gint16)pDescr->descr.value); while (ElementCount > 0) { /* tag control shows existence of next list elements */ - bitvec_write_field(vector, writeIndex, Tag, 1); + bitvec_write_field(vector, &writeIndex, Tag, 1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag); bit_offset++; remaining_bits_len--; /* extract and store no_of_bits long element from bitstream */ - bitvec_write_field(vector, writeIndex, *pui8, no_of_bits); + bitvec_write_field(vector, &writeIndex, *pui8, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)*pui8); pui8++; remaining_bits_len -= no_of_bits; @@ -2500,7 +2500,7 @@ bit_offset += no_of_bits; } - bitvec_write_field(vector, writeIndex, !Tag, 1); + bitvec_write_field(vector, &writeIndex, !Tag, 1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag)); bit_offset++; remaining_bits_len--; @@ -2522,7 +2522,7 @@ while (ElementCount > 0) { /* tag control shows existence of next list elements */ - bitvec_write_field(vector, writeIndex, Tag, 1); + bitvec_write_field(vector, &writeIndex, Tag, 1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag); bit_offset++; @@ -2553,7 +2553,7 @@ } } - bitvec_write_field(vector, writeIndex, !Tag, 1); + bitvec_write_field(vector, &writeIndex, !Tag, 1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)(!Tag)); bit_offset++; @@ -2591,7 +2591,7 @@ { /* get data element */ if (ElementCount != ElementNum) { - bitvec_write_field(vector, writeIndex, Tag, 1); + bitvec_write_field(vector, &writeIndex, Tag, 1); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)Tag); bit_offset++; remaining_bits_len--; @@ -2618,7 +2618,7 @@ } } - bitvec_write_field(vector, writeIndex, !Tag, 1); + bitvec_write_field(vector, &writeIndex, !Tag, 1); bit_offset++; remaining_bits_len--; Tag = STANDARD_TAG; /* in case it was set to "reversed" */ @@ -2629,7 +2629,7 @@ case CSN_FIXED: { /* Verify the fixed bits */ guint8 no_of_bits = (guint8) pDescr->i; - bitvec_write_field(vector, writeIndex, pDescr->offset, no_of_bits); + bitvec_write_field(vector, &writeIndex, pDescr->offset, no_of_bits); LOGPC(DCSN1, LOGL_NOTICE, "%s = %u | ", pDescr->sz , (unsigned)pDescr->offset); remaining_bits_len -= no_of_bits; bit_offset += no_of_bits; diff --git a/src/csn1.h b/src/csn1.h index 96f7558..3f5b849 100644 --- a/src/csn1.h +++ b/src/csn1.h @@ -25,7 +25,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <bitvector.h> +extern "C" { +#include <osmocom/core/bitvec.h> +} + #include <iostream> #include <cstdlib> #ifndef _PACKET_CSN1_H_ diff --git a/src/egprs_rlc_compression.cpp b/src/egprs_rlc_compression.cpp index 82605ff..7eeb7d2 100644 --- a/src/egprs_rlc_compression.cpp +++ b/src/egprs_rlc_compression.cpp @@ -528,10 +528,10 @@ /* put run length of Ones in uncompressed bitmap */ while (run_length != 0) { if (run_length > 8) { - bitvec_write_field(dest, wp, data, 8); + bitvec_write_field(dest, &wp, data, 8); run_length = run_length - 8; } else { - bitvec_write_field(dest, wp, data, run_length); + bitvec_write_field(dest, &wp, data, run_length); run_length = 0; } } @@ -581,7 +581,7 @@ *codewrd_bitmap = t4_term[start][*run_len_cnt]; *codewrd_len = t4_term_length[start][*run_len_cnt]; } - bitvec_write_field(crbb_vec, writeIndex, *codewrd_bitmap, *codewrd_len); + bitvec_write_field(crbb_vec, &writeIndex, *codewrd_bitmap, *codewrd_len); } /* Compress received block bitmap */ diff --git a/src/encoding.cpp b/src/encoding.cpp index ea38b77..ed8fdaa 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -40,12 +40,12 @@ static inline bool write_tai(bitvec *dest, unsigned& wp, int8_t tai) { if (tai < 0) { /* No TIMING_ADVANCE_INDEX: */ - bitvec_write_field(dest, wp, 0, 1); + bitvec_write_field(dest, &wp, 0, 1); return false; } /* TIMING_ADVANCE_INDEX: */ - bitvec_write_field(dest, wp, 1, 1); - bitvec_write_field(dest, wp, tai, 4); + bitvec_write_field(dest, &wp, 1, 1); + bitvec_write_field(dest, &wp, tai, 4); return true; } @@ -53,10 +53,10 @@ static inline void write_ta(bitvec *dest, unsigned& wp, int8_t ta) { if (ta < 0) /* No TIMING_ADVANCE_VALUE: */ - bitvec_write_field(dest, wp, 0, 1); + bitvec_write_field(dest, &wp, 0, 1); else { /* TIMING_ADVANCE_VALUE: */ - bitvec_write_field(dest, wp, 1, 1); - bitvec_write_field(dest, wp, ta, 6); + bitvec_write_field(dest, &wp, 1, 1); + bitvec_write_field(dest, &wp, ta, 6); } } @@ -70,7 +70,7 @@ { write_ta(dest, wp, ta); if (write_tai(dest, wp, tai)) /* TIMING_ADVANCE_TIMESLOT_NUMBER: */ - bitvec_write_field(dest, wp, ts, 3); + bitvec_write_field(dest, &wp, ts, 3); } static int write_ia_rest_downlink( @@ -85,40 +85,40 @@ return -EINVAL; } // GSM 04.08 10.5.2.16 IA Rest Octets - bitvec_write_field_lh(dest, wp, 3, 2); // "HH" - bitvec_write_field(dest, wp, 1, 2); // "01" Packet Downlink Assignment - bitvec_write_field(dest, wp,tbf->tlli(),32); // TLLI - bitvec_write_field(dest, wp,0x1,1); // switch TFI : on - bitvec_write_field(dest, wp,tbf->tfi(),5); // TFI - bitvec_write_field(dest, wp,0x0,1); // RLC acknowledged mode + bitvec_write_field(dest, &wp, 3, 2); // "HH" + bitvec_write_field(dest, &wp, 1, 2); // "01" Packet Downlink Assignment + bitvec_write_field(dest, &wp,tbf->tlli(),32); // TLLI + bitvec_write_field(dest, &wp,0x1,1); // switch TFI : on + bitvec_write_field(dest, &wp,tbf->tfi(),5); // TFI + bitvec_write_field(dest, &wp,0x0,1); // RLC acknowledged mode if (alpha) { - bitvec_write_field(dest, wp,0x1,1); // ALPHA = present - bitvec_write_field(dest, wp,alpha,4); // ALPHA + bitvec_write_field(dest, &wp,0x1,1); // ALPHA = present + bitvec_write_field(dest, &wp,alpha,4); // ALPHA } else { - bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present + bitvec_write_field(dest, &wp,0x0,1); // ALPHA = not present } - bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter - bitvec_write_field(dest, wp,polling,1); // Polling Bit - bitvec_write_field(dest, wp, ta_valid, 1); // N. B: NOT related to TAI! + bitvec_write_field(dest, &wp,gamma,5); // GAMMA power control parameter + bitvec_write_field(dest, &wp,polling,1); // Polling Bit + bitvec_write_field(dest, &wp, ta_valid, 1); // N. B: NOT related to TAI! write_tai(dest, wp, ta_idx); if (polling) { - bitvec_write_field(dest, wp,0x1,1); // TBF Starting TIME present - bitvec_write_field(dest, wp,(fn / (26 * 51)) % 32,5); // T1' - bitvec_write_field(dest, wp,fn % 51,6); // T3 - bitvec_write_field(dest, wp,fn % 26,5); // T2 + bitvec_write_field(dest, &wp,0x1,1); // TBF Starting TIME present + bitvec_write_field(dest, &wp,(fn / (26 * 51)) % 32,5); // T1' + bitvec_write_field(dest, &wp,fn % 51,6); // T3 + bitvec_write_field(dest, &wp,fn % 26,5); // T2 } else { - bitvec_write_field(dest, wp,0x0,1); // TBF Starting TIME present + bitvec_write_field(dest, &wp,0x0,1); // TBF Starting TIME present } - bitvec_write_field(dest, wp,0x0,1); // P0 not present - // bitvec_write_field(dest, wp,0x1,1); // P0 not present - // bitvec_write_field(dest, wp,0xb,4); + bitvec_write_field(dest, &wp,0x0,1); // P0 not present + // bitvec_write_field(dest, &wp,0x1,1); // P0 not present + // bitvec_write_field(dest, &wp,,0xb,4); if (tbf->is_egprs_enabled()) { /* see GMS 44.018, 10.5.2.16 */ unsigned int ws_enc = (tbf->m_window.ws() - 64) / 32; - bitvec_write_field_lh(dest, wp, 1, 1); // "H" - bitvec_write_field(dest, wp, ws_enc,5); // EGPRS Window Size - bitvec_write_field(dest, wp, 0x0,2); // LINK_QUALITY_MEASUREMENT_MODE - bitvec_write_field(dest, wp, 0,1); // BEP_PERIOD2 not present + bitvec_write_field(dest, &wp, 1, 1); // "H" + bitvec_write_field(dest, &wp, ws_enc, 5); // EGPRS Window Size + bitvec_write_field(dest, &wp, 0x0, 2); // LINK_QUALITY_MEASUREMENT_MODE + bitvec_write_field(dest, &wp, 0, 1); // BEP_PERIOD2 not present } return 0; @@ -133,40 +133,40 @@ OSMO_ASSERT(!tbf || !tbf->is_egprs_enabled()); // GMS 04.08 10.5.2.37b 10.5.2.16 - bitvec_write_field_lh(dest, wp, 3, 2); // "HH" - bitvec_write_field(dest, wp, 0, 2); // "0" Packet Uplink Assignment + bitvec_write_field(dest, &wp, 3, 2); // "HH" + bitvec_write_field(dest, &wp, 0, 2); // "0" Packet Uplink Assignment if (tbf == NULL) { - bitvec_write_field(dest, wp, 0, 1); // Block Allocation : Single Block Allocation + bitvec_write_field(dest, &wp, 0, 1); // Block Allocation : Single Block Allocation if (alpha) { - bitvec_write_field(dest, wp,0x1,1); // ALPHA = present - bitvec_write_field(dest, wp,alpha,4); // ALPHA = present + bitvec_write_field(dest, &wp,0x1,1); // ALPHA = present + bitvec_write_field(dest, &wp,alpha,4); // ALPHA = present } else - bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present - bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter + bitvec_write_field(dest, &wp,0x0,1); // ALPHA = not present + bitvec_write_field(dest, &wp,gamma,5); // GAMMA power control parameter write_tai(dest, wp, ta_idx); - bitvec_write_field(dest, wp, 1, 1); // TBF_STARTING_TIME_FLAG - bitvec_write_field(dest, wp,(fn / (26 * 51)) % 32,5); // T1' - bitvec_write_field(dest, wp,fn % 51,6); // T3 - bitvec_write_field(dest, wp,fn % 26,5); // T2 + bitvec_write_field(dest, &wp, 1, 1); // TBF_STARTING_TIME_FLAG + bitvec_write_field(dest, &wp,(fn / (26 * 51)) % 32,5); // T1' + bitvec_write_field(dest, &wp,fn % 51,6); // T3 + bitvec_write_field(dest, &wp,fn % 26,5); // T2 } else { - bitvec_write_field(dest, wp, 1, 1); // Block Allocation : Not Single Block Allocation - bitvec_write_field(dest, wp, tbf->tfi(), 5); // TFI_ASSIGNMENT Temporary Flow Identity - bitvec_write_field(dest, wp, 0, 1); // POLLING - bitvec_write_field(dest, wp, 0, 1); // ALLOCATION_TYPE: dynamic - bitvec_write_field(dest, wp, usf, 3); // USF - bitvec_write_field(dest, wp, 0, 1); // USF_GRANULARITY - bitvec_write_field(dest, wp, 0, 1); // "0" power control: Not Present - bitvec_write_field(dest, wp, tbf->current_cs().to_num()-1, 2); // CHANNEL_CODING_COMMAND - bitvec_write_field(dest, wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING + bitvec_write_field(dest, &wp, 1, 1); // Block Allocation : Not Single Block Allocation + bitvec_write_field(dest, &wp, tbf->tfi(), 5); // TFI_ASSIGNMENT Temporary Flow Identity + bitvec_write_field(dest, &wp, 0, 1); // POLLING + bitvec_write_field(dest, &wp, 0, 1); // ALLOCATION_TYPE: dynamic + bitvec_write_field(dest, &wp, usf, 3); // USF + bitvec_write_field(dest, &wp, 0, 1); // USF_GRANULARITY + bitvec_write_field(dest, &wp, 0, 1); // "0" power control: Not Present + bitvec_write_field(dest, &wp, tbf->current_cs().to_num()-1, 2); // CHANNEL_CODING_COMMAND + bitvec_write_field(dest, &wp, 1, 1); // TLLI_BLOCK_CHANNEL_CODING if (alpha) { - bitvec_write_field(dest, wp,0x1,1); // ALPHA = present - bitvec_write_field(dest, wp,alpha,4); // ALPHA + bitvec_write_field(dest, &wp,0x1,1); // ALPHA = present + bitvec_write_field(dest, &wp,alpha,4); // ALPHA } else - bitvec_write_field(dest, wp,0x0,1); // ALPHA = not present - bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter + bitvec_write_field(dest, &wp,0x0,1); // ALPHA = not present + bitvec_write_field(dest, &wp,gamma,5); // GAMMA power control parameter /* note: there is no choise for TAI and no starting time */ - bitvec_write_field(dest, wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off - bitvec_write_field(dest, wp, 0, 1); // TBF_STARTING_TIME_FLAG + bitvec_write_field(dest, &wp, 0, 1); // switch TIMING_ADVANCE_INDEX = off + bitvec_write_field(dest, &wp, 0, 1); // TBF_STARTING_TIME_FLAG } return 0; } @@ -183,60 +183,60 @@ extended_ra = (ra & 0x1F); - bitvec_write_field(dest, wp, 1, 2); /* LH */ - bitvec_write_field(dest, wp, 0, 2); /* 0 EGPRS Uplink Assignment */ - bitvec_write_field(dest, wp, extended_ra, 5); /* Extended RA */ - bitvec_write_field(dest, wp, 0, 1); /* Access technology Request */ + bitvec_write_field(dest, &wp, 1, 2); /* LH */ + bitvec_write_field(dest, &wp, 0, 2); /* 0 EGPRS Uplink Assignment */ + bitvec_write_field(dest, &wp, extended_ra, 5); /* Extended RA */ + bitvec_write_field(dest, &wp, 0, 1); /* Access technology Request */ if (tbf == NULL) { - bitvec_write_field(dest, wp, 0, 1); /* multiblock allocation */ + bitvec_write_field(dest, &wp, 0, 1); /* multiblock allocation */ if (alpha) { - bitvec_write_field(dest, wp, 0x1, 1); /* ALPHA =yes */ - bitvec_write_field(dest, wp, alpha, 4); /* ALPHA */ + bitvec_write_field(dest, &wp, 0x1, 1); /* ALPHA =yes */ + bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */ } else { - bitvec_write_field(dest, wp, 0x0, 1); /* ALPHA = no */ + bitvec_write_field(dest, &wp, 0x0, 1); /* ALPHA = no */ } - bitvec_write_field(dest, wp, gamma, 5); /* GAMMA power contrl */ - bitvec_write_field(dest, wp, (fn / (26 * 51)) % 32, 5);/* T1' */ - bitvec_write_field(dest, wp, fn % 51, 6); /* T3 */ - bitvec_write_field(dest, wp, fn % 26, 5); /* T2 */ - bitvec_write_field(dest, wp, 0, 2); /* Radio block allocation */ + bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */ + bitvec_write_field(dest, &wp, (fn / (26 * 51)) % 32, 5);/* T1' */ + bitvec_write_field(dest, &wp, fn % 51, 6); /* T3 */ + bitvec_write_field(dest, &wp, fn % 26, 5); /* T2 */ + bitvec_write_field(dest, &wp, 0, 2); /* Radio block allocation */ - bitvec_write_field(dest, wp, 0, 1); + bitvec_write_field(dest, &wp, 0, 1); } else { ws_enc = (tbf->m_window.ws() - 64) / 32; - bitvec_write_field(dest, wp, 1, 1); /* single block alloc */ - bitvec_write_field(dest, wp, tbf->tfi(), 5);/* TFI assignment */ - bitvec_write_field(dest, wp, 0, 1); /* polling bit */ - bitvec_write_field(dest, wp, 0, 1); /* constant */ - bitvec_write_field(dest, wp, usf, 3); /* USF bit */ - bitvec_write_field(dest, wp, 0, 1); /* USF granularity */ - bitvec_write_field(dest, wp, 0, 1); /* P0 */ + bitvec_write_field(dest, &wp, 1, 1); /* single block alloc */ + bitvec_write_field(dest, &wp, tbf->tfi(), 5);/* TFI assignment */ + bitvec_write_field(dest, &wp, 0, 1); /* polling bit */ + bitvec_write_field(dest, &wp, 0, 1); /* constant */ + bitvec_write_field(dest, &wp, usf, 3); /* USF bit */ + bitvec_write_field(dest, &wp, 0, 1); /* USF granularity */ + bitvec_write_field(dest, &wp, 0, 1); /* P0 */ /* MCS */ - bitvec_write_field(dest, wp, tbf->current_cs().to_num()-1, 4); + bitvec_write_field(dest, &wp, tbf->current_cs().to_num()-1, 4); /* tlli channel block */ - bitvec_write_field(dest, wp, tbf->tlli(), 1); - bitvec_write_field(dest, wp, 0, 1); /* BEP period present */ - bitvec_write_field(dest, wp, 0, 1); /* resegmentation */ - bitvec_write_field(dest, wp, ws_enc, 5);/* egprs window_size */ + bitvec_write_field(dest, &wp, tbf->tlli(), 1); + bitvec_write_field(dest, &wp, 0, 1); /* BEP period present */ + bitvec_write_field(dest, &wp, 0, 1); /* resegmentation */ + bitvec_write_field(dest, &wp, ws_enc, 5);/* egprs window_size */ if (alpha) { - bitvec_write_field(dest, wp, 0x1, 1); /* ALPHA =yes */ - bitvec_write_field(dest, wp, alpha, 4); /* ALPHA */ + bitvec_write_field(dest, &wp, 0x1, 1); /* ALPHA =yes */ + bitvec_write_field(dest, &wp, alpha, 4); /* ALPHA */ } else { - bitvec_write_field(dest, wp, 0x0, 1); /* ALPHA = no */ + bitvec_write_field(dest, &wp, 0x0, 1); /* ALPHA = no */ } - bitvec_write_field(dest, wp, gamma, 5); /* GAMMA power contrl */ - bitvec_write_field(dest, wp, 0, 1); /* TIMING_ADVANCE_INDEX */ - bitvec_write_field(dest, wp, 0, 1); /* TBF_STARTING_TIME_FLAG */ - bitvec_write_field(dest, wp, 0, 1); /* NULL */ + bitvec_write_field(dest, &wp, gamma, 5); /* GAMMA power contrl */ + bitvec_write_field(dest, &wp, 0, 1); /* TIMING_ADVANCE_INDEX */ + bitvec_write_field(dest, &wp, 0, 1); /* TBF_STARTING_TIME_FLAG */ + bitvec_write_field(dest, &wp, 0, 1); /* NULL */ } return 0; @@ -255,17 +255,17 @@ int plen; int i; - bitvec_write_field(dest, wp, 0x0, 4); // Skip Indicator - bitvec_write_field(dest, wp, 0x6, 4); // Protocol Discriminator - bitvec_write_field(dest, wp, 0x3A, 8); // Immediate Assign Message Type + bitvec_write_field(dest, &wp, 0x0, 4); // Skip Indicator + bitvec_write_field(dest, &wp, 0x6, 4); // Protocol Discriminator + bitvec_write_field(dest, &wp, 0x3A, 8); // Immediate Assign Message Type // feature indicator - bitvec_write_field(dest, wp, 0x0, 1); // spare - bitvec_write_field(dest, wp, 0x0, 1); // spare - bitvec_write_field(dest, wp, 0x0, 1); // no cs - bitvec_write_field(dest, wp, 0x1, 1); // implicit detach for PS + bitvec_write_field(dest, &wp, 0x0, 1); // spare + bitvec_write_field(dest, &wp, 0x0, 1); // spare + bitvec_write_field(dest, &wp, 0x0, 1); // no cs + bitvec_write_field(dest, &wp, 0x1, 1); // implicit detach for PS - bitvec_write_field(dest, wp, 0x0, 4); // Page Mode + bitvec_write_field(dest, &wp, 0x0, 4); // Page Mode /* * 9.1.20.2 of 44.018 version 11.7.0 Release 11 * Filling of the message @@ -279,18 +279,18 @@ if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { //9.1.20.2a of 44.018 version 11.7.0 Release 11 - bitvec_write_field(dest, wp, 0x7f, 8); /* RACH value */ + bitvec_write_field(dest, &wp, 0x7f, 8); /* RACH value */ } else { - bitvec_write_field(dest, wp, ra, 8); /* RACH value */ + bitvec_write_field(dest, &wp, ra, 8); /* RACH value */ } - bitvec_write_field(dest, wp, + bitvec_write_field(dest, &wp, (ref_fn / (26 * 51)) % 32, 5); // T1' - bitvec_write_field(dest, wp, ref_fn % 51, 6); // T3 - bitvec_write_field(dest, wp, ref_fn % 26, 5); // T2 + bitvec_write_field(dest, &wp, ref_fn % 51, 6); // T3 + bitvec_write_field(dest, &wp, ref_fn % 26, 5); // T2 /* TODO: Make it configurable */ - bitvec_write_field(dest, wp, 20, 8); //Wait Indication 1 + bitvec_write_field(dest, &wp, 20, 8); //Wait Indication 1 } plen = wp / 8; @@ -308,14 +308,14 @@ uint8_t extended_ra = 0; extended_ra = (ra & 0x1F); - bitvec_write_field(dest, wp, 0x1, 1); - bitvec_write_field(dest, wp, extended_ra, 5); /* Extended RA */ + bitvec_write_field(dest, &wp, 0x1, 1); + bitvec_write_field(dest, &wp, extended_ra, 5); /* Extended RA */ } else { - bitvec_write_field(dest, wp, 0x0, 1); + bitvec_write_field(dest, &wp, 0x0, 1); } - bitvec_write_field(dest, wp, 0x0, 1); - bitvec_write_field(dest, wp, 0x0, 1); - bitvec_write_field(dest, wp, 0x0, 1); + bitvec_write_field(dest, &wp, 0x0, 1); + bitvec_write_field(dest, &wp, 0x0, 1); + bitvec_write_field(dest, &wp, 0x0, 1); return plen; } @@ -335,44 +335,44 @@ int plen; int rc; - bitvec_write_field(dest, wp,0x0,4); // Skip Indicator - bitvec_write_field(dest, wp,0x6,4); // Protocol Discriminator - bitvec_write_field(dest, wp,0x3F,8); // Immediate Assignment Message Type + bitvec_write_field(dest, &wp,0x0,4); // Skip Indicator + bitvec_write_field(dest, &wp,0x6,4); // Protocol Discriminator + bitvec_write_field(dest, &wp,0x3F,8); // Immediate Assignment Message Type // 10.5.2.25b Dedicated mode or TBF - bitvec_write_field(dest, wp,0x0,1); // spare - bitvec_write_field(dest, wp,0x0,1); // TMA : Two-message assignment: No meaning - bitvec_write_field(dest, wp,downlink,1); // Downlink : Downlink assignment to mobile in packet idle mode - bitvec_write_field(dest, wp,0x1,1); // T/D : TBF or dedicated mode: this message assigns a Temporary Block Flow (TBF). + bitvec_write_field(dest, &wp,0x0,1); // spare + bitvec_write_field(dest, &wp,0x0,1); // TMA : Two-message assignment: No meaning + bitvec_write_field(dest, &wp,downlink,1); // Downlink : Downlink assignment to mobile in packet idle mode + bitvec_write_field(dest, &wp,0x1,1); // T/D : TBF or dedicated mode: this message assigns a Temporary Block Flow (TBF). - bitvec_write_field(dest, wp,0x0,4); // Page Mode + bitvec_write_field(dest, &wp,0x0,4); // Page Mode // GSM 04.08 10.5.2.25a Packet Channel Description - bitvec_write_field(dest, wp,0x1,5); // Channel type - bitvec_write_field(dest, wp,ts,3); // TN - bitvec_write_field(dest, wp,tsc,3); // TSC - bitvec_write_field(dest, wp,0x0,3); // non-hopping RF channel configuraion - bitvec_write_field(dest, wp,arfcn,10); // ARFCN + bitvec_write_field(dest, &wp,0x1,5); // Channel type + bitvec_write_field(dest, &wp,ts,3); // TN + bitvec_write_field(dest, &wp,tsc,3); // TSC + bitvec_write_field(dest, &wp,0x0,3); // non-hopping RF channel configuraion + bitvec_write_field(dest, &wp,arfcn,10); // ARFCN //10.5.2.30 Request Reference if (((burst_type == GSM_L1_BURST_TYPE_ACCESS_1) || (burst_type == GSM_L1_BURST_TYPE_ACCESS_2))) { - bitvec_write_field(dest, wp, 0x7f, 8); /* RACH value */ + bitvec_write_field(dest, &wp, 0x7f, 8); /* RACH value */ } else { - bitvec_write_field(dest, wp, ra, 8); /* RACH value */ + bitvec_write_field(dest, &wp, ra, 8); /* RACH value */ } - bitvec_write_field(dest, wp,(ref_fn / (26 * 51)) % 32,5); // T1' - bitvec_write_field(dest, wp,ref_fn % 51,6); // T3 - bitvec_write_field(dest, wp,ref_fn % 26,5); // T2 + bitvec_write_field(dest, &wp,(ref_fn / (26 * 51)) % 32,5); // T1' + bitvec_write_field(dest, &wp,ref_fn % 51,6); // T3 + bitvec_write_field(dest, &wp,ref_fn % 26,5); // T2 // 10.5.2.40 Timing Advance - bitvec_write_field(dest, wp,0x0,2); // spare - bitvec_write_field(dest, wp,ta,6); // Timing Advance value + bitvec_write_field(dest, &wp,0x0,2); // spare + bitvec_write_field(dest, &wp,ta,6); // Timing Advance value // No mobile allocation in non-hopping systems. // A zero-length LV. Just write L=0. - bitvec_write_field(dest, wp,0,8); + bitvec_write_field(dest, &wp,0,8); if ((wp % 8)) { LOGP(DRLCMACUL, LOGL_ERROR, "Length of IMM.ASS without rest " @@ -420,83 +420,83 @@ /* timeslot assigned for the Continuous Timing Advance procedure */ uint8_t ta_ts = 0; /* FIXME: supply it as parameter from caller */ - bitvec_write_field(dest, wp,0x1,2); // Payload Type - bitvec_write_field(dest, wp,0x0,2); // Uplink block with TDMA framenumber (N+13) - bitvec_write_field(dest, wp,poll,1); // Suppl/Polling Bit - bitvec_write_field(dest, wp,0x0,3); // Uplink state flag - bitvec_write_field(dest, wp,0xa,6); // MESSAGE TYPE + bitvec_write_field(dest, &wp,0x1,2); // Payload Type + bitvec_write_field(dest, &wp,0x0,2); // Uplink block with TDMA framenumber (N+13) + bitvec_write_field(dest, &wp,poll,1); // Suppl/Polling Bit + bitvec_write_field(dest, &wp,0x0,3); // Uplink state flag + bitvec_write_field(dest, &wp,0xa,6); // MESSAGE TYPE - bitvec_write_field(dest, wp,0x0,2); // Page Mode + bitvec_write_field(dest, &wp,0x0,2); // Page Mode - bitvec_write_field(dest, wp,0x0,1); // switch PERSIST_LEVEL: off + bitvec_write_field(dest, &wp,0x0,1); // switch PERSIST_LEVEL: off if (use_tlli) { - bitvec_write_field(dest, wp,0x2,2); // switch TLLI : on - bitvec_write_field(dest, wp,tlli,32); // TLLI + bitvec_write_field(dest, &wp,0x2,2); // switch TLLI : on + bitvec_write_field(dest, &wp,tlli,32); // TLLI } else { - bitvec_write_field(dest, wp,0x0,1); // switch TFI : on - bitvec_write_field(dest, wp,old_downlink,1); // 0=UPLINK TFI, 1=DL TFI - bitvec_write_field(dest, wp,old_tfi,5); // TFI + bitvec_write_field(dest, &wp,0x0,1); // switch TFI : on + bitvec_write_field(dest, &wp,old_downlink,1); // 0=UPLINK TFI, 1=DL TFI + bitvec_write_field(dest, &wp,old_tfi,5); // TFI } if (!use_egprs) { - bitvec_write_field(dest, wp,0x0,1); // Message escape - bitvec_write_field(dest, wp,tbf->current_cs().to_num()-1, 2); // CHANNEL_CODING_COMMAND - bitvec_write_field(dest, wp,0x1,1); // TLLI_BLOCK_CHANNEL_CODING + bitvec_write_field(dest, &wp,0x0,1); // Message escape + bitvec_write_field(dest, &wp,tbf->current_cs().to_num()-1, 2); // CHANNEL_CODING_COMMAND + bitvec_write_field(dest, &wp,0x1,1); // TLLI_BLOCK_CHANNEL_CODING write_ta_ie(dest, wp,tbf->ta(), ta_idx, ta_ts); } else { /* EPGRS */ unsigned int ws_enc = (tbf->m_window.ws() - 64) / 32; - bitvec_write_field(dest, wp,0x1,1); // Message escape - bitvec_write_field(dest, wp,0x0,2); // EGPRS message contents - bitvec_write_field(dest, wp,0x0,1); // No CONTENTION_RESOLUTION_TLLI - bitvec_write_field(dest, wp,0x0,1); // No COMPACT reduced MA - bitvec_write_field(dest, wp,tbf->current_cs().to_num()-1, 4); // EGPRS Modulation and Coding IE + bitvec_write_field(dest, &wp,0x1,1); // Message escape + bitvec_write_field(dest, &wp,0x0,2); // EGPRS message contents + bitvec_write_field(dest, &wp,0x0,1); // No CONTENTION_RESOLUTION_TLLI + bitvec_write_field(dest, &wp,0x0,1); // No COMPACT reduced MA + bitvec_write_field(dest, &wp,tbf->current_cs().to_num()-1, 4); // EGPRS Modulation and Coding IE /* 0: no RESEGMENT, 1: Segmentation*/ - bitvec_write_field(dest, wp, 0x1, 1); - bitvec_write_field(dest, wp,ws_enc,5); // EGPRS Window Size - bitvec_write_field(dest, wp,0x0,1); // No Access Technologies Request - bitvec_write_field(dest, wp,0x0,1); // No ARAC RETRANSMISSION REQUEST - bitvec_write_field(dest, wp,0x1,1); // TLLI_BLOCK_CHANNEL_CODING - bitvec_write_field(dest, wp,0x0,1); // No BEP_PERIOD2 + bitvec_write_field(dest, &wp, 0x1, 1); + bitvec_write_field(dest, &wp,ws_enc,5); // EGPRS Window Size + bitvec_write_field(dest, &wp,0x0,1); // No Access Technologies Request + bitvec_write_field(dest, &wp,0x0,1); // No ARAC RETRANSMISSION REQUEST + bitvec_write_field(dest, &wp,0x1,1); // TLLI_BLOCK_CHANNEL_CODING + bitvec_write_field(dest, &wp,0x0,1); // No BEP_PERIOD2 write_ta_ie(dest, wp,tbf->ta(), ta_idx, ta_ts); - bitvec_write_field(dest, wp,0x0,1); // No Packet Extended Timing Advance + bitvec_write_field(dest, &wp,0x0,1); // No Packet Extended Timing Advance } #if 1 - bitvec_write_field(dest, wp,0x1,1); // Frequency Parameters information elements = present - bitvec_write_field(dest, wp,tbf->tsc(),3); // Training Sequence Code (TSC) - bitvec_write_field(dest, wp,0x0,2); // ARFCN = present - bitvec_write_field(dest, wp,tbf->trx->arfcn,10); // ARFCN + bitvec_write_field(dest, &wp,0x1,1); // Frequency Parameters information elements = present + bitvec_write_field(dest, &wp,tbf->tsc(),3); // Training Sequence Code (TSC) + bitvec_write_field(dest, &wp,0x0,2); // ARFCN = present + bitvec_write_field(dest, &wp,tbf->trx->arfcn,10); // ARFCN #else - bitvec_write_field(dest, wp,0x0,1); // Frequency Parameters = off + bitvec_write_field(dest, &wp,0x0,1); // Frequency Parameters = off #endif - bitvec_write_field(dest, wp,0x1,2); // Dynamic Allocation + bitvec_write_field(dest, &wp,0x1,2); // Dynamic Allocation - bitvec_write_field(dest, wp,0x0,1); // Extended Dynamic Allocation = off - bitvec_write_field(dest, wp,0x0,1); // P0 = off + bitvec_write_field(dest, &wp,0x0,1); // Extended Dynamic Allocation = off + bitvec_write_field(dest, &wp,0x0,1); // P0 = off - bitvec_write_field(dest, wp,0x0,1); // USF_GRANULARITY - bitvec_write_field(dest, wp,0x1,1); // switch TFI : on - bitvec_write_field(dest, wp,tbf->tfi(),5);// TFI + bitvec_write_field(dest, &wp,0x0,1); // USF_GRANULARITY + bitvec_write_field(dest, &wp,0x1,1); // switch TFI : on + bitvec_write_field(dest, &wp,tbf->tfi(),5);// TFI - bitvec_write_field(dest, wp,0x0,1); // - bitvec_write_field(dest, wp,0x0,1); // TBF Starting Time = off + bitvec_write_field(dest, &wp,0x0,1); // + bitvec_write_field(dest, &wp,0x0,1); // TBF Starting Time = off if (alpha || gamma) { - bitvec_write_field(dest, wp,0x1,1); // Timeslot Allocation with Power Control - bitvec_write_field(dest, wp,alpha,4); // ALPHA + bitvec_write_field(dest, &wp,0x1,1); // Timeslot Allocation with Power Control + bitvec_write_field(dest, &wp,alpha,4); // ALPHA } else - bitvec_write_field(dest, wp,0x0,1); // Timeslot Allocation + bitvec_write_field(dest, &wp,0x0,1); // Timeslot Allocation for (ts = 0; ts < 8; ts++) { if (tbf->pdch[ts]) { - bitvec_write_field(dest, wp,0x1,1); // USF_TN(i): on - bitvec_write_field(dest, wp,tbf->m_usf[ts],3); // USF_TN(i) + bitvec_write_field(dest, &wp,0x1,1); // USF_TN(i): on + bitvec_write_field(dest, &wp,tbf->m_usf[ts],3); // USF_TN(i) if (alpha || gamma) - bitvec_write_field(dest, wp,gamma,5); // GAMMA power control parameter + bitvec_write_field(dest, &wp,gamma,5); // GAMMA power control parameter } else - bitvec_write_field(dest, wp,0x0,1); // USF_TN(i): off + bitvec_write_field(dest, &wp,0x0,1); // USF_TN(i): off } - // bitvec_write_field(dest, wp,0x0,1); // Measurement Mapping struct not present + // bitvec_write_field(dest, &wp,0x0,1); // Measurement Mapping struct not present } @@ -603,20 +603,20 @@ unsigned wp = 0; int plen; - bitvec_write_field(dest, wp,0x0,4); // Skip Indicator - bitvec_write_field(dest, wp,0x6,4); // Protocol Discriminator - bitvec_write_field(dest, wp,0x21,8); // Paging Request Message Type + bitvec_write_field(dest, &wp,0x0,4); // Skip Indicator + bitvec_write_field(dest, &wp,0x6,4); // Protocol Discriminator + bitvec_write_field(dest, &wp,0x21,8); // Paging Request Message Type - bitvec_write_field(dest, wp,0x0,4); // Page Mode - bitvec_write_field(dest, wp,0x0,4); // Channel Needed + bitvec_write_field(dest, &wp,0x0,4); // Page Mode + bitvec_write_field(dest, &wp,0x0,4); // Channel Needed // Mobile Identity - bitvec_write_field(dest, wp,ptmsi_len+1,8); // Mobile Identity length - bitvec_write_field(dest, wp,0xf,4); // unused - bitvec_write_field(dest, wp,0x4,4); // PTMSI type + bitvec_write_field(dest, &wp,ptmsi_len+1,8); // Mobile Identity length + bitvec_write_field(dest, &wp,0xf,4); // unused + bitvec_write_field(dest, &wp,0x4,4); // PTMSI type for (int i = 0; i < ptmsi_len; i++) { - bitvec_write_field(dest, wp,ptmsi[i],8); // PTMSI + bitvec_write_field(dest, &wp,ptmsi[i],8); // PTMSI } if ((wp % 8)) { LOGP(DRLCMACUL, LOGL_ERROR, "Length of PAG.REQ without rest " @@ -624,12 +624,12 @@ exit (0); } plen = wp / 8; - bitvec_write_field(dest, wp,0x0,1); // "L" NLN(PCH) = off - bitvec_write_field(dest, wp,0x0,1); // "L" Priority1 = off - bitvec_write_field(dest, wp,0x1,1); // "L" Priority2 = off - bitvec_write_field(dest, wp,0x0,1); // "L" Group Call information = off - bitvec_write_field(dest, wp,0x0,1); // "H" Packet Page Indication 1 = packet paging procedure - bitvec_write_field(dest, wp,0x1,1); // "H" Packet Page Indication 2 = packet paging procedure + bitvec_write_field(dest, &wp,0x0,1); // "L" NLN(PCH) = off + bitvec_write_field(dest, &wp,0x0,1); // "L" Priority1 = off + bitvec_write_field(dest, &wp,0x1,1); // "L" Priority2 = off + bitvec_write_field(dest, &wp,0x0,1); // "L" Group Call information = off + bitvec_write_field(dest, &wp,0x0,1); // "H" Packet Page Indication 1 = packet paging procedure + bitvec_write_field(dest, &wp,0x1,1); // "H" Packet Page Indication 2 = packet paging procedure return plen; } @@ -667,13 +667,13 @@ LOGP(DRLCMACUL, LOGL_DEBUG, "- V(N): \"%s\" R=Received " "I=Invalid\n", rbb); - bitvec_write_field(dest, wp, is_final, 1); // FINAL_ACK_INDICATION - bitvec_write_field(dest, wp, window->ssn(), 7); // STARTING_SEQUENCE_NUMBER + bitvec_write_field(dest, &wp, is_final, 1); // FINAL_ACK_INDICATION + bitvec_write_field(dest, &wp, window->ssn(), 7); // STARTING_SEQUENCE_NUMBER for (int i = 0; i < 64; i++) { /* Set bit at the appropriate position (see 3GPP TS 04.60 9.1.8.1) */ bool is_ack = (rbb[i] == 'R'); - bitvec_write_field(dest, wp, is_ack, 1); + bitvec_write_field(dest, &wp, is_ack, 1); } } @@ -682,20 +682,20 @@ struct gprs_rlcmac_ul_tbf *tbf, bool is_final) { - bitvec_write_field(dest, wp, tbf->current_cs().to_num() - 1, 2); // CHANNEL_CODING_COMMAND + bitvec_write_field(dest, &wp, tbf->current_cs().to_num() - 1, 2); // CHANNEL_CODING_COMMAND write_packet_ack_nack_desc_gprs(bts, dest, wp, &tbf->m_window, is_final); - bitvec_write_field(dest, wp, 1, 1); // 1: have CONTENTION_RESOLUTION_TLLI - bitvec_write_field(dest, wp, tbf->tlli(), 32); // CONTENTION_RESOLUTION_TLLI + bitvec_write_field(dest, &wp, 1, 1); // 1: have CONTENTION_RESOLUTION_TLLI + bitvec_write_field(dest, &wp, tbf->tlli(), 32); // CONTENTION_RESOLUTION_TLLI - bitvec_write_field(dest, wp, 0, 1); // 0: don't have Packet Timing Advance - bitvec_write_field(dest, wp, 0, 1); // 0: don't have Power Control Parameters - bitvec_write_field(dest, wp, 0, 1); // 0: don't have Extension Bits - bitvec_write_field(dest, wp, 0, 1); // fixed 0 - bitvec_write_field(dest, wp, 1, 1); // 1: have Additions R99 - bitvec_write_field(dest, wp, 0, 1); // 0: don't have Packet Extended Timing Advance - bitvec_write_field(dest, wp, 1, 1); // TBF_EST (enabled) - bitvec_write_field(dest, wp, 0, 1); // 0: don't have REL 5 + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have Packet Timing Advance + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have Power Control Parameters + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have Extension Bits + bitvec_write_field(dest, &wp, 0, 1); // fixed 0 + bitvec_write_field(dest, &wp, 1, 1); // 1: have Additions R99 + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have Packet Extended Timing Advance + bitvec_write_field(dest, &wp, 1, 1); // TBF_EST (enabled) + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have REL 5 }; static void write_packet_ack_nack_desc_egprs( @@ -810,37 +810,37 @@ /* EGPRS Ack/Nack Description IE */ if (len_coded == false) { - bitvec_write_field(dest, wp, 0, 1); // 0: don't have length + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have length } else { - bitvec_write_field(dest, wp, 1, 1); // 1: have length - bitvec_write_field(dest, wp, len, 8); // length + bitvec_write_field(dest, &wp, 1, 1); // 1: have length + bitvec_write_field(dest, &wp, len, 8); // length } - bitvec_write_field(dest, wp, is_final, 1); // FINAL_ACK_INDICATION - bitvec_write_field(dest, wp, bow, 1); // BEGINNING_OF_WINDOW - bitvec_write_field(dest, wp, eow, 1); // END_OF_WINDOW - bitvec_write_field(dest, wp, ssn, 11); // STARTING_SEQUENCE_NUMBER + bitvec_write_field(dest, &wp, is_final, 1); // FINAL_ACK_INDICATION + bitvec_write_field(dest, &wp, bow, 1); // BEGINNING_OF_WINDOW + bitvec_write_field(dest, &wp, eow, 1); // END_OF_WINDOW + bitvec_write_field(dest, &wp, ssn, 11); // STARTING_SEQUENCE_NUMBER if (is_compressed) { - bitvec_write_field(dest, wp, 1, 1); // CRBB_Exist - bitvec_write_field(dest, wp, crbb_len, 7); // CRBB_LENGTH + bitvec_write_field(dest, &wp, 1, 1); // CRBB_Exist + bitvec_write_field(dest, &wp, crbb_len, 7); // CRBB_LENGTH crbb_start_clr_code = (0x80 & ucmp_vec.data[0])>>7; - bitvec_write_field(dest, wp, crbb_start_clr_code, 1); // CRBB_clr_code + bitvec_write_field(dest, &wp, crbb_start_clr_code, 1); // CRBB_clr_code LOGP(DRLCMACUL, LOGL_DEBUG, "EGPRS CRBB, crbb_len = %d, crbb_start_clr_code = %d\n", crbb_len, crbb_start_clr_code); while (crbb_len != 0) { if (crbb_len > 8) { - bitvec_write_field(dest, wp, crbb_bitmap[iter], 8); + bitvec_write_field(dest, &wp, crbb_bitmap[iter], 8); crbb_len = crbb_len - 8; iter++; } else { - bitvec_write_field(dest, wp, crbb_bitmap[iter], crbb_len); + bitvec_write_field(dest, &wp, crbb_bitmap[iter], crbb_len); crbb_len = 0; } } esn_crbb = window->mod_sns(esn_crbb + uclen_crbb); } else { - bitvec_write_field(dest, wp, 0, 1); // CRBB_Exist + bitvec_write_field(dest, &wp, 0, 1); // CRBB_Exist } LOGP(DRLCMACUL, LOGL_DEBUG, "EGPRS URBB, urbb len = %d, SSN = %d, ESN_CRBB = %d, " @@ -853,7 +853,7 @@ for (i = urbb_len; i > 0; i--) { /* Set bit at the appropriate position (see 3GPP TS 04.60 12.3.1) */ bool is_ack = window->m_v_n.is_received(esn_crbb + i); - bitvec_write_field(dest, wp, is_ack, 1); + bitvec_write_field(dest, &wp, is_ack, 1); } } @@ -861,29 +861,29 @@ struct gprs_rlcmac_bts *bts, bitvec * dest, unsigned& wp, struct gprs_rlcmac_ul_tbf *tbf, bool is_final) { - bitvec_write_field(dest, wp, 0, 2); // fixed 00 + bitvec_write_field(dest, &wp, 0, 2); // fixed 00 /* CHANNEL_CODING_COMMAND */ - bitvec_write_field(dest, wp, + bitvec_write_field(dest, &wp, tbf->current_cs().to_num() - 1, 4); /* 0: no RESEGMENT, 1: Segmentation*/ - bitvec_write_field(dest, wp, 1, 1); - bitvec_write_field(dest, wp, 1, 1); // PRE_EMPTIVE_TRANSMISSION, TODO: This resembles GPRS, change it? - bitvec_write_field(dest, wp, 0, 1); // 0: no PRR_RETRANSMISSION_REQUEST, TODO: clarify - bitvec_write_field(dest, wp, 0, 1); // 0: no ARAC_RETRANSMISSION_REQUEST, TODO: clarify - bitvec_write_field(dest, wp, 1, 1); // 1: have CONTENTION_RESOLUTION_TLLI - bitvec_write_field(dest, wp, tbf->tlli(), 32); // CONTENTION_RESOLUTION_TLLI - bitvec_write_field(dest, wp, 1, 1); // TBF_EST (enabled) - bitvec_write_field(dest, wp, 0, 1); // 0: don't have Packet Timing Advance - bitvec_write_field(dest, wp, 0, 1); // 0: don't have Packet Extended Timing Advance - bitvec_write_field(dest, wp, 0, 1); // 0: don't have Power Control Parameters - bitvec_write_field(dest, wp, 0, 1); // 0: don't have Extension Bits + bitvec_write_field(dest, &wp, 1, 1); + bitvec_write_field(dest, &wp, 1, 1); // PRE_EMPTIVE_TRANSMISSION, TODO: This resembles GPRS, change it? + bitvec_write_field(dest, &wp, 0, 1); // 0: no PRR_RETRANSMISSION_REQUEST, TODO: clarify + bitvec_write_field(dest, &wp, 0, 1); // 0: no ARAC_RETRANSMISSION_REQUEST, TODO: clarify + bitvec_write_field(dest, &wp, 1, 1); // 1: have CONTENTION_RESOLUTION_TLLI + bitvec_write_field(dest, &wp, tbf->tlli(), 32); // CONTENTION_RESOLUTION_TLLI + bitvec_write_field(dest, &wp, 1, 1); // TBF_EST (enabled) + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have Packet Timing Advance + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have Packet Extended Timing Advance + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have Power Control Parameters + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have Extension Bits /* -2 for last bit 0 mandatory and REL5 not supported */ unsigned bits_ack_nack = dest->data_len * 8 - wp - 2; write_packet_ack_nack_desc_egprs(bts, dest, wp, &tbf->m_window, is_final, bits_ack_nack); - bitvec_write_field(dest, wp, 0, 1); // fixed 0 - bitvec_write_field(dest, wp, 0, 1); // 0: don't have REL 5 + bitvec_write_field(dest, &wp, 0, 1); // fixed 0 + bitvec_write_field(dest, &wp, 0, 1); // 0: don't have REL 5 }; void Encoding::write_packet_uplink_ack( @@ -896,23 +896,23 @@ LOGP(DRLCMACUL, LOGL_DEBUG, "Encoding Ack/Nack for %s " "(final=%d)\n", tbf_name(tbf), is_final); - bitvec_write_field(dest, wp, 0x1, 2); // Payload Type - bitvec_write_field(dest, wp, rrbp, 2); // Uplink block with TDMA framenumber - bitvec_write_field(dest, wp, is_final, 1); // Suppl/Polling Bit - bitvec_write_field(dest, wp, 0x0, 3); // Uplink state flag - bitvec_write_field(dest, wp, 0x9, 6); // MESSAGE TYPE Uplink Ack/Nack - bitvec_write_field(dest, wp, 0x0, 2); // Page Mode + bitvec_write_field(dest, &wp, 0x1, 2); // Payload Type + bitvec_write_field(dest, &wp, rrbp, 2); // Uplink block with TDMA framenumber + bitvec_write_field(dest, &wp, is_final, 1); // Suppl/Polling Bit + bitvec_write_field(dest, &wp, 0x0, 3); // Uplink state flag + bitvec_write_field(dest, &wp, 0x9, 6); // MESSAGE TYPE Uplink Ack/Nack + bitvec_write_field(dest, &wp, 0x0, 2); // Page Mode - bitvec_write_field(dest, wp, 0x0, 2); // fixed 00 - bitvec_write_field(dest, wp, tbf->tfi(), 5); // Uplink TFI + bitvec_write_field(dest, &wp, 0x0, 2); // fixed 00 + bitvec_write_field(dest, &wp, tbf->tfi(), 5); // Uplink TFI if (tbf->is_egprs_enabled()) { /* PU_AckNack_EGPRS = on */ - bitvec_write_field(dest, wp, 1, 1); // 1: EGPRS + bitvec_write_field(dest, &wp, 1, 1); // 1: EGPRS write_packet_uplink_ack_egprs(bts, dest, wp, tbf, is_final); } else { /* PU_AckNack_GPRS = on */ - bitvec_write_field(dest, wp, 0, 1); // 0: GPRS + bitvec_write_field(dest, &wp, 0, 1); // 0: GPRS write_packet_uplink_ack_gprs(bts, dest, wp, tbf, is_final); } @@ -926,15 +926,15 @@ { unsigned wp = 0; - bitvec_write_field(dest, wp,0x1,2); // Payload Type - bitvec_write_field(dest, wp,0x0,3); // No polling - bitvec_write_field(dest, wp,0x0,3); // Uplink state flag - bitvec_write_field(dest, wp,0x22,6); // MESSAGE TYPE + bitvec_write_field(dest, &wp,0x1,2); // Payload Type + bitvec_write_field(dest, &wp,0x0,3); // No polling + bitvec_write_field(dest, &wp,0x0,3); // Uplink state flag + bitvec_write_field(dest, &wp,0x22,6); // MESSAGE TYPE - bitvec_write_field(dest, wp,0x0,2); // Page Mode + bitvec_write_field(dest, &wp,0x0,2); // Page Mode - bitvec_write_field(dest, wp,0x0,1); // No PERSISTENCE_LEVEL - bitvec_write_field(dest, wp,0x0,1); // No NLN + bitvec_write_field(dest, &wp,0x0,1); // No PERSISTENCE_LEVEL + bitvec_write_field(dest, &wp,0x0,1); // No NLN return wp; } @@ -942,24 +942,24 @@ unsigned Encoding::write_repeated_page_info(bitvec * dest, unsigned& wp, uint8_t len, uint8_t *identity, uint8_t chan_needed) { - bitvec_write_field(dest, wp,0x1,1); // Repeated Page info exists + bitvec_write_field(dest, &wp,0x1,1); // Repeated Page info exists - bitvec_write_field(dest, wp,0x1,1); // RR connection paging + bitvec_write_field(dest, &wp,0x1,1); // RR connection paging if ((identity[0] & 0x07) == 4) { - bitvec_write_field(dest, wp,0x0,1); // TMSI + bitvec_write_field(dest, &wp,0x0,1); // TMSI identity++; len--; } else { - bitvec_write_field(dest, wp,0x0,1); // MI - bitvec_write_field(dest, wp,len,4); // MI len + bitvec_write_field(dest, &wp,0x0,1); // MI + bitvec_write_field(dest, &wp,len,4); // MI len } while (len) { - bitvec_write_field(dest, wp,*identity++,8); // MI data + bitvec_write_field(dest, &wp,*identity++,8); // MI data len--; } - bitvec_write_field(dest, wp,chan_needed,2); // CHANNEL_NEEDED - bitvec_write_field(dest, wp,0x0,1); // No eMLPP_PRIORITY + bitvec_write_field(dest, &wp,chan_needed,2); // CHANNEL_NEEDED + bitvec_write_field(dest, &wp,0x0,1); // No eMLPP_PRIORITY return wp; } @@ -1490,17 +1490,17 @@ { unsigned wp = 0; - bitvec_write_field(dest, wp, 0x1, 2); // Payload Type - bitvec_write_field(dest, wp, 0x0, 2); // Uplink block with TDMA FN - bitvec_write_field(dest, wp, 0, 1); // No Polling Bit - bitvec_write_field(dest, wp, 0x0, 3); // Uplink state flag - bitvec_write_field(dest, wp, + bitvec_write_field(dest, &wp, 0x1, 2); // Payload Type + bitvec_write_field(dest, &wp, 0x0, 2); // Uplink block with TDMA FN + bitvec_write_field(dest, &wp, 0, 1); // No Polling Bit + bitvec_write_field(dest, &wp, 0x0, 3); // Uplink state flag + bitvec_write_field(dest, &wp, MT_PACKET_ACCESS_REJECT, 6); // MESSAGE TYPE - bitvec_write_field(dest, wp, 0, 2); // fixed 00 - bitvec_write_field(dest, wp, 0x0, 1); // TLLI / G-RNTI : bit (32) - bitvec_write_field(dest, wp, tlli, 32); // CONTENTION_RESOLUTION_TLLI - bitvec_write_field(dest, wp, 1, 1); // WAIT_INDICATION size in seconds + bitvec_write_field(dest, &wp, 0, 2); // fixed 00 + bitvec_write_field(dest, &wp, 0x0, 1); // TLLI / G-RNTI : bit (32) + bitvec_write_field(dest, &wp, tlli, 32); // CONTENTION_RESOLUTION_TLLI + bitvec_write_field(dest, &wp, 1, 1); // WAIT_INDICATION size in seconds /* TODO: make it configurable */ - bitvec_write_field(dest, wp, 5, 8); // WAIT_INDICATION value - bitvec_write_field(dest, wp, 0, 1); // WAIT_INDICATION size in seconds + bitvec_write_field(dest, &wp, 5, 8); // WAIT_INDICATION value + bitvec_write_field(dest, &wp, 0, 1); // WAIT_INDICATION size in seconds } diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index da1d26c..71bd139 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -90,7 +90,7 @@ LOGP(DBSSGP, LOGL_DEBUG, "Got BSSGP RA Capability of size %d\n", cap_len); - block = bitvec_alloc(cap_len); + block = bitvec_alloc(cap_len, tall_pcu_ctx); bitvec_unpack(block, cap); /* TS 24.008, 10.5.5.12a */ diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index ac8f2d1..16870c3 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -33,7 +33,7 @@ const char *imsi) { LOGP(DRLCMAC, LOGL_NOTICE, "TX: [PCU -> BTS] Paging Request (CCCH)\n"); - bitvec *paging_request = bitvec_alloc(23); + bitvec *paging_request = bitvec_alloc(23, tall_pcu_ctx); bitvec_unhex(paging_request, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); int plen = Encoding::write_paging_request(paging_request, ptmsi, ptmsi_len); pcu_l1if_tx_pch(paging_request, plen, (char *)imsi); diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 589bd8f..be1e686 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -22,13 +22,13 @@ #define GPRS_RLCMAC_H #ifdef __cplusplus -#include <bitvector.h> #include <gsm_rlcmac.h> #include <gsm_timer.h> extern "C" { #include <osmocom/core/linuxlist.h> #include <osmocom/core/timer.h> +#include <osmocom/core/bitvec.h> } #endif diff --git a/src/gsm_rlcmac.cpp b/src/gsm_rlcmac.cpp index 6b43aa6..6323b09 100644 --- a/src/gsm_rlcmac.cpp +++ b/src/gsm_rlcmac.cpp @@ -4799,7 +4799,7 @@ { csnStream_t ar; unsigned readIndex = 0; - guint8 payload_type = bitvec_read_field(vector, readIndex, 2); + guint8 payload_type = bitvec_read_field(vector, &readIndex, 2); if (payload_type == PAYLOAD_TYPE_DATA) { @@ -4814,7 +4814,7 @@ data->NrOfBits = 23 * 8; csnStreamInit(&ar, 0, data->NrOfBits); readIndex += 6; - data->u.MESSAGE_TYPE = bitvec_read_field(vector, readIndex, 6); + data->u.MESSAGE_TYPE = bitvec_read_field(vector, &readIndex, 6); readIndex = 0; switch (data->u.MESSAGE_TYPE) { @@ -4907,10 +4907,10 @@ gint bit_offset = 0; gint bit_length; unsigned readIndex = 0; - data->PAYLOAD_TYPE = bitvec_read_field(vector, readIndex, 2); - data->RRBP = bitvec_read_field(vector, readIndex, 2); - data->SP = bitvec_read_field(vector, readIndex, 1); - data->USF = bitvec_read_field(vector, readIndex, 3); + data->PAYLOAD_TYPE = bitvec_read_field(vector, &readIndex, 2); + data->RRBP = bitvec_read_field(vector, &readIndex, 2); + data->SP = bitvec_read_field(vector, &readIndex, 1); + data->USF = bitvec_read_field(vector, &readIndex, 3); if (data->PAYLOAD_TYPE == PAYLOAD_TYPE_DATA) { @@ -4929,27 +4929,27 @@ bit_offset = 8; if (data->PAYLOAD_TYPE == PAYLOAD_TYPE_CTRL_OPT_OCTET) { - data->RBSN = bitvec_read_field(vector, readIndex, 1); - data->RTI = bitvec_read_field(vector, readIndex, 5); - data->FS = bitvec_read_field(vector, readIndex, 1); - data->AC = bitvec_read_field(vector, readIndex, 1); + data->RBSN = bitvec_read_field(vector, &readIndex, 1); + data->RTI = bitvec_read_field(vector, &readIndex, 5); + data->FS = bitvec_read_field(vector, &readIndex, 1); + data->AC = bitvec_read_field(vector, &readIndex, 1); bit_offset += 8; if (data->AC == 1) { - data->PR = bitvec_read_field(vector, readIndex, 2); - data->TFI = bitvec_read_field(vector, readIndex, 5); - data->D = bitvec_read_field(vector, readIndex, 1); + data->PR = bitvec_read_field(vector, &readIndex, 2); + data->TFI = bitvec_read_field(vector, &readIndex, 5); + data->D = bitvec_read_field(vector, &readIndex, 1); bit_offset += 8; } if ((data->RBSN == 1) && (data->FS == 0)) { - data->RBSNe = bitvec_read_field(vector, readIndex, 3); - data->FSe = bitvec_read_field(vector, readIndex, 1); - data->spare = bitvec_read_field(vector, readIndex, 4); + data->RBSNe = bitvec_read_field(vector, &readIndex, 3); + data->FSe = bitvec_read_field(vector, &readIndex, 1); + data->spare = bitvec_read_field(vector, &readIndex, 4); bit_offset += 8; } } - data->u.MESSAGE_TYPE = bitvec_read_field(vector, readIndex, 6); + data->u.MESSAGE_TYPE = bitvec_read_field(vector, &readIndex, 6); } /* Initialize the contexts */ @@ -5206,30 +5206,30 @@ else { /* First print the message type and create a tree item */ - bitvec_write_field(vector, writeIndex, data->PAYLOAD_TYPE, 2); - bitvec_write_field(vector, writeIndex, data->RRBP, 2); - bitvec_write_field(vector, writeIndex, data->SP, 1); - bitvec_write_field(vector, writeIndex, data->USF, 3); + bitvec_write_field(vector, &writeIndex, data->PAYLOAD_TYPE, 2); + bitvec_write_field(vector, &writeIndex, data->RRBP, 2); + bitvec_write_field(vector, &writeIndex, data->SP, 1); + bitvec_write_field(vector, &writeIndex, data->USF, 3); bit_offset = 8; if (data->PAYLOAD_TYPE == PAYLOAD_TYPE_CTRL_OPT_OCTET) { - bitvec_write_field(vector, writeIndex, data->RBSN, 1); - bitvec_write_field(vector, writeIndex, data->RTI, 5); - bitvec_write_field(vector, writeIndex, data->FS, 1); - bitvec_write_field(vector, writeIndex, data->AC, 1); + bitvec_write_field(vector, &writeIndex, data->RBSN, 1); + bitvec_write_field(vector, &writeIndex, data->RTI, 5); + bitvec_write_field(vector, &writeIndex, data->FS, 1); + bitvec_write_field(vector, &writeIndex, data->AC, 1); bit_offset += 8; if (data->AC == 1) { - bitvec_write_field(vector, writeIndex, data->PR, 2); - bitvec_write_field(vector, writeIndex, data->TFI, 5); - bitvec_write_field(vector, writeIndex, data->D, 1); + bitvec_write_field(vector, &writeIndex, data->PR, 2); + bitvec_write_field(vector, &writeIndex, data->TFI, 5); + bitvec_write_field(vector, &writeIndex, data->D, 1); bit_offset += 8; } if ((data->RBSN == 1) && (data->FS == 0)) { - bitvec_write_field(vector, writeIndex, data->RBSNe, 3); - bitvec_write_field(vector, writeIndex, data->FSe, 1); - bitvec_write_field(vector, writeIndex, data->spare, 4); + bitvec_write_field(vector, &writeIndex, data->RBSNe, 3); + bitvec_write_field(vector, &writeIndex, data->FSe, 1); + bitvec_write_field(vector, &writeIndex, data->spare, 4); bit_offset += 8; } } @@ -5378,32 +5378,32 @@ { unsigned readIndex = 0; //unsigned dataLen = 0; - guint8 payload_type = bitvec_read_field(vector, readIndex, 2); + guint8 payload_type = bitvec_read_field(vector, &readIndex, 2); if (payload_type == PAYLOAD_TYPE_DATA) { readIndex = 0; // MAC header - data->PAYLOAD_TYPE = bitvec_read_field(vector, readIndex, 2); - data->CV = bitvec_read_field(vector, readIndex, 4); - data->SI = bitvec_read_field(vector, readIndex, 1); - data->R = bitvec_read_field(vector, readIndex, 1); + data->PAYLOAD_TYPE = bitvec_read_field(vector, &readIndex, 2); + data->CV = bitvec_read_field(vector, &readIndex, 4); + data->SI = bitvec_read_field(vector, &readIndex, 1); + data->R = bitvec_read_field(vector, &readIndex, 1); LOGPC(DRLCMACDATA, LOGL_NOTICE, "PAYLOAD_TYPE = %u ", (unsigned)(data->PAYLOAD_TYPE)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "CV = %u ", (unsigned)(data->CV)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "SI = %u ", (unsigned)(data->SI)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "R = %u ", (unsigned)(data->R)); // Octet 1 - data->spare = bitvec_read_field(vector, readIndex, 1); - data->PI = bitvec_read_field(vector, readIndex, 1); - data->TFI = bitvec_read_field(vector, readIndex, 5); - data->TI = bitvec_read_field(vector, readIndex, 1); + data->spare = bitvec_read_field(vector, &readIndex, 1); + data->PI = bitvec_read_field(vector, &readIndex, 1); + data->TFI = bitvec_read_field(vector, &readIndex, 5); + data->TI = bitvec_read_field(vector, &readIndex, 1); LOGPC(DRLCMACDATA, LOGL_NOTICE, "spare = %u ", (unsigned)(data->spare)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "PI = %u ", (unsigned)(data->PI)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "TFI = %u ", (unsigned)(data->TFI)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "TI = %u ", (unsigned)(data->TI)); // Octet 2 - data->BSN = bitvec_read_field(vector, readIndex, 7); - data->E_1 = bitvec_read_field(vector, readIndex, 1); + data->BSN = bitvec_read_field(vector, &readIndex, 7); + data->E_1 = bitvec_read_field(vector, &readIndex, 1); LOGPC(DRLCMACDATA, LOGL_NOTICE, "BSN = %u ", (unsigned)(data->BSN)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "E_1 = %u ", (unsigned)(data->E_1)); @@ -5414,9 +5414,9 @@ unsigned i = 0; do { - data->LENGTH_INDICATOR[i] = bitvec_read_field(vector, readIndex, 6); - data->M[i] = bitvec_read_field(vector, readIndex, 1); - data->E[i] = bitvec_read_field(vector, readIndex, 1); + data->LENGTH_INDICATOR[i] = bitvec_read_field(vector, &readIndex, 6); + data->M[i] = bitvec_read_field(vector, &readIndex, 1); + data->E[i] = bitvec_read_field(vector, &readIndex, 1); LOGPC(DRLCMACDATA, LOGL_NOTICE, "LENGTH_INDICATOR[%u] = %u ", i, (unsigned)(data->LENGTH_INDICATOR[i])); LOGPC(DRLCMACDATA, LOGL_NOTICE, "M[%u] = %u ", i, (unsigned)(data->M[i])); LOGPC(DRLCMACDATA, LOGL_NOTICE, "E[%u] = %u ", i, (unsigned)(data->E[i])); @@ -5425,12 +5425,12 @@ } if(data->TI == 1) // TLLI field is present { - data->TLLI = bitvec_read_field(vector, readIndex, 32); + data->TLLI = bitvec_read_field(vector, &readIndex, 32); LOGPC(DRLCMACDATA, LOGL_NOTICE, "TLLI = %08x ", data->TLLI); if (data->PI == 1) // PFI is present if TI field indicates presence of TLLI { - data->PFI = bitvec_read_field(vector, readIndex, 7); - data->E_2 = bitvec_read_field(vector, readIndex, 1); + data->PFI = bitvec_read_field(vector, &readIndex, 7); + data->E_2 = bitvec_read_field(vector, &readIndex, 1); LOGPC(DRLCMACDATA, LOGL_NOTICE, "PFI = %u ", (unsigned)(data->PFI)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "E_2 = %u ", (unsigned)(data->E_2)); } @@ -5440,7 +5440,7 @@ assert(dataLen <= 20); for (unsigned i = 0; i < dataLen; i++) { - data->RLC_DATA[i] = bitvec_read_field(vector, readIndex, 8); + data->RLC_DATA[i] = bitvec_read_field(vector, &readIndex, 8); LOGPC(DRLCMACDATA, LOGL_NOTICE, "%02x", (unsigned)(data->RLC_DATA[i])); } LOGPC(DRLCMACDATA, LOGL_NOTICE, "\n"); @@ -5459,26 +5459,26 @@ if (data->PAYLOAD_TYPE == PAYLOAD_TYPE_DATA) { // MAC header - bitvec_write_field(vector, writeIndex, data->PAYLOAD_TYPE, 2); - bitvec_write_field(vector, writeIndex, data->RRBP, 2); - bitvec_write_field(vector, writeIndex, data->SP, 1); - bitvec_write_field(vector, writeIndex, data->USF, 3); + bitvec_write_field(vector, &writeIndex, data->PAYLOAD_TYPE, 2); + bitvec_write_field(vector, &writeIndex, data->RRBP, 2); + bitvec_write_field(vector, &writeIndex, data->SP, 1); + bitvec_write_field(vector, &writeIndex, data->USF, 3); LOGPC(DRLCMACDATA, LOGL_NOTICE, "PAYLOAD_TYPE = %u ", (unsigned)(data->PAYLOAD_TYPE)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "RRBP = %u ", (unsigned)(data->RRBP)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "SP = %u ", (unsigned)(data->SP)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "USF = %u ", (unsigned)(data->USF)); // Octet 1 - bitvec_write_field(vector, writeIndex, data->PR, 2); - bitvec_write_field(vector, writeIndex, data->TFI, 5); - bitvec_write_field(vector, writeIndex, data->FBI, 1); + bitvec_write_field(vector, &writeIndex, data->PR, 2); + bitvec_write_field(vector, &writeIndex, data->TFI, 5); + bitvec_write_field(vector, &writeIndex, data->FBI, 1); LOGPC(DRLCMACDATA, LOGL_NOTICE, "PR = %u ", (unsigned)(data->PR)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "TFI = %u ", (unsigned)(data->TFI)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "FBI = %u ", (unsigned)(data->FBI)); // Octet 2 - bitvec_write_field(vector, writeIndex, data->BSN, 7); - bitvec_write_field(vector, writeIndex, data->E_1, 1); + bitvec_write_field(vector, &writeIndex, data->BSN, 7); + bitvec_write_field(vector, &writeIndex, data->E_1, 1); LOGPC(DRLCMACDATA, LOGL_NOTICE, "BSN = %u ", (unsigned)(data->BSN)); LOGPC(DRLCMACDATA, LOGL_NOTICE, "E_1 = %u ", (unsigned)(data->E_1)); @@ -5488,9 +5488,9 @@ unsigned i = 0; do { - bitvec_write_field(vector, writeIndex, data->LENGTH_INDICATOR[i], 6); - bitvec_write_field(vector, writeIndex, data->M[i], 1); - bitvec_write_field(vector, writeIndex, data->E[i], 1); + bitvec_write_field(vector, &writeIndex, data->LENGTH_INDICATOR[i], 6); + bitvec_write_field(vector, &writeIndex, data->M[i], 1); + bitvec_write_field(vector, &writeIndex, data->E[i], 1); LOGPC(DRLCMACDATA, LOGL_NOTICE, "LENGTH_INDICATOR[%u] = %u ", i, (unsigned)(data->LENGTH_INDICATOR[i])); LOGPC(DRLCMACDATA, LOGL_NOTICE, "M[%u] = %u ", i, (unsigned)(data->M[i])); LOGPC(DRLCMACDATA, LOGL_NOTICE, "E[%u] = %u ", i, (unsigned)(data->E[i])); @@ -5503,7 +5503,7 @@ assert(dataNumOctets <= 20); for (unsigned i = 0; i < dataNumOctets; i++) { - bitvec_write_field(vector, writeIndex, data->RLC_DATA[i], 8); + bitvec_write_field(vector, &writeIndex, data->RLC_DATA[i], 8); LOGPC(DRLCMACDATA, LOGL_NOTICE, "%02x", (unsigned)(data->RLC_DATA[i])); } LOGPC(DRLCMACDATA, LOGL_NOTICE, "\n"); diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index 0a0362b..c61eb6d 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -168,7 +168,6 @@ tall_pcu_ctx = talloc_named_const(NULL, 1, "Osmo-PCU context"); if (!tall_pcu_ctx) return -ENOMEM; - bv_tall_ctx = tall_pcu_ctx; bts = bts_main_data(); bts->fc_interval = 1; diff --git a/src/tbf.cpp b/src/tbf.cpp index 0d28c5c..2c0c07f 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -1112,7 +1112,7 @@ msg = msgb_alloc(23, "rlcmac_dl_ass"); if (!msg) return NULL; - bitvec *ass_vec = bitvec_alloc(23); + bitvec *ass_vec = bitvec_alloc(23, tall_pcu_ctx); if (!ass_vec) { msgb_free(msg); return NULL; @@ -1159,7 +1159,7 @@ msg = msgb_alloc(23, "rlcmac_ul_ass_rej"); - bitvec *packet_access_rej = bitvec_alloc(23); + bitvec *packet_access_rej = bitvec_alloc(23, tall_pcu_ctx); bitvec_unhex(packet_access_rej, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); @@ -1216,7 +1216,7 @@ if (!msg) return NULL; LOGP(DRLCMAC, LOGL_INFO, "%ss start Packet Uplink Assignment (PACCH)\n", tbf_name(new_tbf)); - bitvec *ass_vec = bitvec_alloc(23); + bitvec *ass_vec = bitvec_alloc(23, tall_pcu_ctx); if (!ass_vec) { msgb_free(msg); return NULL; diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 2598174..1eee41a 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -121,7 +121,7 @@ msg = msgb_alloc(23, "rlcmac_ul_ack"); if (!msg) return NULL; - bitvec *ack_vec = bitvec_alloc(23); + bitvec *ack_vec = bitvec_alloc(23, tall_pcu_ctx); if (!ack_vec) { msgb_free(msg); return NULL; diff --git a/tests/rlcmac/RLCMACTest.cpp b/tests/rlcmac/RLCMACTest.cpp index 97e5e60..9155809 100644 --- a/tests/rlcmac/RLCMACTest.cpp +++ b/tests/rlcmac/RLCMACTest.cpp @@ -83,9 +83,9 @@ cout << "sizeof PSI5_t " << sizeof(PSI5_t) << endl; } -void testRlcMacDownlink() +void testRlcMacDownlink(void *test_ctx) { - struct bitvec *resultVector = bitvec_alloc(23); + struct bitvec *resultVector = bitvec_alloc(23, test_ctx); bitvec_unhex(resultVector, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); std::string testData[] = { @@ -106,7 +106,7 @@ cout << " DOWNLINK " << endl; for (int i = 0; i < testDataSize; i++) { - bitvec *vector = bitvec_alloc(23); + bitvec *vector = bitvec_alloc(23, test_ctx); bitvec_unhex(vector, testData[i].c_str()); cout << "vector1 = "; for (int i = 0; i < 23; i++) @@ -150,9 +150,9 @@ } -void testRlcMacUplink() +void testRlcMacUplink(void *test_ctx) { - struct bitvec *resultVector = bitvec_alloc(23); + struct bitvec *resultVector = bitvec_alloc(23, test_ctx); bitvec_unhex(resultVector, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); std::string testData[] = { @@ -169,7 +169,7 @@ cout << " UPLINK " << endl; for (int i = 0; i < testDataSize; i++) { - bitvec *vector = bitvec_alloc(23); + bitvec *vector = bitvec_alloc(23, test_ctx); bitvec_unhex(vector, testData[i].c_str()); cout << "vector1 = "; for (int i = 0; i < 23; i++) @@ -212,9 +212,9 @@ bitvec_free(resultVector); } -void testCsnLeftAlignedVarBmpBounds() +void testCsnLeftAlignedVarBmpBounds(void *test_ctx) { - bitvec *vector = bitvec_alloc(23); + bitvec *vector = bitvec_alloc(23, test_ctx); bitvec_unhex(vector, "40200bffd161003e0e519ffffffb800000000000000000"); RlcMacUplink_t data; @@ -229,10 +229,12 @@ int main(int argc, char *argv[]) { + void *ctx = talloc_named_const(NULL, 1, "RLCMACTest"); osmo_init_logging(&gprs_log_info); //printSizeofRLCMAC(); - testRlcMacDownlink(); - testRlcMacUplink(); - testCsnLeftAlignedVarBmpBounds(); + testRlcMacDownlink(ctx); + testRlcMacUplink(ctx); + testCsnLeftAlignedVarBmpBounds(ctx); + talloc_free(ctx); } diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index e367ce6..f042262 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -595,7 +595,7 @@ meas.set_rssi(31); - rlc_block = bitvec_alloc(23); + rlc_block = bitvec_alloc(23, tall_pcu_ctx); encode_gsm_rlcmac_uplink(rlc_block, ulreq); num_bytes = bitvec_pack(rlc_block, &buf[0]); @@ -2573,7 +2573,7 @@ OSMO_ASSERT(dl_tbf->state_is(GPRS_RLCMAC_FLOW)); - block = bitvec_alloc(23); + block = bitvec_alloc(23, tall_pcu_ctx); bitvec_unpack(block, data_msg); diff --git a/tests/types/TypesTest.cpp b/tests/types/TypesTest.cpp index ee1c817..7d09108 100644 --- a/tests/types/TypesTest.cpp +++ b/tests/types/TypesTest.cpp @@ -430,7 +430,7 @@ void test_immediate_assign_rej() { uint8_t plen; - bitvec *immediate_assignment_rej = bitvec_alloc(22); + bitvec *immediate_assignment_rej = bitvec_alloc(22, tall_pcu_ctx); bitvec_unhex(immediate_assignment_rej, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); -- To view, visit https://gerrit.osmocom.org/1753 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id8f797631d89aa12b6e48efb2dc153a3e2f059f7 Gerrit-PatchSet: 1 Gerrit-Project: osmo-pcu Gerrit-Branch: master Gerrit-Owner: lynxis lazus <lynxis at fe80.eu>