Commit Graph

924 Commits

Author SHA1 Message Date
Jacob Erlbeck 2bef4dbd43 edge: Enable CRBB decoding
Currently CRBB bitmaps are ignored if they are present.

This commit enables the decoding.

Note that this requires osmo_t4_decode in libosmocore.

Sponsored-by: On-Waves ehf
2016-02-08 00:45:34 +01:00
Jacob Erlbeck 3fdcb2b84e edge: Add experimental support for uplink CRBB
Currently only uncompressed bitmaps (URBB) are supported in
PACKET UPLINK ACK/NACK messages.

Extend decode_egprs_acknack_bits to decode compressed bitmaps (CRBB),
too.

Note that this code is only active, if the macro WITH_CRBB_DECODING
is defined.

Sponsored-by: On-Waves ehf
2016-02-08 00:45:34 +01:00
Jacob Erlbeck ae9c575d2c edge: Handle EGPRS PACKET DOWNLINK ACK NACK
Currently this message is ignored.

Support decoding and handling of this message. Use a bitvec for the
decoder that just represents a BSN sequence without any encoding
details (first bit -> first BSN). Return the corresponding BSN range
(snsmod(bsn_begin + bits_in_bitvec) = bsn_end), so snsmod(bsn_end-1)
is the last BSN if there is at least 1. If bsn_begin == bsn_end, no
BSNs has been added.

Note that this bitvec is not yet used for RBB handling. It just calls
the old rcvd_dl_ack with a faked (all bits are 1) RBB map.

Sponsored-by: On-Waves ehf
2016-02-08 00:45:34 +01:00
Jacob Erlbeck c2141c6064 edge: Workaround to fix decoding of EGPRS_AckNack_w_len_t
The presence of the LENGTH field adds an additional offset which
breaks the related M_SERIALIZE in gsm_rlcmac.cpp. In that case,
the Desc in EGPRS_AckNack_t is being cast to EGPRS_AckNack_w_len_t
and then ((EGPRS_AckNack_w_len_t *)Desc)->Desc is filled with the
parsed data, which is a platform dependant number of bytes apart the
real Desc struct.

Remove LENGTH field from EGPRS_AckNack_w_len_t so that the Desc field
is the first field.

Note that this is not a real fix. The rlcmac wireshark dissector
still has the same declaration but doesn't seem to suffer from this
problem.

Sponsored-by: On-Waves ehf
2016-02-05 18:27:10 +01:00
Jacob Erlbeck 70955c765c edge: Provide and use CS -> CPS conversion
The MS' RLC receiver needs a valid CPS field to decode the block.

Add the function gprs_rlc_mcs_cps to generate the CPS value based on
coding scheme, puncturing, and padding.

Sponsored-by: On-Waves ehf
2016-02-05 18:27:10 +01:00
Jacob Erlbeck a88d065606 edge: Support MCS data block encoding
Currently only GPRS data block encoding is supported.

This commit adds rlc_data_to_dl_append_egprs which does the EGPRS
specific extension and chunk handling. It extends
Encoding::rlc_data_to_dl_append to use that function for MCS coding
schemes.

Sponsored-by: On-Waves ehf
2016-02-05 18:24:50 +01:00
Jacob Erlbeck 5058bd6e9e edge: Select implementation by mode in rlc_data_to_dl_append
Currently the GPRS data block encoding is applied to every
coding scheme, even if an MCS is selected.

This commit renames the actual encoding function to
rlc_data_to_dl_append_gprs (not exported) and puts
selection code into Encoding::rlc_data_to_dl_append. This
requires an additional cs argument.

Sponsored-by: On-Waves ehf
2016-02-05 13:46:21 +01:00
Jacob Erlbeck fec94d1c5c edge: Use rlc_data_to_dl_append in create_new_bsn
Currently TBF related tasks (status changes, counter updates,
LLC dummy command insertion) as well as
RLC data block generation are done within create_new_bsn.
The data block creation part has already been copied to
the stateless Encoding::rlc_data_to_dl_append function.

This commit changes create_new_bsn to use the encoder function and
just care about the TBF related stuff.

Since the rlc_data_to_dl_append function has been validated against
the test cases being described in annex B of TS 44.060, this
commit fixes an encoder bug which leads to broken LLC frames in
a special case (see example B.2, the main header's E bit was
erroneously set to 1 in that case). When this happens, the LLC frame
will get discarded after reassembly, so that TCP will have to
retransmit the lost packet.

Sponsored-by: On-Waves ehf
2016-02-05 13:46:12 +01:00
Jacob Erlbeck 14bb0947b4 edge: Add Encoding::rlc_data_to_dl_append
This function appends a single chunk to an RLC downlink data block.
The implementation is basically taken from the
gprs_rlcmac_dl_tbf::create_new_bsn method without the TBF related
functionality and any side effects.

Note that it still only supports GRPS.

Sponsored-by: On-Waves ehf
2016-02-05 13:26:34 +01:00
Jacob Erlbeck 3a3b6a7e86 edge: Use RLC data block encoding functions
This commit removes the use of struct rlc_dl_header from
gprs_rlcmac_dl_tbf::create_dl_acked_block and
gprs_rlcmac_dl_tbf::create_new_bsn. Instead of patching the
data area directly, the RLC block encoding functions are used.

Note that the data unit encoding is still hard-coded to GPRS in
create_new_bsn, so using MCS 1-4 (albeit being supported by the
encoder) will not work yet.

Sponsored-by: On-Waves ehf
2016-02-05 13:26:34 +01:00
Jacob Erlbeck 314ec4db40 tbf: Remove obsolete TLLI functions
This commit removes gprs_rlcmac_tbf::extract_tlli and
Decoding::tlli_from_ul_data.

Sponsored-by: On-Waves ehf
2016-02-05 13:26:34 +01:00
Jacob Erlbeck f0e403911d edge: Add encoder for downlink RLC data blocks
Currently the (GPRS) RLC block encoding is done by setting the
header fields directly in gprs_rlcmac_dl_tbf::create_new_bsn.
This is much more complex with EGPRS, since the data fields are
not byte aligned, the header formats depend on the header type,
and the mapping of bits to bytes is LSB first.

This commit adds Encoding::rlc_write_dl_data_header which writes
the header according to the given gprs_rlc_data_header structure.
Encoding::rlc_copy_from_aligned_buffer is also added to copy
byte sequences into the message.

Note that the actual encoding of data units is not yet present.

Sponsored-by: On-Waves ehf
2016-02-05 13:26:34 +01:00
Jacob Erlbeck 6e9f9c20e9 edge: Add init functions for gprs_rlc_data_info
Add the functions gprs_rlc_data_info_init_dl/ul which initialise a
gprs_rlc_data_info structure depending on the coding scheme. The
fields num_data_blocks, data_offs_bits, cs, and the data_blocks are
valid after this call. The other fields are set to 0.

The data blocks are initialised to the correct data_len, e == 1
(no extension header field), cv == 15 (not a final block). The other
data block fields are set to 0.

The gprs_rlc_data_block_info can also be initialised separately
by using the gprs_rlc_data_block_info_init function.

Sponsored-by: On-Waves ehf
2016-02-05 13:26:34 +01:00
Jacob Erlbeck cc34a5b43f rlc: Add info fields for downlink
This commit extends gprs_rlc_data_info and gprs_rlc_data_block_info
by the fields required for downlink RLC data messages.

Sponsored-by: On-Waves ehf
2016-02-05 13:26:34 +01:00
Jacob Erlbeck 22f8087b98 edge: Add numDataHeaderBitsUL/DL and numDataBlockHeaderBits methods
These methods are added to GprsCodingScheme to avoid related
switch statements in the RLC block encoder for EGPRS.

Sponsored-by: On-Waves ehf
2016-02-05 13:26:33 +01:00
Jacob Erlbeck fc1b3e6c90 edge: Fix RLC message size
Currently the RLC message length that is obtained from the DSP is
reduced by 1 if the last byte of the buffer includes spare bits.
While this worked well with GPRS, these bits are being used to
encode RLC blocks in EGPRS mode. Thus this last byte must not be
chopped off. The functionality of the code is not affected by this,
since the modified length value is not used.

This commit adds GprsCodingScheme::usedSizeDL/UL to return
the number of bytes needed to encode the message block. If there are
single bits at the end that are to be used (EGPRS), the functions
return the number of full bytes plus 1 (which is the buffer size
reported by the DSP and returned by sizeUL/sizeDL). The commit also
removes the len parameter from rcv_data_block_acknowledged.

Sponsored-by: On-Waves ehf
2016-02-05 13:26:33 +01:00
Jacob Erlbeck f2ba4cbf51 edge: Rename gprs_rlc_ul_header_egprs and gprs_rlc_ul_data_block_info
These struct names are more specific than necessary. They are used
for GPRS (uplink) already. In downlink direction, only a few fields
will be added to the header struct. Add addition,
gprs_rlc_ul_header_egprs does not map directly to an encoded
header, like many other 'header' structs do.

Change the names to fit both modes and both directions:

  gprs_rlc_ul_header_egprs    -> gprs_rlc_data_info
  gprs_rlc_ul_data_block_info -> gprs_rlc_data_block_info

Sponsored-by: On-Waves ehf
2016-02-05 13:26:33 +01:00
Jacob Erlbeck 7e7a261de0 edge: Remove int casting operator from GprsCodingScheme
This convenience operator rather hide implementation bugs and is thus
removed.

Sponsored-by: On-Waves ehf
2016-02-05 13:25:43 +01:00
Jacob Erlbeck a47aaa4e7a edge: Add work-around to get DL EGPRS from MS object
The EGPRS multi-slot class need to be parsed from the CSN.1 RA
capability (see gprs_bssgp_pcu_rx_dl_ud).

This commit adds a workaround to get the EGPRS MS class from the MS
object if that is present.

Sponsored-by: On-Waves ehf
2016-02-05 13:25:43 +01:00
Jacob Erlbeck 08f631c197 edge: Enable EGPRS in downlink TBFs
Currently GPRS is always used for downlink, which violates TS 44.060
(concurrent TBF must have the same mode).

Enable EGPRS mode for downlink if the EGPRS MS class is != 0 and
EGRPS has been enabled.

Note that EGPRS Ack/Nack handling is not yet implemented, so enabling
EGPRS will not work still. But we will now get EGPRS DL ACK/NACK
messages now from the MS.

Sponsored-by: On-Waves ehf
2016-02-05 13:20:45 +01:00
Jacob Erlbeck 369c2fb7b4 tbf: Remove bogus gprs_rlcmac_dl_tbf::enable_egprs
This method is already present in gprs_rlcmac_tbf and should
not be present in gprs_rlcmac_dl_tbf.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:14 +01:00
Jacob Erlbeck 166c9fc827 edge: Support EGPRS in write_packet_downlink_assignment
Add an use_egprs parameter to write_packet_downlink_assignment
and add the EGPRS related fields if it is set to true. The
window size is fixed at 64 blocks, link quality measurement
reports have been disabled, and the other optional fields are not
present.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:14 +01:00
Jacob Erlbeck 7b57997874 edge: Show current mode in VTY
Add the current mode to the output of the 'show ms imsi' and
'show ms tlli' commands.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:14 +01:00
Jacob Erlbeck cb7289094a edge: Replace integer cs by GprsCodingScheme
Currently the TBF and MS object use a plain integer value
(current_cs) to manage the coding scheme. This makes it difficult to
support the MCS schemes. GprsCodingScheme supports a partial ordering
of these values (CS and MCS) and provides safe increment and
decrement methods.

Use the GprsCodingScheme type instead of integer for cs fields and
variables. Add a 'mode' to GprsMs which can be set to either GPRS,
EGPRS, or EGPRS_GMSK which also set the initial values of
current_cs_ul/dl. Select the mode based on max_mcs_ul and max_mcs_dl.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:14 +01:00
Jacob Erlbeck 96ccea8436 edge: Add initial_mcs_dl and initial_mcs_ul config values
Provide the initial MCS values for EGPRS data blocks. They are set
to 1 (MCS-1) for each direction and there is no support to change
these configuration values yet (the automatic adaption still works,
so there is probably no need to set these values).

Sponsored-by: On-Waves ehf
2016-02-01 13:58:14 +01:00
Jacob Erlbeck 4c9e549aa3 edge: Add methods and operators to GprsCodingScheme
Add a few new operators and methods to support the use of
GprsCodingScheme instead of the plain integer currently used.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:14 +01:00
Jacob Erlbeck 0d05805b76 edge: Add max_mcs_ul and max_mcs_dl config
This sets the maximum MCS encoding used for EGPRS RLC data blocks
in either direction.

The following VTY command are added to node config-pcu:

 - mcs max <1-9>         set maximum for both, uplink and downlink
 - mcs max <1-9> <1-9>   set maximum for downlink and uplink (in that
                         order)
 - no mcs max            do not limit

Note that using a value of 4 or below for each direction implies
that a GMSK-only TBF may be assumed, which for instance would allow
the use of the GPRS MS class instead of the possibly more restrictive
EGPRS MS class.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck ed2dbf6954 tbf: Use LListHead instead of llist_pods
LListHead does basically the same like llist_pods, but more C++ish
and with type safety.

This commit turns the former list field of gprs_rlcmac_tbf into a
private field, provides accessors, moves the related code from
pcu_vty.c to pcu_vty_functions.cpp, and removes the llist_pods
type and related code.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck bf49f042d4 tbf/vty: Move tbf_print_vty_info to pcu_vty_functions.cpp
This function is similar to the show_ms function already present in
the target file. Since the TBF lists will be turned into LListHead
based lists, they will get an iteration function in
pcu_vty_functions.cpp, too.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck aa9daa1b9d tbf: Replace static casts by calls to as_ul_tbf/as_dl_tbf
Currently casts from gprs_rlcmac_tbf to gprs_rlcmac_ul_tbf and
gprs_rlcmac_dl_tbf are done by using static_cast. This doesn't provide
protection against converting a gprs_rlcmac_ul_tbf pointer to a
gprs_rlcmac_dl_tbf pointer and vice versa.

This commit provides two functions as_ul_tbf and as_dl_tbf, that
behave similar like dynamic_cast but use the direction field instead
of RTTI.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck 5ffbb2744f encoding: Remove RlcMacDownlink_t based write_packet_uplink_ack
This is the CSN1-encoder based variant, which has been replaced and
is no longer being used.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck a24e1cd508 tbf: Use bitvec based write_packet_uplink_ack
Use the new bitvec based encoder for PACKET UPLINK ACK/NACK messages
and disable the old CSN.1 encoder based one.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck 37005a165d encoding: Add bitvec based write_packet_uplink_ack
The current write_packet_uplink_ack implementation is based on the
CSN.1 encoder which makes it difficult to do the bitmap encoding for
EGPRS.

Add a new implementation based on bitvec functions to create the
PACKET UPLINK ACK/NACK messages.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck 580edbc326 sched: Assert that the generated message is not empty
Currently the msg data is accessed and index 0 assuming the msg is
not empty. While this should be always the case, the msg can be
empty if there are software errors in the message creation functions.

This commit adds an assertion to catch this kind of bugs.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck 8e323b39f9 edge: Set the EGPRS window parameters
Currently the GPRS parameters are used, which is ok for the WS but
not for the SNS.

This commit uses RLC_EGPRS_SNS and RLC_EGPRS_MIN_WS for the window
configuration.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck 869449cdd0 edge: Move EGPRS setup from setup_tbf to tbf_alloc_ul_tbf
Currently the EGPRS mode is enabled in setup_tbf depending on the
values of egprs_ms_class and bts->egprs_enabled (both must be != 0).
This makes it difficult to set different values (like window
parameters) depending on the direction.

This commit moved the initialisation part to tbf_alloc_ul_tbf und
just leaves the setting of the ms_class to setup_tbf.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:13 +01:00
Jacob Erlbeck 8f8197f3fd rlc: Make WS and SNS variable
Currently the values for WS and SNS are fixed to 64 (WS) and 128
(SNS) which are the only values that can be used with GPRS. On the
other hand, EGPRS requires an SNS of 2014 and a WS in the range of
64 to 1024.

This commit adds member variables and setters to both window
classes. By default, the GPRS values are being used.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:12 +01:00
Jacob Erlbeck a3a567e765 rlc: Add constructor to window classes
Currently the gprs_rlc_dl_window and gprs_rlc_ul_window do not have
constructors, but need to get initialized explicitly.

This commit adds constructors to both classes and removes explicit
external initialization code.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:12 +01:00
Jacob Erlbeck e1ca87f057 rlc/edge: Consistently use uint16_t for BSNs and SSNs
Currently in some places uint8_t is being used to encode BSNs and
SSNs. This is inconsistent and (even worse) not enough for EPGRS
which uses an SNS of 2014.

This commit changes these to uint16_t.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:12 +01:00
Jacob Erlbeck 93c55d04e5 rlc: Add and use mod_sns(bsn) method
Currently there is only a mod_sns() method which is being used in
expression like bsn_expr & win.mod_sns(). This only works, because
it is known that mod_sns() is (sns() - 1) where sns() in turn is
always 2^n. This is error prone, hard to read, and relies on window
specifics that should be kept inside the respective module.

This commit adds a mod_sns(uint bsn) method to gprs_rlc_ul_window and
gprs_rlc_dl_window, that encapsulates and hides this optimized
computation.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:12 +01:00
Jacob Erlbeck 2b3121eebf edge: Support EGPRS uplink Ack/Nack messages
This commit adds EGPRS UL Ack/Nack encoding based on the CSN1 code.

Note that the bitmap encoding is still broken and not easy to fix
with the CSN1 framework, especially w.r.t. the length field.
Therefore this implementation will be abandoned and replaced by a
bitvec based one.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:12 +01:00
Jacob Erlbeck 2e3a81e4b3 rlc: Use a pointer instead of repeated selector chains
Currently the same selector chain is used several times in the same
function.

This commit adds a pointer to Packet_Uplink_Ack_Nack and uses that
instead.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:12 +01:00
Jacob Erlbeck 5c75480e90 edge: Move the GPRS UL Ack/Nack encoding into a separate function
Currently the Encoding::write_packet_uplink_ack function only
supports GPRS.

Split this function into a generic and a GPRS specific part.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:12 +01:00
Jacob Erlbeck d88bb2e825 rlc: Dump RLC data for debugging
Log incoming RLC data messages and RLC data units to LOGL_DEBUG.

Sponsored-by: On-Waves ehf
2016-02-01 13:58:12 +01:00
Jacob Erlbeck c362df25a2 pcu: Fix memory corruption bugs (ASAN)
ASAN has found improper deletion of objects. These only occur
on shutdown but makes it impossible to run the test cases with
full ASAN support.

This commit fixes some of them and deactivates the freeing of the_pcu.bctx
which may cause a corruption in BTS::~BTS() later on.

Note that the latter is only a work-aound and should be fixed
properly. It will leak bctx objects, but this is currently not
critical, since gprs_bssgp_destroy is only called once, immediately
before a call to exit().

Ticket: OW#1572
Sponsored-by: On-Waves ehf
2016-02-01 13:56:32 +01:00
Jacob Erlbeck 27dc941475 edge: Remove leftover comments from encoding.c
Sponsored-by: On-Waves ehf
2016-01-08 11:14:15 +01:00
Jacob Erlbeck ead5e4724c edge: Fix data block decoder (Coverity)
Use a signed integer instead of an unsigned one for num_chunks
which can set to a negative value on error.

Ensure that chunks is not dereferenced if it is NULL. In fact
that will not happen currently, since num_chunks is now always
<= 0 if chunks == NULL.

Fixes: Coverity CID 1347433, 1347434, 1347435

Sponsored-by: On-Waves ehf
2016-01-08 10:14:50 +01:00
Jacob Erlbeck 6e75bc7fe3 sched: Change next_ctrl_prio increment
Currently the control block scheduler does not seem to be fair in all
cases. At least it happend while testing the EGPRS code, that a
Uplink Ack/Nack message got never be sent, because a Downlink
assignment took over all the times.

This commit changes the round robin code to always increment the
priority offset by 1 instead of (i + 1). The former definitely
ensures that every message type gets the highest priority after some
steps. The latter might be more fair in some situations, but that and
its correctness are not proven.

Sponsored-by: On-Waves ehf
2015-12-16 19:57:13 +01:00
Jacob Erlbeck 845c01ef3f edge: Remove unused GPRS functions
This commit removes the code that is no longer used due to the commit
"Use a single PDCH rcv_data_block method for GPRS and EGPRS".

Sponsored-by: On-Waves ehf
2015-12-16 19:57:13 +01:00
Jacob Erlbeck 554a835e90 edge: Use a single PDCH rcv_data_block method for GPRS and EGPRS
Currently GPRS is handled by the old code path while EGPRS already
uses the unified functions. The rcv_block_egprs is basically not
specific to EGPRS and just needs minor modifications to handle GPRS.

This commit turns gprs_rlcmac_pdch::rcv_block_egprs into a unified
rcv_data_block method and uses it for GPRS, too.

Note that the logging messages of the new parser are different.

Sponsored-by: On-Waves ehf
2015-12-16 19:57:09 +01:00
Jacob Erlbeck 39c6c7f738 edge: Implement gprs_rlcmac_pdch::rcv_block_egprs
This commit replaces the stub by a method that decodes the block
first, and passes it to the TBF object associated with the TFI.

Sponsored-by: On-Waves ehf
2015-12-16 19:55:52 +01:00
Jacob Erlbeck b3100e187b edge: Add methods for unified GPRS/EGPRS UL data block handling
The current rcv_data_block_acknowledged_gprs method is tightly
coupled to GPRS.

This commit adds variants of the involved methods that support
EGPRS and GPRS RLC encodings likewise.

Sponsored-by: On-Waves ehf
2015-12-16 19:55:18 +01:00
Jacob Erlbeck e8f5fe5255 tbf: Refactor parts of extract_tlli into set_tlli_from_ul
Currently gprs_rlcmac_tbf::extract_tlli takes care of decoding and
the TBF update. These are really different things and doing the
decoding in extract_tlli makes EGPRS support more complex.

This commit moves the TBF state related part into a new method
gprs_rlcmac_tbf::set_tlli_from_ul.

Sponsored-by: On-Waves ehf
2015-12-16 19:37:49 +01:00
Jacob Erlbeck ce1beb423c edge: Store GprsCodingScheme in gprs_rlc_data
Currently the coding scene is stored as number N, where there scheme
is CS-N.

This commit replaces this by a GprsCodingScheme type cs value. The
gprs_rlcmac_cs table is no longer needed and thus removed.

Sponsored-by: On-Waves ehf
2015-12-16 19:37:08 +01:00
Jacob Erlbeck 784a0bd000 edge: Add is_received and invalidate_bsn to gprs_rlc_ul_window
These methods will be needed for EGPRS decoding.

The is_received method returns true iff a block with the given BSN
has already been received in the current window. A call to
invalidate_bsn marks the block as not received.

Sponsored-by: On-Waves ehf
2015-12-16 19:37:08 +01:00
Jacob Erlbeck d87e1d6ab7 rlc: Do not raise_v_q in receive_bsn
Currently gprs_rlc_ul_window::receive_bsn calls raise_v_q and returns
the number of RLC data blocks that can be taken from the queue. This
does not fit the EGPRS feature to put 2 independant data blocks in a
single RLC block.

This commit removes raise_v_q from receive_bsn, hence it must be
called explicitely to get the number of processable data blocks.

Sponsored-by: On-Waves ehf
2015-12-16 19:37:08 +01:00
Jacob Erlbeck 4abc686d76 edge: Add unified decoder methods for GPRS/EGPRS
This commit adds new RLC block decoder functions that support both
GPRS and EGPRS. The code path is selected based on the value of the
GprsCodingScheme cs object.

- rlc_parse_ul_data_header
        parses the header of an RLC data block including the E and FBI/TI
        flags (currently supported CS-1 - CS-4, MCS-1 - MCS-4).

- rlc_copy_to_aligned_buffer
        copies an RLC data unit to a byte aligned buffer and returns
        the unit's length.

- rlc_get_data_aligned
        is a convenience wrapper around rlc_copy_to_aligned_buffer
        that avoids copying if the data unit is already byte aligned.

Sponsored-by: On-Waves ehf
2015-12-16 19:36:09 +01:00
Jacob Erlbeck 392a545336 edge: Add information about data blocks to GprsCodingScheme
This commit adds the methods maxDataBlockBytes and numDataBlocks
which provide information about the data areas within RLC messages.
In these areas, the extension bytes, TLLI, and the LLC data are
stored.

Sponsored-by: On-Waves ehf
2015-12-15 15:19:43 +01:00
Jacob Erlbeck 4aa78a8bea rlc: Check endianness for bit field declarations
Currently the declarations of rlc_ul_header, rlc_dl_header, and
rlc_li_field silently assume that a gcc for a little endian platform
is being used.

This commit adds '#if OSMO_IS_LITTLE_ENDIAN' the ensure the correct
byte ordering.

Sponsored-by: On-Waves ehf
2015-12-15 15:19:43 +01:00
Jacob Erlbeck 6c3dc61db5 edge: Add header type property to GprsCodingScheme
The header type depends on the coding scheme, for GPRS there is a
single data header type per direction, for EGPRS there are 3 per
direction. In addition, control block header types are used with CS-1
only, so there is one of the per direction altogether for GRPS and
EGPRS.

This commit adds the header type enum and two methods headerTypeData
and headerTypeControl.

Sponsored-by: On-Waves ehf
2015-12-15 15:19:43 +01:00
Jacob Erlbeck 3b802e3c4a edge: Rename rcv_data_block_acknowledged
This commit renames rcv_data_block_acknowledged to
rcv_data_block_acknowledged_gprs to separate it from EGPRS data block
decoding.

Sponsored-by: On-Waves ehf
2015-12-15 15:19:43 +01:00
Jacob Erlbeck 690a734ebf edge: Add gprs_rlcmac_pdch::rcv_block_egprs stub
This stub function gets called when an EGPRS data package arrives.

Sponsored-by: On-Waves ehf
2015-12-15 15:19:42 +01:00
Jacob Erlbeck 9e862e1e7f edge: Use GprsCodingScheme to adjust the UL RLC block size
Currently the block size is mapped by a switch statement to strip
extra bits that are not used for RLC blocks. That information is
already available via the GprsCodingScheme class.

This commit moves the CS/MCS detection to the rcv_block message and
passes the cs object via rcv_block_gprs, where the length gets
adjusted, to gprs_rlcmac_pdch::rcv_data_block_acknowledged. There the
switch statement is removed.

Note that the TbfTest.err changes due to an additional log message.

Sponsored-by: On-Waves ehf
2015-12-15 15:19:42 +01:00
Jacob Erlbeck 409f980a18 edge: Add GprsCodingScheme class
Currently the coding scheme is checked and compared at different
places which makes in cumbersome to extend it for EGPRS.

This class encapsules the coding scheme and provides required meta
information like sizes as well as helper methods.

Sponsored-by: On-Waves ehf
2015-12-15 15:19:42 +01:00
Jacob Erlbeck 14e00f8f66 edge: Extend gprs_rlcmac_dl_tbf::handle by egprs_ms_class
The multislot (MS) class and the EGPRS MS class can also be passed
via BSSGP in an MS Radio Access Capability element which can
optionally be contained in a DL-UNITDATA PDU. While this case is fully
supported for GPRS, the EGPRS MS class in BSSGP messages is ignored.

This commit extends gprs_rlcmac_dl_tbf::handle to pass the EGPRS MS
class, too.

Note, that the EGPRS class is not yet taken from the CSN.1 RA
capability and is always set to 0. Note also, that append_data
still uses ms_class only.

Sponsored-by: On-Waves ehf
2015-12-15 15:19:42 +01:00
Jacob Erlbeck 5265f59525 edge: Enable EGPRS if configured and egprs_ms_class present
Enable the TBF to use EGPRS if the bts->egprs_enabled config variable
has been set via the VTY "egprs" command and if the MS has signaled a
EGPRS multislot class.

Tell the MS to use EGPRS if the condition above holds.

Note that this will cause the MS to use EGPRS RLC block formats for
further messages which are not yet understood by the PCU.

Sponsored-by: On-Waves ehf
2015-12-15 15:19:42 +01:00
Jacob Erlbeck 86b6f05d19 edge: Support EGPRS multislot class handling in tbf_alloc
Add an egprs_ms_class argument to the allocation functions and
set/pass it where necessary.

Sponsored-by: On-Waves ehf
2015-12-15 15:17:51 +01:00
Jacob Erlbeck 5643f35fb4 edge: Add m_egprs_enabled and related methods to TBF
Add the following methods to gprs_rlcmac_tbf:
  - is_egprs_enabled
  - enable_egprs
  - disable_egprs

Also show the value of the flag in name() by displaying "EGPRS" if
it is set.

Sponsored-by: On-Waves ehf
2015-12-15 15:17:51 +01:00
Jacob Erlbeck 76d767cbe8 edge: Support EGPRS in packet uplink assignment message
Currently the Encoding::write_packet_uplink_assignment method only
supports the GPRS variant of the message.

This commit adds the missing EGPRS variant to the encoder.

Sponsored-by: On-Waves ehf
2015-11-30 12:20:36 +01:00
Jacob Erlbeck 953c78987a edge: Add egprs config command
Add a global config flag to enable the use EDGE/EGPRS.

The following VTY commands are added to node config-pcu:

 - egprs              Enables EGPRS
 - no egprs           Disable EGPRS

Note that enabling EGPRS is experimental and will most likely break
packet transmission until a minimal required set of EGPRS
functionality is implemented.

Sponsored-by: On-Waves ehf
2015-11-30 12:20:36 +01:00
Jacob Erlbeck c3c58046c7 edge: Get EGPRS multislot class
The EGPRS MS class ist contained in the MS_RA_capability information.
Its presence indicates, that the MS is able (and willing) to use
EGPRS.

This commit implements basic support for retrieving, storing, and
showing it in the VTY. The information is stored in the MS object.

Sponsored-by: On-Waves ehf
2015-11-30 12:20:36 +01:00
Jacob Erlbeck eb93f592e5 pcu: Enable dl-tbf-idle-time and idle-ack-delay by default
Currently these are enabled in the default config file. Since CoDel
is enabled by default in main() but should not be used without at
least dl-tbf-idle-time, the current default config may lead to
packet loss and performance problems.

This commit enables both features to provide a good (GPRS) performance
experience even without a configuration.

Sponsored-by: On-Waves ehf
2015-11-30 12:11:39 +01:00
Jacob Erlbeck f5898a0528 stat: Add global stat group
Add a global stat_item group for measurement values and a
corresponding macro to get and set the values.
Add a stat_item STAT_MS_PRESET to monitor the number of
MS objects in the storage.

Sponsored-by: On-Waves ehf
2015-11-30 12:11:29 +01:00
Jacob Erlbeck edfd7e3d94 encoder: Whitespace fixes
Sponsored-by: On-Waves ehf
2015-11-27 15:09:10 +01:00
Jacob Erlbeck 42aba81c2f stats: Enable stats subsystem
Sponsored-by: On-Waves ehf
2015-11-17 15:42:01 +01:00
Harald Welte 08e5d604d3 remove obsolete OpenBTS PCU interface support
This OpenBTS socket interface was originally added to enable GPRS
capabilitie with a forked version of OpenBTS, at a time when the public
OpenBTS release didn't yet have any GPRS support.

Meanwhile, the later OpenBTS releases included their own version of
GPRS, without any external PCU/SGSN/GGSN, so this interface is no longer
needed.

This also means that the OsmoBTS socket interface is now the default at
compilation time.  There is no other interface.
2015-11-13 16:07:25 +01:00
Harald Welte 19d1e9270d osmobts_sock.cpp: Add missing space in log statement. 2015-11-12 01:08:19 +01:00
Harald Welte 218482769b print/log OpenBTS / OsmoBTS variant in PCU startup
Otherwise it can be very confusing, as Max had to figure out today...
2015-11-12 01:07:41 +01:00
Harald Welte d32cbbb130 rename sysmo_sock.cpp to osmobts_sock.cpp
This also renames the --enable-sysmbts option to --enable-osmobts

This socket interface was nevery sysmoBTS specific, but it is a generic
socket interface to any OsmoBTS supported layer1/hardware.  So it was a
mis-nomer so far.
2015-11-12 01:01:35 +01:00
Holger Hans Peter Freyther 8df447dc77 stats: Include the header file for the new class identifier 2015-11-07 21:04:40 +01:00
Holger Hans Peter Freyther b8a5426cf0 stats: Attempt to compile fix the new rate_ctr
We wanted to support gcc-4.2 and this didn't allow us to use
the C99 initializers inside C++ code. Attempt to initialize
the class_id correctly.
2015-11-07 21:01:23 +01:00
Jacob Erlbeck 2db0f08e08 bssgp: Use measured leak rate for flow control
The leak rate sent to the SGSN does not reflect the current CS level,
lost frames, and control message overhead. So the SGSN cannot do
proper queue control under non-optimal conditions.

This commit computes the leak rate for the last flow control interval
by computing the maximum theoretical leak rate and basically
substracting control blocks, nacked blocks, and reduced block sizes
due to CS downgrade. By using this approach, the value will by more
stable on low load, where the value will tend to be near the value
derived from the configuration. On full load the transmitted value is
completely derived from the measurements.

Note that the MS default values are no adapted to the adapted BVC
leak rate, since a single MS which has a lower link quality would
otherwise be reducing the rate of another MS with good radio
conditions, which would not make much sense if they did not share any
PDCH.

Sponsored-by: On-Waves ehf
2015-09-11 11:52:02 +02:00
Jacob Erlbeck 7c8d39a67b poll: Count failed procedures
When a timeout has occured several times, the procedures handled by
poll_timeout are aborted. This happens when the number of repetitions
exceed N3105. Currently only the timeouts themselves are counted.

This commits adds counters that are incremented if a procedure has
really failed.

New counter:
- rlc.ass.failed:   Count failing UL and DL assigments via PACCH
- rlc.ack.failed:   Count failing DL Ack/Nack requests

Sponsored-by: On-Waves ehf
2015-09-07 14:10:35 +02:00
Jacob Erlbeck c8cbfc2c98 bts: Start a DL TBF if needed after establishment of an UL TBF
Currently an existing DL TBF can get lost in the process of
establishing an UL TBF via RACH. This can lead to stalled connections
until the network sends more LLC frames.

This commit adds a check for a non-empty LLC queue after the UL TBF
has been established to rcv_control_ack (GPRS_RLCMAC_UL_ASS_WAIT_ACK
path) to eventually establish a new DL TBF on the UL TBF's PACCH.

Sponsored-by: On-Waves ehf
2015-09-01 12:01:20 +02:00
Jacob Erlbeck ae0a799f44 bts: Release DL TBF instead of killing in rcv_resource_request
Currently an existing DL TBF is freed immediately, when a resource
request is received. This makes sense since the MS might have dropped
it when switching to the PDCH signaled via the AGCH for the SBA. But
if the TBF still is assumed to exist on the MS side, there might be
TFI collisions if the old TBF object is not kept to block its TFI
for some time.

This commit changes rcv_resource_request to call release() instead of
tbf_free() on the DL TBF object (if it exists).

Sponsored-by: On-Waves ehf
2015-09-01 12:00:31 +02:00
Jacob Erlbeck 91ff7d1864 tbf: Refactor reuse_tbf into releasing and DL TBF establishment
Currently reuse_tbf (partly) resets the old DL TBF and uses its PACCH
to establish a new DL TBF. The method can not be used with UL TBFs.

This commit replaces the reuse_tbf method into a
gprs_rlcmac_dl_tbf:release method which triggers the TBF's timer
based deletion (so that the TFI is still reserved for some time) and
a gprs_rlcmac_tbf::establish_dl_tbf_on_pacch which can establish DL
TBFs on existing PACCHs of either DL or UL TBFs.

Sponsored-by: On-Waves ehf
2015-09-01 11:49:04 +02:00
Jacob Erlbeck 9659d59307 tbf: Keep the old MS object alive in extract_tlli
Currently when a second MS object has been created for an MS, because
the TLLI was not known yet, the will be detected in
gprs_rlcmac_tbf::extract_tlli and the two objects will be merged by
update_ms. But when the dl_tbf is moved from the old to the new
(second) MS object, the old MS object can get idle and be removed
before the object are merged. This can cause LLC frame loss when the
MS object is deleted immediately after getting idle (no timeout
configured).

This commit adds a guard to keep the MS object until extract_tlli has
been executed.

Sponsored-by: On-Waves ehf
2015-09-01 11:48:26 +02:00
Jacob Erlbeck cf6ae9d12f Revert "tbf: Do not kill DL TBF on Packet Resource Request"
This reverts commit e91bd3babd.

That commit seems to cause hanging DL TBFs when there was a RACH
based UL TBF establishment while it that TBF is active. This could be
caused by the use of a different PDCH for the SBA.

Conflicts:
	tests/tbf/TbfTest.cpp
	tests/tbf/TbfTest.err
2015-09-01 11:48:25 +02:00
Jacob Erlbeck af75ce8e15 l1: Use the FN of all data_ind/ra_ind DSP messages
Currently all of these messages are discarded if they are assumend to
be caused by noise. But even in these cases, the FN and TN values
which are added by the DSP are valid. So these can be used to update
the current_frame value.

The osmo-bts sets the fBFILevel of a physical channel to -200dB if it
is used for PDTCH or PACCH which is the case for all PDCH. This way
a data_ind or ra_ind message is already send at least once per block
period (4 frames) per PDCH. These messages are passed to either
handle_ph_data_ind or handle_ph_ra_ind even if they contain garbage
data.

The ra_ind messages are sometimes sent a few frames earlier than
data_ind messages using the same frame.

This commit adds calls to update the current_frame value based on all
of these messages before they are discarded. The FN taken from ra_ind
are passed with an increased max_delay (5) to compensate for early
ra_ind messages.

Sponsored-by: On-Waves ehf
2015-08-28 12:23:07 +02:00
Jacob Erlbeck be4a08b58a poll: Count unexpected block FN values
Currently a log entry is written if FN_data_ind - FN_time_ind <= -13.

This commit adds a counter 'rlc.late-block' that is incremented in
these cases.

Sponsored-by: On-Waves ehf
2015-08-28 12:23:07 +02:00
Jacob Erlbeck 60f77033ad poll: Use the data_ind FN as time source for current frame
The FN of the data_ind taken from the DSP are monotonic, so latency
does not affect the detection of poll timeouts if these FN are used.
If the FN is larger than a poll_fn value, it can safely be assumed
that the poll response will not arrive later on.

Currently a max_delay of 60 frames is used, which has the drawback
that additional ~250ms will pass until a lost ACK is detected.

Using the data_ind's FN alone breaks the poll timeout detection if
there are no other MS sending data blocks.

This commit adds BTS::set_current_block_frame_number that is called
with the FN taken from data_ind messages. The max_delay is set to 0
which removes the additional delay, when this FN is used to detect
poll timeouts. So the average additional delay decreases with the
number of data_ind per time. The current_frame is updated unless it
seems to have been updated already (assumed if 0 < cur_fn - block_fn
< 500). Thus the time_ind has still priority to update the
current_frame value.

Sponsored-by: On-Waves ehf
2015-08-28 12:23:07 +02:00
Jacob Erlbeck e77d49f2a2 poll: Set the max_delay to 60 frames
Currently the max_delay parameter is set to 13, since that is
slightly above maximum number of frames that a time_ind can preceed a
block's data_ind of the same frame. This assumes that these messages
are not reordered after thay have been obtained from the DSP. In the
current implementation, the GPRS data_ind can directly be taken from
the DSP by the PCU while the time_ind messages are provided via the
BTS. So the messages are queued differently in that case, resulting
in a additional delay of the data_ind with respect to the time_ind.
The propability for this raises with a increased CPU load of the PCU.

If this happens, a poll timeout is detected by mistake and the poll
is either retried or cleared.

This commit increases the tolerance to 60 frames, since
values for FN_data_ind - FN_time_ind of up to 50 frames have been
observed under heavy PCU load.

Sponsored-by: On-Waves ehf
2015-08-28 12:23:07 +02:00
Jacob Erlbeck ac49d0943a poll: Add a max_delay parameter to PollController::expireTimedout
Currently the maximum additional delay is hard coded to 13. This
value depends on the source of the frame number value.

This commit adds the max_delay parameter to make it caller dependant.

Sponsored-by: On-Waves ehf
2015-08-28 12:23:07 +02:00
Jacob Erlbeck 16d29c7da4 tbf: Add logging for polling
This commit adds the relevant frame number to the "poll timeout"
logging message. In addition, logging is added to the places where
poll_fn gets set.

The goal is to track down the source for frequent "poll timeout"
messages.

Sponsored-by: On-Waves ehf
2015-08-28 12:23:07 +02:00
Jacob Erlbeck b6b3c7eb27 tbf: Use explicit initialisations in constructor (Coverity)
Currently when allocating tbf_alloc_ul_tbf or tbf_alloc_dl_tbf
objects, the allocated memory area is pre-initialised by talloc_zero
before the C++ constructors are called. This is not recognised by
Coverity, since there is no talloc model file yet. Thus Coverity
complains about missing initialisers.

On the other hand, it is still planned to convert the TBF classes
into real C++ ones. So instead of silencing Coverity directly, this
is an opportunity to do it the C++ way.

This commit adds initialisers and initialisation code for all
members that relied on talloc_zero. The corresponding calls to
talloc_zero are replaced by calls to talloc to give ASAN/valgrind
a chance to detect future initialisation errors. Some initialisation
code is also moved from setup_tbf to the constructors, notably the
initialisation of the bts pointer.

Fixes: Coverity CID 1320604, 1320605, 1320606

Sponsored-by: On-Waves ehf
2015-08-28 12:07:14 +02:00
Jacob Erlbeck 1c95bd383e openbts: Remove unused declaration of fl1h in udp_read_cb
Fixes:
openbts_sock.cpp:94:22: warning: unused variable 'fl1h'

Sponsored-by: On-Waves ehf
2015-08-27 11:47:35 +02:00
Jacob Erlbeck 159d4de370 ms/vty: Show LLC queue octets and packets in both views
Currently the per IMSI/TLLI view only shows the number of packets and
the 'all' view does not show any LLC related information at all. A
constant LLC queue length is often an indication for a stalled TCP
connection where the RLC layer has stopped to send downlink data
messages.

This commit adds the number of packets to the 'all' view and the
number of octets to the IMSI/TLLI views.

Sponsored-by: On-Waves ehf
2015-08-27 10:33:10 +02:00
Jacob Erlbeck c62216b4fc ms/vty: Show old TBFs
This commit extends the 'show ms imsi|tlli' command to show the old
TBFs, too.

Sponsored-by: On-Waves ehf
2015-08-24 12:23:50 +02:00
Jacob Erlbeck 6835cead8c ms: Store references to replaced TBFs in the MS object
Currently when calling GprsMs::attach_tbf and a TBF of the same
direction already exists, the old TBF gets detached from the MS
object.

Therefore that TBF object loses access to that MS object including
for instance TLLI and IMSI.

This leads to failing DL TBF reuses, since the downlink assigment
cannot be sent on the PACCH later on because that must be sent on the
old DL TBF which ms() is NULL and the new DL TBF cannot be retrieved.

This commit fixes this bug by changing the GprsMs implementation to
keep a list of replaced (old) TBFs. TBFs are only removed when they
are being detached explicitely (see tbf_free and set_ms).

Addresses:
tbf.cpp:741 We have a schedule for downlink assignment at uplink
TBF(TFI=1 TLLI=0xf35a680e DIR=UL STATE=RELEASING), but there is no
downlink TBF

Sponsored-by: On-Waves ehf
2015-08-24 12:23:50 +02:00
Jacob Erlbeck 6e013a136a bssgp: Only call bssgp_tx_llc_discarded if the bctx exists
While this does not happen in real use, and unset btcx can lead to
segfaults in test cases. The other code outside of gprs_bssgp_pcu.cpp
does not depend on bctx being non-NULL:

Sponsored-by: On-Waves ehf
2015-08-24 12:23:50 +02:00
Jacob Erlbeck af387e2199 llist: Add missing const qualifier in llist cast method
The missing const qualifier prevents the llist_empty() C++ wrapper
function from being compiled successfully when it is used.

Sponsored-by: On-Waves ehf
2015-08-24 12:23:50 +02:00
Jacob Erlbeck 444bc82081 tbf: Use C++/talloc magic to support TBF constructors/destructors
The TBF object are currently created by using talloc_zero/talloc_free
directly from plain functions. Therefore C++ constructors and destructors
are not called. So the only initialisation that is done is setting
every member to 0. Non POD members do not have their constructors
called either, which makes it impossible to use the current LListHead
class for real members when the LListHead::m_back member has to be set.

This commit changes the TBF allocation functions to call the
corresponding C++ constructor after the call to talloc_zero and to
register the C++ destructor with the talloc context, so that is is
called before talloc_free actually frees the memory.

With this change, non-POD members and custom
constructors/desctructors can be used with gprs_rlcmac_tbf,
gprs_rlcmac_dl_tbf, and gprs_rlcmac_ul_tbf.

Note that this change is only a single step of the plan to turn the
TBF classes into real C++ classes.

Sponsored-by: On-Waves ehf
2015-08-24 12:23:50 +02:00
Jacob Erlbeck e0b21f41c2 tbf: Move pending LLC frames when merging MS objects
Currently the pending LLC packets are lost in some cases when MS
objects are merged, for instance after a RACH when there were 2 MS
object for the same MS (they get merged, when the TLLI is known for
both objects).

This patch modifies GprsMs::merge_old_ms to move all pending LLC
packets (if there are any) to the current MS object.

Sponsored-by: On-Waves ehf
2015-08-21 19:02:18 +02:00
Jacob Erlbeck 257b630216 llc: Add move_and_merge method to llc_queue
This methods takes all LLC frames from the old LLC queue and moves
them into the current. If both queues are ordered chronologically
(recv_time), the resulting queue is also ordered.

Sponsored-by: On-Waves ehf
2015-08-21 19:02:18 +02:00
Jacob Erlbeck e91bd3babd tbf: Do not kill DL TBF on Packet Resource Request
Currently all active TBF of an MS are killed if a Packet Resource
Request is received from the MS. In general this happens after a RACH
request. This does not happen after a resource request that has been
included into a Downlink Ack/Nack.

Sometimes an UL TBF is requested by an MS via RACH while a DL TBF is
running for instance to send a TCP Ack. This can happen, if a former
request via PACCH did not work.

This commit removes the killing of the DL TBF from
gprs_rlcmac_pdch::rcv_resource_request().

Sponsored-by: On-Waves ehf
2015-08-21 19:02:18 +02:00
Jacob Erlbeck 076f5c794d tbf/test: Fix existing tests
This commit fixes several issues:
- Set MS class in request
- Set IMSI in establish_ul_tbf_two_phase
- Fake assigment acknowledgement in establish_ul_tbf_two_phase
- Fix TFI bit offset to 1 (was 2)

Sponsored-by: On-Waves ehf
2015-08-21 19:02:18 +02:00
Jacob Erlbeck 537b149828 tbf: Fix typos in log messages concerning UL/DL
The TBF in create_dl_ass can be of any direction. The text in
rcv_resource_request uses DL instead of UL.

Sponsored-by: On-Waves ehf
2015-08-21 18:59:14 +02:00
Jacob Erlbeck 2b349b5d33 ms: Move MS information merging to GprsMS
Currently the merging of the meta information (MS class, IMSI) takes
place in gprs_rlcmac_tbf::merge_and_clear_ms(). This makes it
difficult to merge the internal state and does not directly relate to
TBFs anyway.

This commit moves this into a new method GprsMs::merge_old_ms.

Sponsored-by: On-Waves ehf
2015-08-18 11:55:03 +02:00
Jacob Erlbeck ebebad1c92 ns: Reconnect NSVC after timeout
Currently the signal S_NS_ALIVE_EXP emitted by the NS layer if the
alive check has timed out too often is ignored. This prevents the PCU
from reconnecting to the SGSN if it has not been accessible for some
time.

This commit modifies nsvc_signal_cb to reset the NSCV if
S_NS_ALIVE_EXP is sent, so that the PCU continues to send NS RESET
message if that happened.

Sponsored-by: On-Waves ehf
2015-08-17 16:29:34 +02:00
Jacob Erlbeck 56af6d55ed ns: Add logging support
Currently there is not support for Network Service (NS) logging.

This commit adds the missing definitions and sets the default level
to INFO. Further configuration can now be done with the 'logging
level ns' VTY command.

Sponsored-by: On-Waves ehf
2015-08-17 16:24:11 +02:00
Jacob Erlbeck f76fedeed5 vty: Change API to have node installation be done by int
This commit fixes the go_parent_cb API according to libosmocore's
commit of the same name.

Fixes:
pcu_vty.c:799:2: warning: initialization from incompatible pointer
type [enabled by default]
  .go_parent_cb = pcu_vty_go_parent,

Sponsored-by: On-Waves ehf
2015-08-17 16:23:27 +02:00
Jacob Erlbeck fea17f8b8c ms: Do not retrieve MS with IMSI 000 from the storage
The IMSI '000' is used as default value for an incoming BSSGP
message's IMSI IE. This can lead to the retrieval of the wrong MS
object from the storage.

This commit changes the get_ms method to skip the IMSI search if such
an IMSI is passed as selector.

Note that changing the default value in the BSSGP code does not help
here.

Sponsored-by: On-Waves ehf
2015-08-17 16:23:27 +02:00
Jacob Erlbeck af9a39d954 tbf: Use update_ms instead of confirm_tlli in handle()
The confirm_tlli method does not handle TLLI clashes in the MS
storage.

This commit changes gprs_rlcmac_dl_tbf::handle() to use update_ms
instead.

Sponsored-by: On-Waves ehf
2015-08-17 16:23:27 +02:00
Jacob Erlbeck 28c40b1757 tbf: Clean old MS objects if they have the same TLLI
Currently if an MS retries to access the PCU by using RACH and if
there is already an entry for that MS, a duplicated MS object
referring to the same TLLI is created. This is caused by blindly
setting the TLLI without querying the MS storage to avoid
inconsitencies.

This leads to several entries in the MS storage that are assigned to
the same TLLI. If that happens, 'show ms all' can display multiple
entries with the same TLLI (note that an MS object can belong to
several TLLIs, so there might be an intersection that is not visible
in the list) or 'show tbf all' can show entries with MS_CLASS == 0 in
some cases.

This commit changes update_ms() to merge and clean up old entries
that belong to the given TLLI if they exist. Some data (like the MS
class) is copied to the new MS object.

Note that TBF belonging to the old MS object are deleted immediately
if they have not registered a timer.

Sponsored-by: On-Waves ehf
2015-08-17 16:23:01 +02:00
Jacob Erlbeck 1c3b8998bc ms: Set default CoDel interval to 4s
The current default interval is 2s which seems to be too short when
the DL TBF has to be established. This may cause freezing or really
slow TCP connections.

This commit increases the default value to 4s. When the
dl-tbf-idle-time is set, DL TBF are established less frequent, so
smaller values (like 2s or below) can be used to improve the average
latency when the load is high.

Sponsored-by: On-Waves ehf
2015-08-14 16:35:34 +02:00
Jacob Erlbeck ac28905082 tbf: Handle TLLI change on DL
When doing an RA Update the network can request to change the TLLI.
In this case, there can be 2 MS objects with different TLLI for a
single real MS. The first is associated with the old TLLI and the
IMSI, while the second is associated with the new TLLI and no IMSI if
it had been created for the uplink TBF. When the first message with
the new TLLI and the IMSI arrives from the network, the PCU is able
to detect this.

Currently this is not handled properly. The TBFs of the old MS object
are not cleaned up properly, keeping the old MS from being deleted.

This patch modifies gprs_rlcmac_dl_tbf::handle to check for this and
if neccessary to move an existing DL TBF and to clean up the old MS
object to ensure its deletion.

Sponsored-by: On-Waves ehf
2015-08-14 16:35:29 +02:00
Jacob Erlbeck 04e72d34f5 tbf: Always start T3193 when changing state to GPRS_RLCMAC_WAIT_RELEASE
Currently when receiving a PACKET DL ACK/NACK message with the Final
Ack Indicator bit set, the TBF's state is set to
GPRS_RLCMAC_WAIT_RELEASE but T3193 is only started when the LLC queue is
empty. Otherwise the reuse_tbf() method is called to establish a new
DL TBF. In that case, the timer is not started. This will leave the
current TBF without a timer so it is potentially not released later
on.

This is recognisable by sticky entries in the output of the
'show tbf all' command and possibly allocation failures if there are
too many of them.

This commit changes the code to always start T3193 to make sure, that
a timer is always active when the the state is set to
GPRS_RLCMAC_WAIT_RELEASE.

Note that TS 44.060, 9.3.2.6 requests to release the 'old' TBF
immediately in some cases, which is not implemented by this change.
This will lead to a longer reservation period of the TFI only, which
is safer than reassigning it too early.

Sponsored-by: On-Waves ehf
2015-08-13 19:51:50 +02:00
Jacob Erlbeck 6eed1911fd bssgp: Fix leak rate computation CS value
Currently the initial_cs_dl value is used to compute the maximum leak
rate. This can be too low if adaptive CS selection is used.

This commit changes gprs_bssgp_tx_fc_bvc to derive the max CS level
from the configuration.

Sponsored-by: On-Waves ehf
2015-07-21 19:22:36 +02:00
Jacob Erlbeck b31f5ef699 pcu: Enable LLC CoDel by default
Currently CoDel is disabled by default.

This commit enables CoDel on start up with the default interval time,
equivalent to the 'queue codel' VTY command.

To disable CoDel, use the 'no queue codel' command.

Sponsored-by: On-Waves ehf
2015-07-21 19:22:36 +02:00
Jacob Erlbeck d4ad731bae llc: Use CoDel to drop packages from the LLC queue
Currently packets are only dropped if they have reached their maximum
life time. This leads to LLC queues being constantly filled under
load, increasing the latency up to the maximum life time. This kind
of bufferbloat hinders TCP's congestion avoidance algorithms. To keep
the queues short, the CoDel active queue management algorithm can be
used.

This commit changes to llc_dequeue method to apply the CoDel
algorithm to selectively drop LLC frames before they passed to the
TBF layer to be encoded in BSNs. This feature is currently disabled
by default.

The CoDel state is managed per MS since the LLC queues are also kept
in the MS objects.

Note that there is still some buffering in the TBF objects, in the
worst case (CS4) 3.5kByte + LLC-MTU octets are stored there. The
resulting additional packet delay is not (yet) taken into account for
CoDel.

Also note that configuration changes are applied to new MS objects
only.

The following VTY commands are added to the 'pcu' node:

- queue codel           activates CoDel, the interval is selected by
                        the implementation
- queue codel interval <1-1000>
                        activates CoDel with a fixed interval given
                        in centiseconds (10ms-10s)
- no queue codel        deactivates CoDel

Which interval value to use is still an open issue. For high speed
links (e.g. Ethernet), CoDel suggests 100ms. For slower links, the
expected RTT is recommended. The current implementation uses a
default value of 2000ms.

Measurements:

Note that the following measurements depend on several other factors,
most notably the interaction with the SGSN's flow control. They are
just examples to give an idea how CoDel might influence some
parameters.

The measurements have been done with a single E71, first with a
running ping only (Idle), then with an additional TCP download
of a 360k file (Busy). The CoDel interval was set to 1s.

- Idle :
        ping ~400ms, avg queue delay 0ms, dropped 0
- Busy, No CoDel:
        ping ~6s, avg queue delay 4-6s,
        dropped  0, scheduled  948, duration 54s
- Busy, CoDel:
        ping 500-1500ms, avg queue delay ~600ms,
        dropped 77, scheduled 1040, duration 60s

More measurements with two MS downloading in parallel (two
independant measurements per case).

- Busy, No CoDel:
        dropped  0, scheduled 1883, duration 121s
        dropped 19, scheduled 2003, duration 133s
- Busy, CoDel:
        dropped 22, scheduled 1926, duration 116s
        dropped 22, scheduled 1955, duration 108s

Sponsored-by: On-Waves ehf
2015-07-21 19:22:36 +02:00
Jacob Erlbeck 4f666bc113 llc: Add CoDel AQM implementation
This commit adds an implementation of the CoDel algorithm based on
the reference pseudocode presented in
http://queue.acm.org/appendices/codel.html. Instead of abstracting
the queue itself, the implementation provides a time stamp based
automaton which is invoked after a package has been dequeued.

Note that the modifications of the algorithm shown in
https://tools.ietf.org/html/draft-ietf-aqm-codel-01 are not yet
applied.

Sponsored-by: On-Waves ehf
2015-07-21 19:22:32 +02:00
Jacob Erlbeck 7f79f0d332 bssgp: Adapt flowcontrol MS default to current alloc algorithm
Currently the values Bmax/R default MS are computed under the
assumption than min(4, N_PDCH) DL slots are allocated for an MS, even
if multislot assignment is not enabled.

This commit changes the computation to assume 1 DL slot if algorithm
A is selected or the dynamic algorithm is used and has disabled
multislot assigment due to high load.

Sponsored-by: On-Waves ehf
2015-07-17 12:06:19 +02:00
Jacob Erlbeck 77da35515c alloc: Make alloc_algorithm_dynamic stateful
Currently there is no persistent state being used in
alloc_algorithm_dynamic. So algorithm B is even used in persistent
high usage scenarios. If there are many active TBFs, multislot
assigments are not fair, because MS of a "higher" multislot class get
higher troughputs. On the other hand, as long as all PDCH are busy no
bandwidth will be wasted even if all MS use algorithm A.

This commit modifies alloc_algorithm_dynamic to disable algorithm B
when that call fails. It then keeps it disabled until there is a
single PDCH which is idle (it is considered idle, if there is at most
one active DL TBF assigned to it).

Sponsored-by: On-Waves ehf
2015-07-16 19:24:16 +02:00
Jacob Erlbeck 7af53e61f0 alloc: Use a separate usage computation for algo A
Currently algorithm A can select an TBF even when there is no free
TBF in the reverse direction. While this does not necessarily lead to
an allocation failure, the probabily is higher. In addition, the
current slot reservations are not taken into account.

This commit changes the selection algorithm to prefer slots where TFI
are available in both directions and which are less reserved.

Sponsored-by: On-Waves ehf
2015-07-16 19:24:16 +02:00
Jacob Erlbeck e21b79cb21 alloc: Change tx_window optimization strategy
Currently each tx_window combination is checked only once by using a
set containing the sets of TX slots that have been checked already.
This approach does not ensure, that num_tx and ul_ts really match the
tx_window being tested. This does not make a difference with the
current test cases probably because num_tx starts with 1 and is
increased each iteration. Since the bitmap optimization is equivalent
to a cache optimization strategy that only uses tx_window as key. On
the other hand, ul_ts, num_tx, and rx_mask cannot be derived from
tx_window, but these values are also refered to after the call to
test_and_set_bit(). This makes it difficult to prove that correctness
of the caching. While this will not lead to a defect, the results
might be less optimal.

This commit changes the optimization strategy to skip all tx_window
where ul_ts and ul_ts+num_tx-1 are not both contained.  This provides
a similar degree of optimization like the set approach (only the
iteration with num_ts == 8 is not optimized, which only applies to to
ms class 18 and 29 MS) but ensures that the values of the related
variables have a clear relationship.

Note that the bitset based optimization for rx_window does not suffer
from a possible cache inconsistency, since only tx_window and
rx_window (tx_slot_count and rx_slot_count can be derived from the
windows and thus are covered by the cache key) are used after the call
to test_and_set_bit(). tx_window is constant over the whole lifetime
of the cache.

Sponsored-by: On-Waves ehf
2015-07-16 19:24:16 +02:00
Jacob Erlbeck f16a069fd7 pcu: Use alloc_algorithm_dynamic by default
The dynamic algorithm behaves like B until there are no TFI left.

This commit changes the default algorithm to to former.

Ticket: #1934
Sponsored-by: On-Waves ehf
2015-07-16 19:24:16 +02:00
Jacob Erlbeck 5979fe9d8a alloc: Add counters for successful algo A/B allocations
This adds counters for algorithm A and B with count successful
allocation combined for UL and DL.

Ticket: #1934
Sponsored-by: On-Waves ehf
2015-07-16 19:24:16 +02:00
Jacob Erlbeck 400ec02e8a alloc: Add 'dynamic' allocation algorithm
The idea behind this meta algorithm is to automatically select one of
the other algorithms based on the system state. Basically algorithm B
will be selected if the PDCH usage is low to improve throughput and
latency. Algorithm A will be selected to support more concurrent MS.

This commit adds a first simple state-less version of this algorithm
that always tries B first and only if that fails A is tried
afterwards.

The following VTY command is added to the 'pcu' node:

 - alloc-algorithm dynamic

Ticket: #1934
Sponsored-by: On-Waves ehf
2015-07-16 19:24:15 +02:00
Jacob Erlbeck 40da3e17e5 alloc: Remove disabled code fragment for multi-UL allocation
This part of algorithm_b has already been disabled. Further work may
depend on this, but it is going out of sync. So this commit removes
it completely.

Sponsored-by: On-Waves ehf
2015-07-16 19:24:15 +02:00
Jacob Erlbeck 5a2b8be3f5 alloc: Refactor alloc algorithms to only apply changes on success
Currently these algorithms modify other objects (MS, TBF, PDCH) even
if the allocation will fail later on. To implement an algorithm that
dynamically tries another algorithm on failure (e.g. A after B), the
first (failing) algorithm should not change or damage anything.

This commit refactors algorithm A and B to delay the actual allocation
until it is known that the allocation will not fail.

Ticket: #1934
Sponsored-by: On-Waves ehf
2015-07-16 19:24:13 +02:00
Jacob Erlbeck 2b558857dd alloc: Remove redundant first_common_ts handling
Currently this code path is only used, if an allocation has been
taken place in a former call to an allocation algorithm function.
If this was for an DL TBF, the first common TS was selected,
otherwise the least used common TS was selected for an UL TBF.
The shrinking of the UL set (to 1<<first_common_ts) is done in the
latter case.

This commit removes an additional code path that aligns the UL set to
first_common_ts, because it has no more influence on the set of
common TS after both UL and DL TBF have been allocated.

Sponsored-by: On-Waves ehf
2015-07-16 18:51:40 +02:00
Jacob Erlbeck b2439bbb8a ms: Add is_idle() method to GprsMs::Guard
Currently there is no simple way to determine, whether the MS object
protected by a guard will continue to exist after the guard object is
destroyed.

This patch adds a is_idle() method that will return true if the MS
object is just kept by the guard from being idle. In that case, the
MS object would either be deleted or return true for
GprsMs::is_idle() after the guard's destruction, provided that no
TBF attachment took place in between.

Sponsored-by: On-Waves ehf
2015-07-16 10:25:14 +02:00
Jacob Erlbeck 3a10dbd564 tbf: Put the TFI->TBF mapping into the PDCH objects
Currently the TBFs are registered in a TFI indexed array within the TRX
objects. TBFs can be searched globally by TFI and TRX number. This
conflicts with the use of the same TFI for different TBF on different
PDCH. This use case requires the specification of the PDCH as
additional search dimension.

This commit moves the TFI index TBF arrays into the PDCH objects. The
related methods are updated accordingly.

Ticket: #1793
Sponsored-by: On-Waves ehf
2015-07-16 10:25:14 +02:00
Jacob Erlbeck e0853cdf42 alloc: Allocate TFI per slot (algorithm A)
Currently the TFI are managed per TRX, thus only a maximum of 32 TBF
per direction and per TRX are possible simultaneously.

This commit modifies algorithm_a() to allow the sharing of TFI
between different PDCH. Since algorithm A only assigns a single slot
to each TBF, the TFI of each PDCH can be assigned independently.
This increases the maximum to 32 TBF per direction and per PDCH
concerning the TFI allocation.

Ticket: #1793
Sponsored-by: On-Waves ehf
2015-07-16 10:25:14 +02:00
Jacob Erlbeck 5879c6493f tbf: Move TFI selection into alloc_algorithm
Currently the TFI and the TRX have to be determined before the actual TBF
allocation function is called, passing TFI and TRX number as
parameters. This does fit to TFI reuse for different slots, since
this were tightly coupled with the slot selection.

This commit just moves the TFI selection into the alloc_algorithm
functions. The tfi parameter is removed from the the TFI alloc
functions. The trx parameter is changed into use_trx to optionally
limit the trx selection (same semantics like in tfi_find_free).

Sponsored-by: On-Waves ehf
2015-07-16 10:25:14 +02:00
Jacob Erlbeck 47a57f6f86 pdch: Manage TFIs per direction
Currently a single bit set is used to maintain a set of used TFI
without distinguishing between uplink and downlink. Since the
namespaces of UL and DL TFI are separate, this implementation is
not correct.

This commit changes gprs_rlcmac_pdch to use a separate bit set for
each direction. It also replace the corresponding conditional fprintf
statement in check_tfi_usage (AllocTest.cpp) by an equivalent
OSMO_ASSERT.

Sponsored-by: On-Waves ehf
2015-07-16 10:25:14 +02:00
Jacob Erlbeck 57cf69a18c alloc: Fix MS_B/MS_C interpretation
Currently the handling of MS_B and MS_C is not compliant with TS
45.002, annex B.1. These values may only interpreted as 0, if
frequency hopping is not enabled and if there is no change from Rx to
Tx or vice-versa.

This commit sets Ttb/Trb to 1 if the table entry is MS_B/MS_C, since
only combined down/up access modes are supported.

Sponsored-by: On-Waves ehf
2015-07-16 10:24:37 +02:00
Jacob Erlbeck dd08ac86e6 alloc: Do not use masking for multislot class type 2 MS
Currently the masks are computed equally for each class type. This
does not make much sense for class type 2 MS, since those are capable
to work in full duplex mode.

This commit sets the masks to 0xff for class type 2 MS.

Sponsored-by: On-Waves ehf
2015-07-16 10:24:37 +02:00
Jacob Erlbeck bae33a7001 alloc: Select applicable Tta/Tra
According to TS 45.002, 6.4.2.2 the choice whether Tta or Tra has to
be applied, depends on the medium access mode (currently always
dynamic) and the number of UL/DL slots. Currently either value can be
used which might result in combinations not covered by the spec.

This commit changes find_multi_slots() to skip non-compliant
combinations.

Note that this code will have to be extended, if other medium
access modes are implemented.

Sponsored-by: On-Waves ehf
2015-07-16 10:24:37 +02:00
Jacob Erlbeck 5e46a20e03 alloc: Use an enum instead of numbers to select the mask
The local enums MASK_TT and MASK_TR replace the hard coded indices.
The variable m_idx is renamed to mask_sel for more clarity.

Sponsored-by: On-Waves ehf
2015-07-16 10:24:37 +02:00
Jacob Erlbeck c135b878cd alloc: Merge find_least_busy_pdch and find_least_reserved_pdch
Both functions only differ in the computation of the value for
num_tbfs.

This commit merge both functions and adds a parameter containing a
function for that compuation.

Sponsored-by: On-Waves ehf
2015-07-16 10:24:37 +02:00
Jacob Erlbeck 1139ec1d0f sba: Fix loop exit in SBAController::alloc (Coverity)
The commit 506f156f7a has reverted the
TS search order. The outer loop exit condition was not updated
accordingly. This bug would would only lead to an error if there were
multiple TRX where the first TRX has not got any PDCH assigned.

This commit corrects the break condition.

Fixes: Coverity CID 1311776
Sponsored-by: On-Waves ehf
2015-07-15 14:17:19 +02:00
Jacob Erlbeck 3db617f14a llc: Fix comparison warning
Fixes: Jenkins build #609 warning

Addresses:
  llc.cpp:56, GNU C Compiler 3 (gcc), Priority: Normal
  comparison between signed and unsigned integer expressions

Sponsored-by: On-Waves ehf
2015-07-14 08:51:55 +02:00
Jacob Erlbeck efe62a7395 alloc: Use least reserved PDCH for algo A
Currently the slot selection of algorithm A is based on the current
slot usage by active TBF. Especially in the Dl after UL case which
reflects the commen use case "MS initiates TCP connection", the
resulting distribution is not optimal with respect to PDCH usage.

This commit changes the implementation to use the slot reservation
information instead.

Sponsored-by: On-Waves ehf
2015-07-07 11:52:28 +02:00
Jacob Erlbeck 506f156f7a sba: Reverse TS search order
Currently the search for an enabled PDCH slot for SBA start with the
first TS. If there are more than 2 PDCH slots enabled, this slot will
conflict with an existing multislot reservation for most multislot
classes. This were less likely if the search were reversed and
started with the last slot due to the 3 slot shift between Tx and Rx.

When multislot allocation is enabled and several MS are connected,
and increased rate of poll timeouts can be observed.

This commit tries to reduce the number of poll timeouts by reverting
the slot search order for SBA allocation.

Sponsored-by: On-Waves ehf
2015-07-07 10:41:44 +02:00
Jacob Erlbeck 1653f837e3 alloc: Disable inner loop debugging by default
The current logging statements within the inner loop of
find_multi_slots drain quite a lot of CPU resources even if
LOGL_DEBUG is not enabled. This might cause issues on the target
hardware.

This commit disables these LOGP calls unless the
ENABLE_TS_ALLOC_DEBUG macro has been set explicitly. This results in
a reduction in the CPU usage reported by callgrind for
find_multi_slots from 42% to 25% when executing AllocTest.

Sponsored-by: On-Waves ehf
2015-07-07 10:35:28 +02:00
Jacob Erlbeck 20b7ba7501 alloc: Optimize find_free_usf
According to callgrind, this function consumes 33% CPU when running
the AllocTest program.

This commit uses the assigned_usf() method to get the USFs allocated
by a PDCH instead of traversing the TBFs.

Sponsored-by: On-Waves ehf
2015-07-07 10:35:28 +02:00
Jacob Erlbeck cc9358f95a tbf: Keep a set of used TFI and USF per PDCH
Currently is is rather expensive to get TFI and USF usage per PDCH,
because the TBFs need to be scanned to get that information.

This commit adds corresponding bit sets which get updated by the
attach_tbf/detach_tbf methods of the gprs_rlcmac_pdch class.

Sponsored-by: On-Waves ehf
2015-07-07 10:35:28 +02:00
Jacob Erlbeck 16c6ecc365 alloc: Skip common TS without free USF when rating
Currently the search of the "best" slot combination is done
separately from the UL slot selection, which can lead to an
allocation failure due to USF exhaustion even if another combination
had been possible.

This commit reduces the probability for this event by skipping UL
slots without free USF while calculation the capacity.

Note that the implementation is rather inefficient which will be
fixed by the following commits.

Sponsored-by: On-Waves ehf
2015-07-07 10:29:12 +02:00
Jacob Erlbeck 5f494b8415 alloc: Only reserve 1 UL slot with algorithm B
Since currently the algorithm B will only allocate a single UL slot
and will have to stick to it (first common TS), the other possible UL
slots will not be allocated while the reservation is kept.

This commit adds code to update the reserved set of UL slots to only
reserve the single common TS when the UL TBF is allocated.

Interestingly this leads to fewer allocated TBF in some cases due to
USF exhaustion. This will be improved by the following commit "alloc:
Skip common TS without free USF".

Sponsored-by: On-Waves ehf
2015-07-07 10:22:18 +02:00
Jacob Erlbeck 9ae282372c alloc: Set minimum slot capacity to 1
Currently the capacity of a PDCH slot is calculated as 32 - N_reserved
for each direction. This can result in a capacity of 0 and even
negative values.

This commit forces the capacity of an usable slot to be at least zero
under the assumption, that an overly reserved PDCH is still better
than none.

Sponsored-by: On-Waves ehf
2015-07-07 10:03:29 +02:00
Jacob Erlbeck ed46afda6f alloc: Only use common UL slots when calculating the capacity
Currently al possible UL slots are included in the capacity
calculation which is the base of the slot selection. Nevertheless
UL-only slots will never be used, since only one uplink slot (which
must be a common slot) will be used.

This patch changes the code to only include common slots in the
capacity sum.

Note that this might not be optimal if algorithm B supported
multiple uplink slots.

Sponsored-by: On-Waves ehf
2015-07-07 09:35:26 +02:00
Jacob Erlbeck ea65c72d06 alloc: Replace Algorithm B implementation
The current implementation always starts the downlink slot allocation
with the first possible slot, depending on which channels are enabled
and which multislot class is offered by the MS. So in configurations
with many (>4) PDCH, some PDCH are not really used.

The new implementation introduced by this commit differs as follows:

 - The reservation mechanism provided by GprsMs is used to avoid
   incompatibilities is used in the same way like algo A does. This
   basically means, that the allocation is done once when the first
   TBF is requested and then used until all TBF have been released.

 - All combinations of Rx and Tx slots are checked for compatibility
   with the multiscot class. Basically the combination with the most
   usable PDCH and the least number of reservations is used.

 - Only one UL slots is provided.

 - Tta and Tra are checked.

Sponsored-by: On-Waves ehf
2015-07-07 09:35:26 +02:00
Jacob Erlbeck c91c18e6ef tbf: Add Poll Timeout counters
This commits adds three poll timeout counters

  - RLC Assign Timeout
  - RLC Ack Timeout
  - RLC Release Timeout

to help diagnosing to cause for these events. There seems to be an
increased rate of these when a PDCH is shared by multiple TBFs.

Sponsored-by: On-Waves ehf
2015-07-07 09:33:29 +02:00
Jacob Erlbeck e0c734dcfe Revert "tbf: Add GprsMs* argument to update() and use it in reuse_tbf"
This reverts commit 2272a83a13b57ea7e99fe96ac76e4ad892e19e90.

The modification is no longer needed, since the call to update has
been removed from reuse_tbf().

Conflicts:
	src/tbf_dl.cpp

Sponsored-by: On-Waves ehf
2015-07-03 15:58:45 +02:00
Jacob Erlbeck 07111668d4 tbf: Remove call to update() in reuse_tbf
Since both TBF are based on the same reservation which means that
they should be compatible with respect to the slot usage, and since
the new TBF has not been forced to single slot usage, an update of
the allocation is not necessary now.

This commit removes the call to update() from within reuse_tbf().

Sponsored-by: On-Waves ehf
2015-07-03 15:58:43 +02:00
Jacob Erlbeck 4944c195d4 tbf: Set ms in call to tbf_alloc_dl_tbf
The call to tbf_alloc_dl_tbf misses the pointer to the GprsMs object
which is already known in that case (tbf_reuse). This leads to a full
reallocation of the PDCH slots, which is possibly incompatible with
the old set of slots. This can result in hanging TCP connections and
TCP connection failures.

This commit replaces the old NULL value by the actual GprsMs object.
Since the set_ms() is also done within the tbf_alloc_dl_tbf method,
that call is removed.

Sponsored-by: On-Waves ehf
2015-07-03 15:53:15 +02:00
Jacob Erlbeck 5cd496d208 alloc: Base algo A on reserved PDCHs
Currently algorithm A bases its time slots selection on the number of
TBF actively using the PDCHs. This statistically prefers the first
time slots, especially with short living TBFs. So when the first TBF
is triggered by an uplink transfer (which generally results in a
short-lived TBF) the potentially longer living DL TBF will be bound
to the same slot. When another MS then requests an uplink TBF, it
will get the same slot (no UL TBF currently active).

This commit changes the algorithm to base its selection on reserved
slots instead.

Sponsored-by: On-Waves ehf
2015-07-03 15:37:16 +02:00
Jacob Erlbeck 83426b20a3 alloc: Ignore slots with differing TSC if multiple slots are requested
According to TS 45.002, 6.4.2 the training sequence (TSC) must be the
same for all slots in a multi-slot set.

This commit updates find_possible_pdchs() to only consider slots with
the same TSC if more that 1 slot shall be assigned.

Note that the first PDCH's TSC will be used as reference, so if two
or more groups with a common TSC are configured, only the first will
be used. This restriction does not apply to algorithm A, since it
will not assign more than one slot and therefore sets the max_slots
parameter to 1.

Sponsored-by: On-Waves ehf
2015-07-03 15:37:16 +02:00
Jacob Erlbeck 617c7127f4 ms: Get the set of slots currently active
This commits adds methods to GprsMs and gprs_rlcmac_tbf to retrieve
the slots that are actively used.

Sponsored-by: On-Waves ehf
2015-07-03 15:37:16 +02:00
Jacob Erlbeck 23f93a15ca ms: Add support for slot reservation
In contrast to the slots currently used by existing TBFs, the
reserved slots refer to the time slots that can be used for newly
allocated TBFs without causing conflicts (given that the first common
TS does not change). They correspond to the potential use of the
PDCHs and can be used to achieve a more uniform slot allocation.

This commit adds bit set based methods to GprsMs and gprs_rlcmac_trx
and a counter to gprs_rlcmac_pdch. The current TRX will also be
stored in the MS object.

Sponsored-by: On-Waves ehf
2015-07-03 15:37:16 +02:00
Jacob Erlbeck ec478756cc alloc: Load balancing for algo A
Currently only the first enabled PDCH will be used. Beside the
throughput this will also limit the number of TBFs:

  - number of UL TBFs <= 7
  - number of DL TBFs <= 32

This commit changes the allocation algorithm to use the PDCH with the
least number of attached TBFs. This will improve the troughput in
both directions and the UL limits:

  - number of UL TBFs <= min(32, N_PDCH * 7) UL TBFs

Ticket: #1794
Sponsored-by: On-Waves ehf
2015-07-03 15:37:15 +02:00
Jacob Erlbeck 9380f5d218 tbf: Add GprsMs* argument to update() and use it in reuse_tbf
Since set_ms() is caled on the new DL TBF, the old DL TBF loses the
reference to the MS object. This will lead to a segfault, when
update() is called in reuse_tbf().

This commit adds an optional GprsMs* parameter to update() and uses it
for the slot allocation.

This fixes a TbfTest crash that would otherwise occur after applying
the next commit.

Sponsored-by: On-Waves ehf
2015-07-03 15:30:26 +02:00
Jacob Erlbeck ac89a555fa ms: Add tbf() method to get the TBF based on the direction
To avoid the need for a switch or conditional statement when needing
a TBF from an MS object in direction independant code, this method
contains that case distinction. For additional flexibility, a
reverse() function is added to get the opposite direction.

Sponsored-by: On-Waves ehf
2015-07-03 13:17:22 +02:00
Jacob Erlbeck 699b8dca49 ms: Add first_common_ts method to GprsMs
This method gets the index (0 based) of first common time slot used
by the TBFs attach to it. It expects that all of them have the same
notion of this. If no TBF is attached, -1 will be returned.

Sponsored-by: On-Waves ehf
2015-07-03 13:17:22 +02:00
Jacob Erlbeck ccc34e4d30 tbf: Maintain the number of TBF per PDCH
Currently the PDCH object do not know anything about the TBFs using
them. To make the slot allocation load dependant, at least some
numbers are required.

This commit adds TBF counters (one per direction) and the related methods
attach_tbf, detach_tbf, and num_tbfs to gprs_rlcmac_pdch.

Sponsored-by: On-Waves ehf
2015-07-03 13:17:22 +02:00
Jacob Erlbeck cb1b494c89 tbf: Add BTS::ms_alloc method
Currently the code that creates the MS objects with tbf.cpp is
duplicated.

This commit moves the corresponding code into a new method. Since
there is no TLLI available there, the GprsMsStorage::create_ms method
has been refactored into two variants: one with TLLI/direction and
one without.

Sponsored-by: On-Waves ehf
2015-06-29 11:43:17 +02:00
Jacob Erlbeck 6d86628e5b tbf: Always create an MS object on TBF allocation
Currently the MS object are created when the TLLI gets known.
Therefore some information (TA, MS class) must be stored in the TBF
itself and is copied to the MS object later on. This would get even
more complex, if the allocation algorithms were extended based on
this scheme.

This commit ensures, that an MS object will always be created on TBF
allocation, even if the TLLI is not yet known. These 'anonymous'
objects are still managed by the MS storage. To avoid dangling
entries without a TLLI there (which cannnot be retrieved anyway), the
timer in the MS objects is not started after all TBF have been
detached, so that they get deleted immediately in that case.

Note that an MS object can still be removed (e.g. by replacement)
from an existing TBF, so tbf->ms() can be NULL.

Ticket: #1794
Sponsored-by: On-Waves ehf
2015-06-29 10:53:32 +02:00
Jacob Erlbeck e2e004e7a9 tbf: Pass the MS object around instead of old_tbf
Currently the old TBF (either uplink or downlink) is passed around at
TBF allocation mainly to get information about the MS. To implement
more complex allocation algorithms, the MS object itself will be
needed anyway.

This commit replaces the old_tbf arguments by MS object arguments.

Sponsored-by: On-Waves ehf
2015-06-29 10:53:32 +02:00
Jacob Erlbeck ace7b570a0 tbf: Remove update_tlli method
This method does not do anything anymore, it's functionality has been
taken over by update_ms.

This commit removes gprs_rlcmac_tbf::update_tlli completely.

Sponsored-by: On-Waves ehf
2015-06-29 10:53:32 +02:00
Jacob Erlbeck f1379346f7 vty: Fix documentation for 'no cs downgrade-threshold'
The NO_STR is missing, this commit adds it.

Fixes: Jenkins #603
Sponsored-by: On-Waves ehf
2015-06-29 10:49:30 +02:00
Jacob Erlbeck e500e2e5d1 llc: Add missing include directive for struct timeval
While including time.h is sufficient with Ubuntu's current libc6
2.19, the correct (and portable) include file is sys/time.h.

This commit modifies the include directive in llc.h accordingly.

Fixes: Jenkins #600

Addresses:
    In file included from gprs_ms.h:28,
        from gprs_ms.cpp:22:
        llc.h:68: error: field 'recv_time' has incomplete type
        llc.h:69: error: field 'expire_time' has incomplete type

Sponsored-by: On-Waves ehf
2015-06-29 09:46:17 +02:00
Jacob Erlbeck b671dbfe94 llc: Move storage of timestamps into gprs_llc_queue
Currently the receive and expiry timestamps are prepended to the LLC
msgb before it is passed to gprs_llc_queue::enqueue(). Since this meta
information should not be counted as LLC octets, the gprs_llc_queue
needs to known about this (unless the correction was done in the LLC
layer).

This commit moves the meta information storage code into
gprs_llc_queue.  The meta data is now stored in the control block
(cb) area of the msgb.

Note that the info pointer that is returned from the dequeue method
is only valid if that method returns a (non-NULL) msgb. It must not
be used after that msgb has been modified or freed.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck 1e50a3dade llc: Make timeval arguments const
Some struct timeval pointer arguments do not have the const qualifier,
albeit the methods do not write to the structures. The next commit
will change related pointers to const, so this commit provides the
required constness.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck 70b96aa232 ms: Reduce DL CS level if only a few LLC bytes are left
If just a few bytes are left to send to the MS, it makes sense to
reduce the coding scheme level to increase the throughput. This
has been shown by Chen and Goodman in their paper "Theoretical
Analysis of GPRS Throughput and Delay". See their throughput over C/I
measurement graphs (figures 4 and 5 in the paper) for details.

This commit implements a simplified CS downgrade feature for the
downlink. The coding scheme will be downgraded if there are only a
few octets are left to be send over the TBF (see the
downgrade-threshold command below) and the NACK rate is not low (the
CS will not get degraded on a high quality RF link). As an exception,
CS-3 will be degraded to CS-1, since CS-2 does not improve the
throughput in general when a few small packets are sent and the
signal fades slowly (see Chen/Goodman).

The following VTY command is added to the config-pcu node:

- cs downgrade-threshold <1-10000>
- cs no downgrade-threshold

to set the threshold of the number of remaining bytes to be RLC/MAC
encoded. The CS will only be reduced, if the number is below the
threshold. The 'no' command disables this feature completely. The
default value is 200 octets.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck 07eb655244 llc: Keep track of the number of stored LLC octets
To get the number of LLC octets that are stored in the queue, this
commit adds a m_queue_octets member along with a octets() method.
This value is updated similarly to m_queue_size on each modifying
method call.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck 1eae96ca2f llc: Add missing include directive to llc.h
Currently struct llist_head is used without declaration which
accidently did not produce an error so far.

This commit adds the missing include directive.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck 409efa1ec8 tbf: Fix downlink packet loss
When the MS is pinged with a longer interval, many packets get lost
even if the GprsMs object is kept. If the interval is above the time
where the DL TBF is in state FLOW (mainly influenced be the
dl-tbf-idle-time command), an new TBF must be requested via AGCH for
each ICMP PING message.

Currently the LLC frame containing the PING is immediately stored
in the TBF and gets lost, if TBF establishment fails for some reason.

This commit moves all calls to put_frame() to schedule_next_frame(),
where the data is moved from the LLC queue to the frame storage
within the TBF object. This method is only called from within
create_new_bsn() when the TBF is in the FLOW state and the frame is
going to be encoded immediately.

At all other places, where put_frame() has been called before, the
LLC message is just appended to the LLC queue in the GprsMs object.
This change effectively simplifies the related code parts, since
date/len information and discard notifications is no longer needed
there.

Ticket: #1759
Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck 04a108617a ms: Store the NACK rate in the MS object
Currently the NACK/unconfirmed ratio is already passed to the
corresponding MS object, but the value is not being stored there.

This commit adds a member and a getter method and include the values
into the output of the 'show ms' command.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck e1d2b3568a tbf: Include CS into create_new_bsn log message
This change lets the test suite fail, so it get its own commit.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck da1a79ef5b l1: Add debug log messages for I_LEVEL
The I_LEVEL values that are obtained now look suspicious. They do not
seem to be contained in messages recorded via gsmtab.

To help debugging this issue, this commit adds related debug messages
that are generated while the encoded values are taken from the
RLC/MAC messages.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck 51b1151044 l1: Store measurement values sent by the MS
This commit extends the pcu_l1_meas structure by MS side measurement
values which are transmitted by PACKET DOWNLINK ACK/NACK and
PACKET RESOURCE REQUEST messages. The encoded values are remapped to
dB respectively % values. The values are stored in the corresponding
MS object (if there is one).

Note that the values are store as (rounded) integers, so some
different encodings are mapped to the same decoded value.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck 94cde130ca ms: Add UL CS selection based on L1 link quality
Currently the UL CS values are set to the corresponding DL CS value,
eventually limited by a maximum value. This approach does not reflect
the general situation of the RF link between ME and BTS, which is
rather asymmetric e.g. due to a lower degree of TX efficiency of the
built-in antenna. This means, that UL and DL CS control should be
decoupled for better results.

This commit adds automatic UL CS selection based on the link quality
measurement parameter. Each coding scheme is mapped to a link quality
range. If the link quality value leaves that range, the current UL CS
value is increased/decreased accordingly. This value will be copied
when the next PACKET_UPLINK_ACK_NACK or PACKET_UPLINK_ASSIGMENT is
sent to the MS.

The following VTY command will be added to the config-pcu node:

-  cs link-quality-ranges cs1 <0-35> cs2 <0-35> <0-35>
          cs3 <0-35> <0-35> cs4 <0-35>

which sets the ranges for the four coding schemes. For instance the
example below reflects the current default values:

  cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12

set the following ranges, where the overlapping is used to configure
a hysteresis:

  CS1: -inf ..  6
  CS2:    5 ..  8
  CS3:    7 .. 13
  CS4:   12 .. inf

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck e4bcb62dbf ms: Store the L1 measurement values in the MS objects
This commits adds the GprsMs::update_l1_meas() and GprsMs::l1_meas()
methods to store and access the measurement values. The internal
state is updated depending on which values are actually set.

In addition, these values are shown in the output of the 'show ms
imsi|tlli' command.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck 20f6fd1b63 l1: Pass all L1 measurements upwards
Currently only the RSSI value is passed to the upper layers. Other
values like TA and BER which are needed for TA update respectively CS
selection are not propagated.

This commit introduces and passes a struct that contains a set of
measurement values.

Sponsored-by: On-Waves ehf
2015-06-22 10:39:06 +02:00
Jacob Erlbeck b4584ff6c4 build: Add -lrt to AM_LDFLAGS
This is needed to link programs using clock_gettime and related
functions when compiling with older glibc versions.

This should fix the Jenkins build. Nevertheless fixing this in
configure.ac were probably nicer.

Sponsored-by: On-Waves ehf
2015-06-22 10:36:50 +02:00
Jacob Erlbeck 0808f68601 ms: Fix timer start condition (Coverity)
Currently the timer can be started even if m_ul_tbf is attached.

Replace m_dl_tbf by m_ul_tbf to only start the timer if _both_ TBF
are detached.

Fixes: Coverity CID 1304683
Sponsored-by: On-Waves ehf
2015-06-11 13:13:55 +02:00
Jacob Erlbeck 25db7c6116 ms: Add missing initialiser for m_delay (Coverity)
Set m_delay to 0 in the constructor to disable the timer feature by
default.

Fixes: Coverity CID 1304682
Sponsored-by: On-Waves ehf
2015-06-11 13:13:55 +02:00
Jacob Erlbeck 7bf9f49728 tbf: Check for NULL in name() (Coverity)
The gprs_rlcmac_tbf::name() method is generally used to generate log
messages. To avoid the need for an explicit NULL check for the tbf
and to get a consistent text if it is NULL, this commit adds a
NULL check to the method itself so that it can be called with this ==
NULL.

Fixes: Coverity CID 1304680, 1304681
Sponsored-by: On-Waves ehf
2015-06-11 13:13:55 +02:00
Jacob Erlbeck 0ae4313800 bssgp: Calculate the avg_delay_ms in 32bit only (Coverity)
Currently the delay_sum is stored in 64 to avoid overflow errors.
But only the result of tv_sec * 1000 is casted to 64 bit, resulting
in an overflow if the accumulated queue delay reached 25 days (which
will not happen in practice, unless there are >200k LLC messages with
a max of 10s delay each in the queue). If that were the case, the
only impact would be a wrong number in a log message and in the BSSGP
FLOW CONTROL message.

This commit changes the calculations so that they are done in 32 bit
only, rather than to do the calculation in 64 bit properly.

Fixes: Coverity CID 1298705
Sponsored-by: On-Waves ehf
2015-06-11 13:13:55 +02:00
Jacob Erlbeck d0aee85b29 llc: Fix LLC UI frame detection (Coverity)
Currently the wrong nibble is masked out, so the conditional
expression always yields true.

Therefore gprs_llc::is_user_data_frame() always returns true. As a
consequence, the low watermark feature of
gprs_rlcmac_dl_tbf::llc_dequeue() is not being used in fact.

This commit fixes the mask value.

Fixes: Coverity CID 1292834, 1292835
Sponsored-by: On-Waves ehf
2015-06-11 13:13:55 +02:00
Jacob Erlbeck 09fdf6622a bssgp: Handle btcx == NULL in gprs_bssgp_pcu_rx_sign (Coverity)
Currently it is assumed, that btcx is non-NULL. The btcx is only used
to obtain the BVCI in some log messages.

This commit changes that by using -1 as shown BVCI value.

Fixes: Coverity CID 1040961
Sponsored-by: On-Waves ehf
2015-06-11 13:13:55 +02:00
Jacob Erlbeck 37e896dff1 vty: Add command to show detailed MS info
This commit extends the "show ms" command to display an extended set
of information for a single MS.

The following VTY commands are added:

- show ms tlli TLLI
- show ms imsi IMSI

Sponsored-by: On-Waves ehf
2015-06-08 09:41:24 +02:00
Jacob Erlbeck b33e675e5a ms: Add support for maximum CS values
Currently the CS values can be increased to CS4 even when the "cs"
configuration command has been used with a lower value. The "cs"
command just sets the initial coding scheme, so other means are
needed to limit the selection. One approach is to use the CS flags
passed in SI, but these are currently ignored.

To make it possible to limit the CS selection by configuring the PCU,
this commit adds the following VTY commands to config-pcu:

- cs max <1-4>             Limit DL and UL CS to the given value
- cs max <1-4> <1-4>       Limit DL and UL CS separately (DL first)
- no cs max                Don't limit

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-06-08 09:41:07 +02:00
Jacob Erlbeck 8158ea7288 ms: Add blocking period for CS upgrade
Currently the CS level is immediately increased if the error rate
drops below the lower threshold. Since the measurement values are not
damped, this behaviour leads to a quick return to higher CS values
even under bad radio conditions. Since with GPRS RLC/MAC blocks
cannot be resent with another coding scheme, increasing the CS value
should be done carefully.

This commit adds a blocking period that only allows higher CS values
if all error rate measurements were below the LOW threshold for a
certain amount of time (currently fixed to 1s).

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-06-08 09:40:48 +02:00
Jacob Erlbeck 144a1d0516 tbf: Ignore lost+recv == 1
Currently the CS level gets changed quickly if single RLC/MAC blocks
are sent (e.g. LLC dummy commands), since the rate is either 0% or
100%.

This commit ignores measurements which are based on a single block
only.

Sponsored-by: On-Waves ehf
2015-06-08 09:40:41 +02:00
Jacob Erlbeck 8322d08071 tbf: Add adaptive coding scheme configuration
This commit adds the following VTY commands to config-pcu:

- cs threshold <0-100> <0-100>    Enables adaptive CS selection
- no cs threshold                 Disables it

The "cs threshold LOW HIGH" command sets the water marks
(cs_adj_lower_limit and cs_adj_upper_limit) used to
decide about switching coding schemes.

Ticket: #1739
Sponsored-by: On-Waves ehf
2015-06-08 09:40:35 +02:00
Jacob Erlbeck a17fccbcf4 tbf: Add debugging output to analyse_errors()
To help with the debugging, optimisation, and understanding of this
method, this commit adds an info string containing a flag character per
RLC/MAC data block in the current window.

Note that the blocks are shown in reversed order (highest BSN first)
in comparison to other logging output.

Sponsored-by: On-Waves ehf
2015-06-08 09:40:28 +02:00
Jacob Erlbeck 1751c62c98 tbf: Add adaptive DL CS adjustment
To cope with transmission failures due to bad radio conditions, a
different coding scheme with more redundance can be used.

This commit adds an implemenation that is based on the Ack/Nack
ratio per PACKET DOWNLINK ACK/NACK message received from the MS.

Basically the CS level is decreased, if the block error rate goes
above cs_adj_upper_limit (default 33%), and it is increased, if the
rate drops below cs_adj_lower_limit (default 10%). Only blocks that
have been encoded with the current CS are taken into account.

Note that this approach doesn't measure the MS->BTS conditions and
that the measurement values reported by the MS are not taken into
account.

Ticket: #1739
Sponsored-by: On-Waves ehf
2015-06-08 09:40:09 +02:00
Jacob Erlbeck f47f68a9d8 vty: Add 'show ms all' command
This command lists the entries of the ms_store by a line per MS.
Beside TLLI and IMSI, some measurement and state information is
shown.

A ms_list() getter method is added to GprsMsStorage to obtain a list
of the MsGprs objects.

The following VTY command is added to the 'enable' node:

 - show ms all

Sponsored-by: On-Waves ehf
2015-06-08 09:39:51 +02:00
Jacob Erlbeck 62e96a3535 vty: Add a file for C++ functions
Currently the pcu_vty.c doesn't compile with C++. Thus C++ object
cannot be access directly there.

This commit adds a helper C++ file that exports all functions with C
calling conventions and naming to work around that limitation until
the transition of pcu_vty.c is completed.

Sponsored-by: On-Waves ehf
2015-06-08 09:39:43 +02:00
Jacob Erlbeck a700dd9e11 tbf: Move the current CS field to GprsMs
Currently the current CS value is stored in the cs field of
gprs_rlcmac_tbf and initialised when it is used the first time.

This commit adds separate fields for UL and DL CS values to the
GprsMs class and provides corresponding getter methods for GprsMs and
gprs_rlcmac_tbf.

Ticket: #1739
Sponsored-by: On-Waves ehf
2015-06-08 09:39:25 +02:00
Jacob Erlbeck 17214bb06d ms: Add back pointer to BTS
Since more functionality will be moved to the GprsMs class, a pointer
to the current BTS object is added to allow access to configuration
data and other methods.

Sponsored-by: On-Waves ehf
2015-06-08 09:39:07 +02:00
Jacob Erlbeck befc760f86 tbf: Store MS class in GprsMs objects
The ms_class value is a property of the MS and thus belongs to the
GprsMs class. Nevertheless the MS object is created after the TLLI
gets known, so the value still has to be stored in the TBF initially.

This commit add the ms_class value to the GprsMs class and introduces
TBF accessor functions which either access that object or, if that is
not available, the value stored locally.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-06-08 09:38:49 +02:00
Jacob Erlbeck 489a2b35d8 tbf: Move the LLC queue to GprsMs
Currently the enqueued DL LLC messages which have not yet passed to
RLC/MAC encoding are eventually copied from one TBF to the next one
(see gprs_rlcmac_dl_tbf::reuse_tbf). Since the enqueued LLC messages
are related to a specific MS, they should be stored at that layer.

This commit moves the gprs_llc_queue object to GprsMs and changes the
TBF's accessor methods accordingly. The LLC copying code is removed
from gprs_rlcmac_dl_tbf::reuse_tbf().

Sponsored-by: On-Waves ehf
2015-06-08 09:38:44 +02:00
Jacob Erlbeck 10ed79553a tbf: Make the ms() getter method const
Currently this method cannot be used in other const methods.

This commit adds the missing const keyword.

Sponsored-by: On-Waves ehf
2015-06-08 09:35:47 +02:00
Jacob Erlbeck 1d0a52a349 llc: Add missing declarations to llc.h
Currently llc.h relies on the structs BTS, timeval, and msgb being
declared before the file is included.

This commit adds forward declaration for these structs, because they
will only be used for pointer types.

Sponsored-by: On-Waves ehf
2015-06-08 09:35:29 +02:00
Jacob Erlbeck 6dbe822062 llc: Separate LLC queue handling from gprs_llc
Currently the gprs_llc class handles both LLC queueing and the
partition into smaller pieces for RLC/MAC encapsulation. This hinders
the separation of TBF and MS related data, since LLC queueing belongs
to the MS related code while the RLC/MAC encoding/decoding belongs to
the TBF layer.

This commits takes the LLC queueing related methods and members and
puts them into a new class gprs_llc_queue. It puts the queueing
object into gprs_rlcmac_tbf and adds accessor functions. The
implementation in tbf.cpp and tbf_dl.cpp is adapted accordingly.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-06-08 09:35:11 +02:00
Jacob Erlbeck b3f713bd7b l1: Fix warning by logging acc_delay
The acc_delay value is computed but not used, resulting in a warning.

This commit adds a logging message it case the function is executed
to make the warning disappear. It also adds a CPP warning to remind
of the incomplete implementation.

Addresses:
  sysmo_l1_if.c:226:10: error: variable ‘acc_delay’ set but not used
[-Werror=unused-but-set-variable]

Sponsored-by: On-Waves ehf
2015-06-08 09:34:45 +02:00
Jacob Erlbeck 3c91cb881d pcu: Set ms_idle_sec to 60s
Since the timing advance storage has been removed, the TA values are
lost, when the last TBF of a single MS is freed. The TA storage has
at least saved the last 30 TA values. So now in more cases a wrong TA
value can be transmitted to an MS. Note that this also could have
happened before the removal of the storage, especially if more than
30 MS were in use.

This commit changes the default value of ms_idle_sec to 60s which is
higher than default value for T3314 (44s, see TS 24.008, 11.2.2),
after which the SGSN will have to start paging anyway. In that case,
a RACH request will be triggered, that will trigger an update of the
TA value in the PCU.

Sponsored-by: On-Waves ehf
2015-06-05 13:49:06 +02:00
Jacob Erlbeck a098c19b55 tbf: Set MS timeout
This commit sets the MS timeout when the MS object is created. The
value is taken from the ms_idle_sec field in gprs_rlcmac_bts which
can be changed by the VTY commands shown below.

The following VTY commands are added to the config-pcu node:

- ms-idle-time <1-7200>      Set the timeout in seconds
- no ms-idle-time            Disable the timeout

Another timer that is related is T3314 (Ready Timer, default 44s, GSM
24.008, 11.2.2) which requires the SGSN to use paging after its
expiry. Longer timeouts can help if adaptive coding scheme selection
is used (not yet implemented). On the other hand, measurement values
(TA, signal quality) can get invalid after some time, especially with
a moving MS. So a value slightly above T3314 is probably a good value
to start with.

Sponsored-by: On-Waves ehf
2015-05-28 17:40:15 +02:00
Jacob Erlbeck d9e102472a ms: Add timer
Currently the MS object is immediately idle when all TBFs are
detached and if no guard is being used. Since the plan is to use the
MS objects to pass information from one TBF to the next one even
across the gap of some seconds of inactivity, a mechanism is needed
to keep the MS objects around for some time.

This commit extends the GprsMs class by a timer that keeps the MS
objects in non-idle state for some time after all TBFs have been
detached. The set_timeout method must be used with a non-zero value
to activate this feature.

Sponsored-by: On-Waves ehf
2015-05-28 16:38:16 +02:00
Jacob Erlbeck 1db67e0a35 tbf: Remove TimingAdvance storage
Currently the TA storage stores up to 30 TLLI->TA mappings, if more
entries are created the oldest one is dropped. In theory this can
lead to missing TA information if many MS are present.

This commit removes the TimingAdvance class completely, since the TA
value is now stored in the GprsMs objects.

Note that the GprsMs objects are currently not kept after the TBFs
have detached from them, so the TA values are now kept for a shorter
time than before.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-05-28 13:59:25 +02:00
Jacob Erlbeck 9200ce6019 tbf: Store the timing advance (TA) value in the GprsMs object
The TA value rather relates to an MS and not to a single TBF. So all
TBFs share the same TA value. Currently the TA value is stored per
TBF and eventually copied from an old TBF to a new one. It is in
general only passed with an RACH request when the TLLI and thus the
MS is not yet known.

This commit adds a TA member to the GprsMs class and uses that one
when the TBF is associated to an MS object. Since the TBF is not
always associated with an MS object (after RACH or when it has been
replaced by another TBF), the TA value is still stored in each TBF
and that value is used as long as no MS object is being associated.

Sponsored-by: On-Waves ehf
2015-05-28 13:58:23 +02:00
Jacob Erlbeck ddfc0d5763 tbf/test: Add tests for single and two phase access
These tests cover the message exchange from receiving from the first
RACH request to the first data block when establishing an uplink TBF.

This will be used to check, whether TA and other values are passed to
an MS object correctly.

In addition, the RX RACH log message in rcv_rach is extended to
contain the single block fn.

Sponsored-by: On-Waves ehf
2015-05-28 12:29:43 +02:00
Jacob Erlbeck d3eac2867a tbf: Remove TBF chaining (m_new_tbf and m_old_tbf)
Currently a new TBF is chained to an existing older one, either of
the other direction (active or releasing) or of the same direction
(releasing). This does not work properly work if and uplink and a
downlink TBF are being established at the same time while an old TBF
is being released. In that case, one of them is thrown away and the
pending procedure is cancelled.

The chaining is no longer necessary since the GprsMs objects have
been introduced which keep track of the active TBFs.

This commit removes the TBF members m_new_tbf and m_old_tbf and the
related methods and code paths.

Note that a new TBF can replace an older TBF entry of the same
direction within an MS object when it is associated with an MS (e.g.
by TLLI or because it is assigned via another, already associated
TBF). In that case, the old TBF is no longer associated with an MS
object.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-05-28 12:29:43 +02:00
Jacob Erlbeck 71e55118f5 tbf: Remove IMSI handling from trigger_dl_ass
Currently the BTS::trigger_dl_ass() method assigns the IMSI to the MS
object. This should be (and is already) done earlier where the MS
object is retrieved/created.

This commit removes the corresponding code along with the 'imsi'
parameter from trigger_dl_ass.

Sponsored-by: On-Waves ehf
2015-05-28 12:29:42 +02:00
Jacob Erlbeck 7b9f825ae8 ms: Use the IMSI to retrieve the MS object
This commit extends get_ms() to really compare the IMSI if it has
been given. Matching by TLLI has a higher precedence than matching by
IMSI.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-05-28 12:29:40 +02:00
Jacob Erlbeck b0e5eaf59a tbf: Move IMSI to MS object
Currently the IMSI is stored in the TBFs. Since it directly refers to
an MS, it should rather be stored in an MS object.

This patch move the m_imsi field from gprs_rlcmac_tbf to GprsMs,
changes gprs_rlcmac_tbf::imsi() to get the IMSI from the associated
MS object, and adds getter and setter to GprsMs. Before changing the
IMSI of the associated MS object, assign_imsi() checks if there is
already another MS object with the same IMSI and eventually resets
the IMSI of that one. So using update_ms() and assign_imsi() ensures
that there are not two MS object entries is the storage with the
same TLLI or the same IMSI.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-05-28 12:28:40 +02:00
Jacob Erlbeck 0e50ce6145 tbf: Always call set_tlli/confirm_tlli in update_ms
Currently the m_tlli member in GprsMs is set by the constructor,
circumventing the TLLI confirmation mechanism.

This commit replaces the get_or_create_ms() method by a create_ms()
method which takes the TLLI and the direction (UL or DL) as
parameters to select either set_tlli() or confirm_tlli(). The MS
object is instantiated with TLLI = 0, and therefore GprsMs::tlli() is
extended to return the DL TLLI if both of the other TLLI are not set.

Note that create_ms() will not check whether an MS object with a
matching TLLI is already stored in the list, so it should only be
called after a corresponding get_ms() in general.

Sponsored-by: On-Waves ehf
2015-05-27 13:30:01 +02:00
Jacob Erlbeck 767193e20b tbf: Remove the TLLI from the TBFs
Currently the TLLI is stored in each TBF. Since each MS is now
represented by a GprsMs object which takes care of TLLI updating,
and each TBF that has been associated with an TLLI also contains a
reference to a GprsMs object, per TBF TLLI handling is no longer
needed. Keeping all TBF m_tlli members up to date is complex and
doesn't currently work correctly in all circumstances.

This commit removes m_tlli and related members from the TBF class and
the tbf_by_tlli functions from the BTS class.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-05-27 13:29:59 +02:00
Holger Hans Peter Freyther d1cb41bfd0 write_queue: Check the result of osmo_wqueue_enqueue and free
The write_queue is designed to have a maximum amount of pending
messages and will refuse to take new messages when it has been
reached. The caller can decide if it wants to flush the queue
and add the message again, create a log. But in all cases the
ownership of the msgb has not been transferred. Fix the potential
memory leak in the failure situation.
2015-05-22 10:37:57 +02:00
Jacob Erlbeck 4f459799e3 tbf: Just pass the MS object in reuse_tbf
Currently the MS will be searched based on the TLLI in resue_tbf().
Since the MS object is already known in the TBF when the TLLI is set,
it can just be passed to the new TBF.

This commit removes the call to update_ms() and just adds
new_tbf->set_ms(ms()) which will also work as expected if ms() == NULL.

Sponsored-by: On-Waves ehf
2015-05-21 17:11:40 +02:00
Jacob Erlbeck be0cbc1b7e tbf: Explicitly pass the direction to update_ms()
The type of the TBF update_ms() is being called on does not always
reflect whether the TLLI has been signaled by the MS or the SGSN.

This commit adds an additional parameter to tell the method, in which
direction the TLLI has been passed.

Sponsored-by: On-Waves ehf
2015-05-21 17:11:14 +02:00
Jacob Erlbeck 87597358cf tbf: Get the TLLI from the MS object
Since the synchronisation of the TBF's concerning the TLLIs has been
removed in 'Support new and old TLLI's', gprs_rlcmac_tbf::tlli() can
return the old TLLI which is probably different to ms()->tlli() in
that case. This can lead to a wrong TLLI being used in BSSGP messages.

This commit modifies the TBF's tlli() method to get the current TLLI
from the MS object.

Sponsored-by: On-Waves ehf
2015-05-21 17:10:49 +02:00
Jacob Erlbeck 9399046729 ms: Support new and old TLLIs
According to the specification (GSM 04.08/24.008, 4.7.1.5) after a
new P-TMSI has been assigned, the old P-TMSI must be kept basically
until it has been used by both sides. Since the TLLI will be derived
from the P-TMSI, the old TLLI must also be kept until the new TLLI
has been used by both MS and SGSN.

This commit modifies the TLLI handling of GprsMs accordingly.
set_tlli() is only used with TLLIs derived from MS messages,
confirm_tlli() is used with TLLIs derived from messages received from
the SGSN. tlli() returns the value set by the MS. check_tlli()
matches each of the TLLI used by either MS or SGSN as well as the old
TLLI until it has been confirmed.

Sponsored-by: On-Waves ehf
2015-05-21 17:10:42 +02:00
Jacob Erlbeck e43460b50f ms: Integrate the MS storage
Use the MS storage to find a MS object for a given TLLI instead of
searching the TBF lists. The TBFs are then taken from the MS object,
if one has been found. If all TBF might be temporarily detached from
the MS object, a GprsMs::Guard is added to prevent the deletion of
the object, in case another TBF gets attached later on in the scope.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-05-20 11:36:12 +02:00
Jacob Erlbeck 5367086175 ms: Add MS storage class
Currently the MS objects are contained in the TBF objects only. To
allow for an extended life time after the TBF objects have been freed
and to find them based on TLLI, a container for the MS objects is
needed.

This commit adds the container class and also adds the corresponding
m_list member to GprsMs. Further integration into the PCU code is not
yet done.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-05-20 11:36:12 +02:00
Jacob Erlbeck dfef28de88 llist: Add a C++ wrapper for linux_list
This commit adds the LListHead class which is a wrapper around the
linuxlist. It adds an additional member to refer to the container,
since the container_of macro doesn't work properly with C++ classes.
All functions and macros from linuxlist.h are support except for the
entry macros (e.g. llist_entry, llist_for_each_entry, ...). To access
the container (entry), an entry() method is provided instead:

  llist_for_each(pos, &elems) {
      pos->entry()->do_something();
  }

Sponsored-by: On-Waves ehf
2015-05-20 11:36:06 +02:00
Jacob Erlbeck fecece0e59 tbf: Add MS object management to TBF code
This commit adds MS object creation and cleanup to the TBF related
code. MS objects are created when a TBF that has been "anonymous" so
far gets associated with a TLLI. When a TBF is replaced by another,
the old TBF is detached and the new one is attached to the MS. When
all TBFs have been detached, the MS object gets deleted.

The TBF related code should not call attach_tbf/detach_tbf directly
but use set_ms instead to make sure, that the references are updated
properly. GprsMs::detach_tbf also calls set_ms(NULL) on the detached
TBF object.

The MS object is not really used yet, the focus is still on object
creation, TBF association, and cleanup.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-05-20 11:31:07 +02:00
Jacob Erlbeck e04e0b0a20 ms: Add GprsMs class to hold per-MS information
Currently only TBF objects are used to handle the data flow between
the MS and the SGSN. MS specific data (e.g. pending LLC frames, TLLI)
is copied between successive TBFs. If all TBFs (uplink and downlink)
are idle for some time, all information about the MS is discarded in
the PCU. This makes the implementation of some features more
difficult, e.g. proper TLLI and timing advance handling,
connection based CS selection, and proper management of multiple TBF.

This commit adds the GprsMs class that is intended to hold
information directly related to the MS and to keep references to the
active TBFs.

The class is not yet integrated with the other PCU code. A GprsMs
object container and MS specific fields (TA, CS) will be added in
later commits.

Note that calling detach_tbf() can possibly delete the MS object
depending on the callback implementation.

Ticket: #1674
Sponsored-by: On-Waves ehf
2015-05-20 11:30:41 +02:00
Jacob Erlbeck 6eeb7c7e74 bssgp: Increment BSSGP flow control tag value
Currently the tag value in FLOW CONTROL BVC messages is always 1.

This commit changes the implementation to increment that value with
each of the FLOW CONTROL BVC messages that is sent to the SGSN.

Sponsored-by: On-Waves ehf
2015-05-06 15:26:08 +02:00
Jacob Erlbeck 6e4ccec6c4 bssgp: Compute and transmit queue delay
The specification 28.018,  allows to transmit the average LLC downlink
queueing delay in FLOW CONTROL BVC messages (BVC Measurement IE, see
GSM 28.018, 10.4.4 and 11.3.7).

This commit extends gprs_bssgp_pcu.cpp to compute the average delay
time between two subsequent FLOW CONTROL BVC messages. The average is
implemented as an arithmetic average without any weighting.

Ticket: OW#1432
Sponsored-by: On-Waves ehf
2015-05-06 15:22:57 +02:00
Jacob Erlbeck 0288cdb0a8 bssgp: Add VTY command to Limit the bucket size by time
Currently the bucket size is by default being computed based on the
leak rate and the expected life time of LLC frames. The latter is
either taken from 'queue lifetime' (if given) or a fixed value is
used. Using 'queue lifetime' has the drawback that it sets a 'hard'
limit, since frames will be dropped if they stay in the queue
for a longer time.

This commit adds a VTY command to specifically set the time used for
the computation of the bucket size advertised to the SGSN. It does
not affect the PCUs queue handling in any way. If the bucket time is
not set (or if the 'no' command has been used), the old behaviour
(see above) is applied.

The following VTY commands are added (config-pcu node):

- flow-control bucket-time <1-65534>  Sets the time in centisecs
- no flow-control bucket-time         Don't use this time

Ticket: OW#1432
Sponsored-by: On-Waves ehf
2015-05-06 15:22:33 +02:00
Jacob Erlbeck 3d62fc55d8 bssgp: Compute BVC bucket size and leak rate
Currently the PDCH assignment and coding scheme does not influence
the values transmitted by the FLOW-CONTROL-BVC messages.

This commit adds the computation of those values. If the leak rate is
not given explicitly, it is derived from the number of PDCH and the
allowed coding scheme. If the BVC bucket size is not given
explicitly, it is derived from the leak rate and the maximum buffer time.
The latter is taken from the 'queue lifetime' command (or 10s if this
has not been used). The MS default bucket size is set to 50% of the
BVC bucket size. The MS default rate computation assumes, that each MS
only supports up to 4 time slots for GPRS RX.

Sponsored-by: On-Waves ehf
2015-05-06 15:20:43 +02:00
Jacob Erlbeck 87d7341fbe bssgp: Make BVC bucket size / leak rate configurable
Currently the FLOW-CONTROL_BVC message contains fixed values: The tag
is 1, the BVC bucket size is 6MB, the BVC bucket leak rate is
820kbit/s, the MS bucket size is 50kB, and the MS leak rate is
50kbit/s.

This commit makes the BVC parameters configurable and adds the
following VTY commands:

- flow-control force-bvc-bucket-size <1-6553500>
- no flow-control force-bvc-bucket-size
- flow-control force-bvc-leak-rate <1-6553500>
- no flow-control force-bvc-leak-rate
- flow-control force-ms-bucket-size <1-6553500>
- no flow-control force-ms-bucket-size
- flow-control force-ms-leak-rate <1-6553500>
- no flow-control force-ms-leak-rate

The 'no' variants restore the default behaviour.

Sponsored-by: On-Waves ehf
2015-05-06 15:20:35 +02:00
Jacob Erlbeck 29d91e9271 tbf: Added calls to llc_dropped_frame
Currently this function which increments the corresponding counter is
just called in gprs_llc::clear(). It is not called on places where
LLC DISCARDED messages are sent.

This commit adds calls to llc_dropped_frame() at these places.

Sponsored-by: On-Waves ehf
2015-05-06 15:20:25 +02:00
Jacob Erlbeck 0d39dc92b5 l1if: Add missing function prototypes
A few prototypes are not part of any header files, leading to
corresponding compiler warnings.

This commit adds the missing prototypes to sysmo_l1_if.h.

Addresses:
  sysmo_l1_if.c:347:2: warning: implicit declaration of function
      ‘l1if_transport_open’
  sysmo_l1_if.c:364:3: warning: implicit declaration of function
      ‘l1if_transport_close’
  sysmo_l1_fwd.c:89:3: warning: implicit declaration of function
      ‘l1if_handle_sysprim’
  sysmo_l1_fwd.c:91:3: warning: implicit declaration of function
      ‘l1if_handle_l1prim’
  sysmo_l1_hw.c:109:3: warning: implicit declaration of function
      ‘l1if_handle_sysprim’
  sysmo_l1_hw.c:118:3: warning: implicit declaration of function
      ‘l1if_handle_l1prim’

Sponsored-by: On-Waves ehf
2015-05-04 10:02:01 +02:00
Jacob Erlbeck 1f33294b1c pcu: Fix non-critical warnings
These fixes do not affect the semantics of the code. They either help
gcc by providing default values that won't be used ("may be
uninitialised"), remove unused variables, or change signed to
unsigned variables to avoid comparison warnings.

Addresses:
  bts.cpp:494:32: warning: 'tbf' may be used uninitialized in this
      function
  emu/test_replay_gprs_attach.cpp:81:27: warning: comparison between
      signed and unsigned integer expressions
  emu/test_pdp_activation.cpp:95:23: warning: unused variable ‘budh’
  emu/test_pdp_activation.cpp:97:6: warning: variable ‘rc’ set but
      not used
  emu/pcu_emu.cpp:109:26: warning: unused variable ‘bts’
  alloc/AllocTest.cpp:74:27: warning: unused variable ‘tbf’
  osmocom/core/utils.h:13:50: warning: comparison between signed and
      unsigned integer expressions
  types/TypesTest.cpp:319:7: warning: unused variable ‘count’
  types/TypesTest.cpp:320:11: warning: unused variable ‘rbb’
  alloc/AllocTest.cpp:74:27: warning: unused variable ‘tbf’
  alloc/AllocTest.cpp:132:11: warning: unused variable ‘ts_no’
2015-05-04 10:01:25 +02:00
Jacob Erlbeck 2acfbebfd3 vty: Fix value range of commands accepting csecs
Currently an uint8_t csec variable is used to temporarily store
the number of centiseconds which can be set within the range
1 - 65535. This way values above 255 cannot be set properly. This
affects the VTY commands "queue lifetime", "queue hysteres", and
"queue idle-ack-delay".

This commit replaces the uint8_t by an uint16_t.

Sponsored-by: On-Waves ehf
2015-05-04 09:58:34 +02:00
Jacob Erlbeck c0c580c414 vty: Fix warnings about undeclared functions
This commit adds missing includes to pcu_vty.c and fixes the
llist_head type (missing struct keyword) used by tbf_print_vty_info.

Sponsored-by: On-Waves ehf
2015-05-04 09:58:34 +02:00
Jacob Erlbeck 56e8d71090 tbf: Remove double assigment to m_last_dl_drained_fn
Currently the value -1 is assigned twice to m_last_dl_drained_fn
within append_data().

This commit removes the first of these assigments.

Sponsored-by: On-Waves ehf
2015-04-30 15:23:16 +02:00
Jacob Erlbeck 00fc6b13f2 pcu: Call bssgp_set_log_ss(DBSSGP) in main()
Currently the BSSGP functions in libosmocore do not log correctly to
DBSSGP since the DBSSGP variable in common_vty.c is left
uninitialized.

This commit adds the call to bssgp_set_log_ss() to inform libosmocore
which sub system id it shall use for BSSGP.

Sponsored-by: On-Waves ehf
2015-04-09 19:26:39 +02:00
Jacob Erlbeck 90de3a7ffe tbf: Send BSSGP LLC discarded on TBI exhaustion
Currently the PCU silently discard LLC frames from the SGSN if a
DL TBF cannot be allocated.

This commit changes tbf_new_dl_assignment and reuse_tbf to send an
LLC discarded message to the SGSN in this case.

Ticket: #607
Sponsored-by: On-Waves ehf
2015-04-09 19:24:47 +02:00
Jacob Erlbeck cc12f02658 vty: Use libosmocore VTY standards
This commit applies to following changes to pcu_vty.c:

- Use vty_install_default() instead of install_default()
- Add a blank after the '#' of the prompt
- Rename the 'pcu' configuration node to 'config-pcu'

Sponsored-by: On-Waves ehf
2015-04-09 17:05:19 +02:00
Jacob Erlbeck d0261b72de tbf: Force ACK after the last DL LCC frame has been received
If the protocol layers above LLC (e.g. TCP) need an acknowledgement
to continue, it can take up to 400ms (single TS) until the MS is
polled for Ack/Nack which it can use to request an uplink TBF
quickly. The 400ms result from requesting an DL Ack/Nack every 20 RLC
blocks until all pending LLC frames have been sent.

Especially TCP's slow start mechanism can lead to a high delay at the
start of the connection, since the sender will eventually stop after
having sent the first packets (up to 4 (RFC2581) or 10 (RFC6928)).

This commit modifies append_data() to (re-)start
a timer every time it handles an LLC packet and to request an
Ack/Nack every time it expires. So if the server ceases to send IP
packets, the MS is polled in the assumption, that the server is
waiting for an ACK.

The following VTY commands are added (pcu node):

 - queue idle-ack-delay <1-65535>  timeout in centiseconds
 - no queue idle-ack-delay         disable this feature (default)

A sensible value is 10 (100ms) that at gave promising results when
testing locally.

Sponsored-by: On-Waves ehf
2015-04-02 18:14:08 +02:00
Jacob Erlbeck 0c1c8778df tbf: Use a hysteresis when discarding DL LLC frames
Currently single LLC blocks are discarded when the PDU lifetime
expires. If an IP packet has been fragmented either on the IP or on
the LLC layer and is therefore distributed over several LLC frames,
the kept fragments are transmitted and then discarded by the MS
because of the missing PDU. This can cause massive IP packet loss
when there are many fragmented packets (e.g. when trying 'ping
-s1800' or if the GGSN chops downlink IP packets into several SNDCP
packets).

On the other hand, discarding too many packets might disturb the
congestion handling of TCP. Dropping plain TCP ACKs might also hinder
flow control and congestion avoidance.

This commit adds a hysteresis algorithm to the LLC discard loop. If
an LLC message's age reaches the high water mark, further message's
with an age above the low water mark are discarded, too. This is
aborted, if a GMM, a non-UI, or a small message is detected. In
these cases, that message is kept.

The following VTY commands are added (pcu config node):

- queue hysteresis <1-65535>   set the difference between high
                               (lifetime) and low watermark in
                               centiseconds
- no queue hysteresis          disable this feature (default)

Since the SGSN will most probably send all fragments of a single
N-PDU without much delay between them, a value slightly above the
average transmission delay jitter between SGSN and PCU is probably a
sensible value to discard all fragments of a single IP packet.

This is an experimental feature that might be replaced by more
advanced means of active queue management in the future.

Sponsored-by: On-Waves ehf
2015-04-02 12:34:48 +02:00
Jacob Erlbeck 0a0b5dcb32 pcu: Add pcu_utils.h to Makefile.am
Addresses:
src/gprs_rlcmac_sched.cpp:26:23: error: pcu_utils.h: No such file or directory

Sponsored-by: On-Waves ehf
2015-03-29 13:55:42 +02:00
Jacob Erlbeck 502bd1feea tbf: Poll MS on idle DL TBFs
If an MS wants to open a new UL TBF, it can either use (P)RACH or
request one in a Ack/Nack message for a DL TBF (PACCH). When a TBF
becomes idle (LCC queue is empty but the TBF is kept open), there
aren't any Ack/Nack requests that can be used by the MS to ask for an
UL TBF, therefore it has to use the RACH. This leads to many RACH
requests even for a single HTTP transaction, so it takes some time to
retrieve even a simple web page.

This commit modifies the scheduler to regularly send Ack/Nack
requests on idle DL TBFs. It does so by extending the priority based
scheduling algorithm to have 5 priority levels (highest priority
first):

  - Control block is pending
  - High age (100%) threshold reached (-> request Ack/Nack)
  - Data is waiting or there are pending Nacks
  - Low age (200ms) threshold reached (-> request Ack/Nack)
  - Pending Nacks that have been resent already
  - None of the above (-> send DL dummy control block)

The 'age' refers to the time since since the last control block has
been sent on the TBF. This high age threshold is set to
dl-tbf-idle-time or to 50% of T3190 (whichever is smaller), aiming
for at least a poll (and TBF shutdown) after the TBF has expired and
to safely prevent expiry of T3190. So if dl-tbf-idle-time > 200ms,
there will be a poll every 200ms and a final poll after
dl-tbf-idle-time. On high load, the interval between polls can get
higher, but the 'high age' poll should be in place.

This commit implements the scheduling with respect to GSM 44.060,
9.3.1a ("Delayed release of downlink TBF").

Ticket: #556
Sponsored-by: On-Waves ehf
2015-03-25 12:34:38 +01:00
Jacob Erlbeck e25b5b91f6 tbf: Only create dummy frames if necessary
Currently a lot of LLC dummy commands will be generated while waiting
for an ACK for the DL TBF, even if there are blocks that could be
resent instead.

This patch modifies create_dl_acked_block to only call
create_new_bsn() if there is unsent LLC data or m_window is empty.
If the TBF is in state FLOW, no unsent LLC data is left, but there
are blocks left in m_window, those are resent instead.

Sponsored-by: On-Waves ehf
2015-03-25 12:34:38 +01:00