Only the gprs_rlcmac_pdch will manipulate the paging list now. There
can be various more refactorings of the code but they can be done
later. E.g. on memory allocation failure we can continue instead
of leaving the code, we should also set any_tbf only after things
have been paged.
Rely on packet_paging_request returning NULL in case the queue
is empty. We should move the write_packet_paging_request into
a separate file/object as well.
When a PDCH is disabled all resources should be freed. This is
currently not possible as the PDCH does not know where it belongs
to. On top of that the list (and other resources) should be
properly initialized on construction so that disable() is idempotent
and does not check if it was disabled. During the re-factoring I
noticed that during a sysmobts re-start some resources are not
freed. I left a warning in the code to resolve this issue later.
The current_frame is an attribute of the BTS. Move it from the
pcu_l1_if.cpp into the BTS. As the next step we can trigger
actions depending on the change of the frame.
Compared to the previous code there will be a branch to get the
global pointer so the code will be slightly slower than the previous
version but it allows us to start creating objects but still use
the code from C. It is best approach I have found so far.
One downside of C++ is that by default talloc will not be used
(unless we override the new operator to use talloc. Right now
we need to memset the C data structure by hand. The benefit of
enforcing a better structure should is more important though.
Remove the global state from gprs_rlcmac_trigger_downlink_assignment
and walk up to the pcu_l1_if.cpp where I find the timeout handling
that should be part of the SBA and TBF functionality. In terms of
hierachies things start to be more clear.
There should be the BTS object. That holds the SBA and TBF Controllers
that can allocate TBFs and SBAs and will handle the timeout polling
for a BTS.
Global state makes mocking/writing tests more difficult. Continue
by removing direct usage of the bts and adding it as pointer to
the function calls (showing the true dependencies of the functions)
There was no difference but there is no point in poking in the
internals of the tbf, pdch and trx from various places. Information
hiding has a real purpose, e.g. compare with reading "the mythical
man month".
Vladimir Rolbin pointed out that in case of the alloc_algorithm_a
the usf has not been assigned. For now move all the assignment into
a method and call it from the A and B algorithm.
There really shouldn't be too many callers of state. Instead the
tbf should dispatch depending on the internal state. For now
introduce state_is and state_is_not accessor functions so we can
start to see who is using the internal state.
This is the begin of a long march of turning tbf into a C++ class
and properly hiding the secrets inside this implementation instead
of having it spread across various different files.
The TBF should use the IMSI to identify a block flow but all
handling is spread across the entire code. Start to clean this
up by moving relevant code into the tbf file. Afterwards one
can clean up and add more internal structure.
Do not claim that the payload is not known. Add the missing break.
Do not print:
<0002> gprs_rlcmac.cpp:1174 GPRS_RLCMAC_CONTROL_BLOCK_OPT block payload is not supported.
<0002> gprs_rlcmac.cpp:1176 Unknown RLCMAC block payload.
For mocking/unit-testing/emulation (and a dual trx-systems) having
global state is quite bad. Cut back on the usage of the global
struct gprs_rlcmac_bts. It also makes the complexity of certain
routines more clear.
Fixes:
bitvector.cpp: In function 'int bitvec_pack(bitvec*, uint8_t*)':
bitvector.cpp:53:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
bitvector.cpp: In function 'int bitvec_unpack(bitvec*, uint8_t*)':
bitvector.cpp:63:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
bitvector.cpp: In function 'uint64_t bitvec_read_field(bitvec*, unsigned int&, unsigned int)':
bitvector.cpp:91:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
bitvector.cpp: In function 'int bitvec_write_field(bitvec*, unsigned int&, uint64_t, unsigned int)':
bitvector.cpp:108:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
femtobts.c:250:2: warning: excess elements in array initializer [enabled by default]
{ SuperFemto_ClkSrcId_NetList, "nwl" },
^
femtobts.c:250:2: warning: (near initialization for ‘femtobts_clksrc_names’) [enabled by default]
femtobts.c:251:2: warning: excess elements in array initializer [enabled by default]
{ 0, NULL }
^
femtobts.c:251:2: warning: (near initialization for ‘femtobts_clksrc_names’) [enabled by default]
This might clash with C++11 and literal values but we will
see that once the compilers enable that by default.
Fixes:
csn1.cpp: In function 'gint16 csnStreamDecoder(csnStream_t*, const CSN_DESCR*, bitvec*, unsigned int&, void*)':
csn1.cpp:864:17: warning: format '%d' expects argument of type 'int', but argument 8 has type 'guint64 {aka long unsigned int}' [-Wformat]
csn1.cpp:1144:15: warning: format '%u' expects argument of type 'unsigned int', but argument 7 has type 'uint64_t {aka long long unsigned int}' [-Wformat]
csn1.cpp:1150:15: warning: format '%u' expects argument of type 'unsigned int', but argument 7 has type 'uint64_t {aka long long unsigned int}' [-Wformat]
csn1.cpp: In function 'gint16 csnStreamEncoder(csnStream_t*, const CSN_DESCR*, bitvec*, unsigned int&, void*)':
csn1.cpp:2119:17: warning: format '%d' expects argument of type 'int', but argument 8 has type 'guint64 {aka long unsigned int}' [-Wformat]
Decrease the number of lines of a single method by splitting things up.
The fewer lines of code, branches and side-effects in a method, the easier
it will be to understand. The other benefit is that one can start creating
unit tests for the some parts of the code.
One of the issues with not properly re-setting everything is that
due the global state it is not clear which variables belong together
and how long it exists. Begin with creating a osmo_pcu and moving
things into this class.
Think of an organic cell, this commit is introducing the cell wall
around it... and defines what is inside and what is outside of it.
The PCU does not properly re-set the state when the connection to the
BTS is lost (and the SGSN potentially is re-started during that). This
results in the BSSGP BVCI > 1 remaining blocked and no data will be
accepted by the SGSN.
Add the '-e' option and exit the PCU when the BSSGP/NS are getting
destroyed.
osmo_timer_del is an idempotent operation. There is no requirement
to check if it is running. If you don't want a timer to run, delete
it. Maybe one should have called the method _unschedule, _cancel to
make this more clear.
The timing advance of any TBF is stored when it ends. Whenever a new TBF
with the same TLLI is created (downlink TBF), the stored TA is recalled.
This algorithm assumes that the mobile does not move too fast during
transfer. Also the mobile must start a connection in order to get correct
initial timing advance.
This algorithm does not implement the timing advance procedure as defined
in TS 04.60. To implement the standard timing advance procedure, the BTS
must decode RACH on certain bursts, the mobile is expected to send them.
This requires much more complexity to a transceiver like USRP/UmTRX or
Calypso BTS.
The algorithm was tested at TA >= 8 and works quite well.
I ported the Holger's scheduling patch from sysmobts to osmo-pcu.
This is usefull, if PCU uses direct access to the DSP of sysmobts.
The latency to respond to a PH-READY_TO_SEND.ind may not be higher
than 18ms. Currently we are using nice to increase our priority but
for a heavily loaded cell this is not enough. Add an option to enable
realtime scheduling and use it in the screenrc.
Linux offers two realtime scheduling classes these are SCHED_FIFO
and SCHED_RR. For SCHED_FIFO the process is running as long as possible
(potentially taking all the CPU and never yielding it), for SCHED_RR
the process can still be pre-empted at the end of the timeslice.
Using SCHED_RR appears to be the more safe option as a run-a-way
sysmobts process will not be able to take all the CPU time.
The measurements include:
- DL bandwidth usage
- DL packet loss rate
- DL measurements by mobile
- UL measurements by BTS
In order to receive DL measurements from mobile, it must be enabled via
system information message at BSC.
Since we don't know the RX and TX parameters of the BTS that might be used
with PCU, the MS should not adapt the TX power from the RX level. So the
MS should always transmits with same power.
Finding an 'alpha' and 'gamma' value that will result in a constant
RX level at the BTS is a task of deployment.
If not compiled with this support, the closing function does not exists,
so it must not be called.
Removed a "#warning", because closing is already supported.
This simpliefies the allocation process.
tfi_alloc is responsible to allocate a TFI, not a time slot.
The first time slot available depends on multislot class and on other
ongoing TBF (concurrent TBFs), so it is part of the allocation
algorithm to select it.
In order to use this feature, sysmoBTS requires option "-M", otherwise
the traffic is forwarded through socket interface.
This is essential, if PCU runs on processor of sysmoBTS. The reaction
time and delay of PDTCH frames could heavily degrade proper packet flow.
The slots are choosen in a way that later selection of slots for
concurrent TBFs will have the same downlink/uplink control channel
(PACCH).
This is required for polling acknowledge of new TBF assignment on PACCH.
The MS will always have the same PACCH uplink slot while beeing in packet
transfer mode.
Original code: c7e7f6868b
(The code was committed earlier, but got lost somehow.)
I added IMSI, so the paging request is sent in correct paging group.
Also I excluded rest octets from pseudo length.
It is tested and it work.
Some MS will leave packet transfer mode, if TAI is given, but no timing
advance control messages are sent on PTCCH. This could results in
permanent loss of larger packets.
It is essential to initialize the first_fin_ack variable.
Also it is essential not to free TBF, in case the final ack is not
received, but all frames have been acked. In this special case, we resend
the final block again and again (and poll), until we receive the final
ack.
It is quite essential. It shows how TBFs are related and helps to estimate
states and timers (timeouts) of the MS.
In order to use it, it must be defined by a switch at gprs_rlcmac.h.
Generic improvements to the csn.1 dissector include:
• Added a flag to the type descriptor structure so that any type can (potentially) flagged as xxx_OR_NULL. This was specifically needed for UINT_OR_NULL for the ms capabilities struct.
• Changed the CSN_SERIALIZE so that the length of the length field can be specified.
• For CSN_NEXT_EXIST removed the requirement that the next type be CSN_END, to allow truncation of multiple IEs.
• For CSN_LEFT_ALIGNED_VAR_BITMAP corrected the handling of bit_offset.
• Added a new type CSN_PADDING_BITS to make inspection of padding bits more convenient.
• Improved the CSN_RECURSIVE_TARRAY_1 to show the array index.
Improvements to the gsm_rlcmac dissector include:
• Rework the definition of EGPRS Ack/Nack Description so that the length IE (and absence thereof) is handled correctly.
• Added Padding Bits definitions to all PDUs
• Change the Multislot_capability_t and Content_t definitions to allow truncation at any IE
In this case the mobile has lost existing flows, so it make sense to free
them. The TFI(s) can be re-used immidiately, because they are not
associated by MS anymore.
Be sure to use always two bytes of length information for DL-UNITDATA,
even if the length of LLC data is less than 128 bytes. This way the data
has always the same offset from a 32 bit boundary.
This is required, since we may change slot allocation. In case of a
change, we do not want to be unable to change, if the same TFI on one of
the other slots is already in use by a different TBF (having same TFI, but
on different slot).
It is mandatory to support it because MS may request a single block.
In this case the network must assign a single block.
It is possible to force single block allocation for all uplink requests
on RACH. (VTY option)
Both flags can be used to determine wether assignment must be sent on PCH
or on AGCH. Before contention resolution is done, mobile will ignore
downlink assinment. When final uplink acknowledge was sent, the mobile
will go back to PCH after reception of akcnowledge.
This is required because uplink assignment (PACCH) is done on a request
by mobile, so the mobile expects that it get this assignment in return.
After that we may assign downlink.
If the mobile misses assignment, it changes back to idle mode. In this
case we must kill the pending downlink TBF, because it is not used by
mobile and we can assign a new downlink TBF for new downlink data.
(We may not have two downlink TBF with same TLLI!)
If lifetime expires of queued LLC frames, they are discarded. The number
of discarded frames and the sum of their octets are reported to SGSN
via LLC-DISCARDED message.
The lifetime can be overridden via VTY. The value can be centi-seconds
or "infinite".
In order to do downlink assignment during uplink TBF, the content
resolution must be completed. It is completed when the first Packet
Uplink Ack/Nack message is transmitted to the mobile.
It turned out that the final ack flag may not be set, but all packets
have been acknowledged. This patch will finish transfer in case all
blocks are acknowledged.
The slot must be the control channel TS, which is selected by the
allocation algorithm. The MS must be able to respond at this TS.
The counter to trigger polling is incremented until polling has to be
performed. Then the counter stops. When the transmission of data block is
requested on control channel TS, the counter is reset. The counter-value
is also used to poll immediately when the transmission has finished.
In order to send control blocks to MS and receive control blocks from MS
(polling), it is required to select one timeslot that the MS must be
able to send and receive. The allocation algorithm must take care of
selecting that slot.
The new data structure is required to define slot/TFI assigment for MS
with multislot capability.
Now there are two lists for TBFs: uplink and downlink. It is possible to
have different TBFs with same TFI in the same direction, as long as they
are assigned on different timeslots.
See tbf.txt for description.
Note: This does not implement any multislot support. It defines the new
data structure. Currently only the first slot is assigned.
The signal handler will end the main loop, so clean exit is performed.
The allocated memory is dumped in order to detect memory leaks.
All talloc functions use tall_pcu_ctx context instead of NULL, to track
memory leaks.
Merge is based on jolly_new branch with two modifications.
1. Modified PCU L1 interface.
pcu_l1_if.cpp - common functions for tx and rx messages on L1 interface.
sysmo_sock.cpp - SYSMO-PCU socket functions.
openbts_sock.cpp - OpenBTS-PCU socket functions.
pcuif_proto.h - L1 interface's primitives.
2. Modified encoding of RLC/MAC Control messages, now we use structures and encode_gsm_rlcmac_downlink() function for encode control blocks (without hand-coding).
Only when using LOGL_DEBUG, every detailled information is displayed.
When using LOGL_INFO, a summary of the process is displayed.
When using LOGL_NOTICE, only errors and warnings like timeouts
or invalid received informations are displayed.
When using LOGL_ERROR, only local error like software errorss are
displayed.
The pseudo length may not include the rest-octets, so it stays compatible
to non-GPRS phones.
At pcu_l1_if.c (OpenBTS) no pseudo length is given, so the frame is
only 22 bytes long. I could not test if it works.
The hack for resetting BSSGP instance is removed and now performed
whenever the NS state changes to UNBLOCKED.
The BSSGP instance is now created only once, as it should be.
Received STATUS messages are ignored as they should be.
The creation and destruction of BSSGP/NS instances is now handled by
layer 1 interface alone.
The option added is required to change PLMN that is announced to SGSN.
This allows BTS to have a different PLMN.
(Usefull for roaming in conjunction with simlock.)
These informations provide RAI, timers, counters and other attributes to
the BSSGP and RLC/MAC processes.
The attributes are stored in gprs_rlcmac_bts global structure.
Added functions:
- gprs_bssgp_pcu_rx_paging_ps() for handling paging message from BSSGP;
- write_paging_request() for writing paging request message;
- gprs_rlcmac_paging_request() and pcu_l1if_tx_pch() for sending paging request message to BTS.
It uses history buffer and sends ack/nack control messages about received
blocks. It defragments the blocks and forwards them to upper layer. It
does content resolution and ignores other MS. It sends final ACK after
all blocks have been sucessfully received. Timers are used to detect
loss of uplink, and repeat lost final ACK.
The scheduler is triggered at ready-to-send-requesst. It schedules
control blocks, data block and dummy blocks, depending on priority.
It provides upstream ressource by setting USF. The ressources are
assigned, if required. The ressources are dispatched round-robin.
In case of polling, the upstream ressource is given to MS at the
time it will respond to polling request.
The OpenBTS socket functions are moved from main to pcu_l1_if.cpp.
New sysmo_l1_if.cpp is introduced. It used special unix socket interface
to connect to sysmo-BTS. This is required to access CCCH/RACH and info
about cell layout. Traffic is also forwarded via this interface, but
it direct access of L1 baseband DSP will be added soon.
In order to handle ready-to-send requests above l1_if, the transmit
queue (for downlink blocks) is moved to gprs_rlcmac.cpp.
The TBF instance additionally holds TRX and TS info, but this is only
a hack currently. TBF instance requires more details about allocated
ressources in the future.
Added functions for TBF allocation, establishment, data transfer and release management.
Modified TBF structure, added list for several LLC PDUs in one TBF.
Added function gprs_rlcmac_tx_llc_pdus() providing transmission of several LLC PDUs in one TBF to MS.
this is probably a historic relict. None of them should be used, and I
cannot see any actual use of them either.
The only non-library code that we link now is libosmo-gb (ns/bssgp),
which soon will be turned into a real library.