Introduce a VTY setting that right now needs to be set to
one. To make updating this setting possible we will now store
the number of endpoints in the bsc connection as well.
On a classic BSC we have 32 channels but one is reserved for
signalling. Make sure that we are not assigning 0x1f as we
assume that this is the signalling channel. This means that
from 32 possible voice channels we are only going to use 30
as we are already not using the 0x0.
Allocate the status for an endpoint dynamically. We will support
BSCs with different amount of multiplexes and need to have this
flexibility in the future. Add the proper null checks to the
current users of this code.
Rename the method as we send everything to the MSC and not just
SCCP. Put alink into the function name. Also use msg->data and
msg->len in hexdump as this is what we are sending to the server.
Recent libosmocore introdues a way how log targets can be configured from
the VTY.
This commit makes the 'log filter (imsi|nsvc|bvc)' compatible with it.
This introducecs the new VTY command "neighbor-list mode manual-si5"
in combination with "si5 neighbor-list (add|del) arfcn <0-1024>",
which allows you to (optionally) have neighbor channel lists that
differ in SI5 and in SI2.
So far, all BTS we have interfaced had one OML link per BTS, independent of the
number of TRX. In Ericsson RBS 2000, there is an OML link for the DXU/IXU,
and one additional OML link for each TRX/TRU.
The previous patch introduces new code for the RBS2000 but didn't
actually activate/call it yet.
After this patch, you can see LAPD being established and OM2000 messages
will fall into abis_nm.c (which of course has no clue about them).
bsc_init.c was a big mess even only for two supported BTS models,
so before adding more BTS types, this needs a cleanup.
All the BTS specific code from bsc_init.c has now moved into
bts_{siemens_bs11,ipaccess_nanobts}.c
This has required that input_event() and nm_state_event() get both
converted to proper libosmocore signals instead of referencing external
symbols.
When we copy a msgb, we need to make sure the msgb_cb->bssgp_cell_id
pointer points to data in the new message, not in the old message.
Thanks to Dieter Spaar for spotting this.
As we only have one NS-VC between gb_proxy and SGSN, we cannot
forward a NS-BLOCK from the BSS to the SGSN, as it would affect
all other BSS's, too.
Thus, we check if we have an unblocked PTP-BVC in the NSVC to the BSS,
and then issue a BVC-BLOCK towards the SGSN.
This should prevent any further PDU's from the SGSN to be sent to
this BSS.
We cannot afford static/global state, as we may have multiple E1
lines, each having its own LAPD instance. Furthermore, we might
even have multiple LAPD instances on the same E1 line (think of
a multi-drop setup).
This also implements dynamic TEI allocation, i.e. no hardcoded
TEI list anymore.
This introduces a new 'e1_input' config node with a command to be
used like:
e1_line 0 driver misdn
This allows us to have different input drivers in the future
When the remote subscriber has not responded yet we could
end up with a crash in the MNCC code. It was enough to dial
the number, then hang up and bsc_hack would end up with a
segfault due the list poisining of linux_list.
The paging response should always have a TMSI or IMSI
and we should be able to find the subscriber using that. If
no IMSI/TMSI is present and we would still accept the LU
we would access the uninitialized memory.
The compiler concludes that if (ts->type == type && ts->line && line
can be false as line is NULL and then we unconditionally access
it, make it happy by adding an extra NULL check.
now it correctly names some of the IEs like DSP/FPGA version,
and also automatically marks the UDP streams as RTP depending on
what it has seen in the RSL CONNECT TRAU message.
This parameter indicates how many of the PCH+AGCH blocks are reserved
for the AGCH and thus not used for the PCH. If we set it to 0,
we basically tell the BTS there is no AGCH - and thus it would be
impossible to send any IMMEDIATE ASSIGNMENTs.
Luckily the BS-11 and the nanoBTS don't seem to care.
So far, OpenBSC simply assumed that all BTS's configured in openbsc.cfg are
neighbors of each other. While this is true for small site installations,
it is definitely not true in most real world cases. We now have the
following new commands at the 'configure bts' level:
'neighbor-list mode (auto|manual)' for selecting the mode
'neighbor-list (add|del) arfcn <0-1024>'
for adding/deleting ARFCN in manual mode
Add a short README mentioning the svn version they apply
to, how to rebase them in the future, and what they do.
The renaming is done to add a hint on in which order to
apply them. The abis_oml patch has been updated to some
value_string changes in epan, all patches now add the new
files to the CMakeLists.txt of epan as well.
Instead of using more numbers from the proto range we will
use the 0xee and then have a mini header with our new proto
id in there. For a start rename the use types to _OLD.
The transaction layer was stopping paging requests that might or
might not have been owned by the transaction. This makes the subscr
code get stuck delivering requests. This code is mostly a band aid
and just makes sure that we will kick the queue if it is needed.
Remember if this channel got opened due a paging response and in
that case when we close it down we will call subscr_put_channel
that will try to page the subscriber again. This highlights the
lack of a good subscriber management in the MSC code.
If one paging request is timing out the others will timeout soon
as well. With the current code the next timeout would expire the
next request in the queue. We will now stop all paging requests
and then issue a next paging request. So for both paging success
and failure we will now stop all the other requests.
This is mostly a workaround, one should count on how many
BTSes we are paging and wait for all failures before we remove
the item from the queue.
Kick the queue in case the paging was timing out. No one is going
to call subscr_put_channel for us so we will do it on the subscriber.
There is also another problem with multiple BTS in the LAC and paging
timeout. We will need to remember how many BTSes we have paged.
If we have a RF failure between the paging response and the auth
success we will not inform the subscriber layer of the failed paging
and instead just 'drop' the SMS. In case we have not completed the
auth and close the channel we will now send an auth failure.
The conn might be released during the loop and then conn->bts
is a null pointer and we end up crashing. Store the gsm_network
in a local variable and access this one.
Improve the debugging possibilities and print the failed attempts
and the sms that was attempted to be delivered. this should help
with debugging the code.
The active channel might or might not be gone when the transaction
has been released. Instead of passing an invalid subscriber conn
we will pass the subscr that is ref-counted and guranteed to be
valid at this point. subscr_put_channel could search the connections
for an active connection if that is ever needed.
In contrast to the previous believe we may not have a conn here
as we are still paging for the sub. Instead of printing the BTS
print the lac where we think the subscriber is located.
Follow trans->conn->lchan to the BTS instead of using the BTS that
is guranteed to be NULL in the codepath we have entered here. The
trans->conn should still be there, and the lchan should be valid as
well as we have reordered the clear statements.
When the new_lchan for handover is failing we should stop the
handover operation. This is fixing a crash that we get a timeout
on the lchan and have no conn set to it. Introduce a flag to
the bsc_clear_handover to not free the lchan. In case the ho_lchan
is failing we do not want to call lchan_release as it would
reset the state.
The trau_mux likes to call cc_tx_to_mncc for each received
frame from the E1 link. Using a signal for each audio frame
is messy as well. The best thing I could think of is to put
this into the BSC to deref the pointer. The other option would
be to include the gsm_data.h in the mncc.h header and have
the method as inline.
Instead of creating the sockets in the RSL code we will do this
in the CRCX_ACK, MDCX_ACK, DLCX_IND signal handler of gsm_04_08.
Introduce a handover signal so we can repatch the RTP sockets in
the gsm_04_08 as well.
In case we get a RA UPD REQ on a new cell (both served by the same
SGSN), the LLC stack should not allocate a ne LLE/LLME, as the latter
would reset the V(u)sent / V(u)recv to zero and make the MS discard
our responses.
Instead, whenever the LLC stack sees a foreign TLLI, it should always
convert it to the local TLLI before doing any lookup for a LLE/LLME.
We create a loop by not setting trans->callref = 0 before calling
trans_free(), as the latter would again send a MNCC_REL_IND up
the stack.
Also: Fix memory leak in case we try to read from mncc_sock
but socket is just gone.
This adds mncc_sock_from_cc() as a handler function for CC messages
to be passed to the MNCC interface. If there is no MNCC socket
registered, we immediately release any CC related messages.
Together with flushing all established CC transaction at MNCC socket
close time, this ensures that all resources are released and no
new resources can be established until the MNCC applicaiton has
re-attached.
The MNCC messages now again get directly handled by the net->mncc_recv()
callback. If the callee wants to put them in a queue, it' his business
to do that.
Using this code we will soon be able to use LCR or other MNCC
applications via a unix domain socket.
The code is not actually used yet after this patch.
The reason for this is quite simple: We want to make sure anyone
running a customized version of OpenBSC to operate a network will
have to release all custom modifiations to the source code.
The SS_LCHAN signals now always include the lchan_sig_data. For
the measurement report it will optionally include the measurement
report as well. Attempt to update all handlers of this signal as well
Check the signal and only continue if it is any of the
signals we want to handle. In the case of measurement
reports we would cast some random code to a lchan.
The release might release the lchan we want to send the response
on. Reorder the code to first send the message and then give up
the security operation which might release the lchan.
According to the specs (GSM 04.08 Table 9.9), the only possibility
if neci=1 and this cause is used is "Originating call and TCH/F is
needed"
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
With the old code it was possible that we first saw SMS that
we have already in the queue. In that case we had free slots
available but have not filled them. With his new loop we try
harder to find SMS we can send, it attempts (and should work)
to detect a loop to break the loop before finding SMS to deliver.
Increase the number of SMS we will try to send at a time and
decrease the failures we handle before going to the next item. With
the default timeout we will attempt to page the subscriber for 60
seconds and we can increase the queue speed by going to the next
item faster.
The sms queue will attempt to send one SMS per subscriber
to fill all the available slots. It will handle the case
where paging has not started, timed out or if there was
any kind of other failure. It is also retransmitting SMS
in case of failures.
The SMSqueue will be responsible of sending to the user. It will
do so in a loop and will also try not to overload the BTS. This
means the throughput of SMS will be limited.
This is providing access to the paging result, the sms,
the transaction. This will allow the SMS queue to do
decisions based on the source of the failure.
The signal_data was inconsistent. Sometimes we passed the transaction
and sometimes we passed the sms. Change it to always pass the sms. The
S_SMS_SMMA is a bit special as it does not involve any SMS.
This is creating 1000 subscribers and 30 SMS each. The SMS
itself is badly formatted (not a valid 7bit encoding) but
it should be enough for a stress test.
If a signal handler accesses the database he will still see
the old lac. Make sure he is seeing the new one. Update the
subscriber from the database in case the query failed or other
things have changed.
Start counting the attempts of each paging request and call
the callback with the PAGING_BUSY type when the paging request
timed out but the subscriber was not paged at all. This can
only happen with a huge paging backlog.
In case the system has so many pending paging
Introduce a method that will remove all subscribers that have a
zero use count. This is useful if someone wants to purge subscribers
from memory or wants to disable the everything in RAM feature.
This is implemented by not freeing the subscriber when the
reference count becomes smaller than zero. We hope that this
will save many database accesses during the congres.
As we do not yet use the HLR from the SGSN, we allow all MS to
attach to our GPRS network. However, if this is running in a public
environment, it could cause service interruption to users of commercial
GPRS networks.
Thus, we now check if the first 5 digits of the IMSI match the MCC/MNC
of the cell that they want to register to. Thus, any subscribers with
SIM cards from real operators will no longer be accepted.
LOGL_ERROR will make this message shpw up in everey default log
config. However, as it seems, this is commonly observed in case
a MS still sends a MS STATUS (in respons to the MM INFO) at the
end of a location area update.
It might be best to actually change the channel release procedure
to make sure we can still pass such 'late' data to the MSC until
the time the Layer2 has been completely released.
If a MS changes RA, the RA will arrive in the new cell using the old
TLLI (masked as foreign TLLI). So we need to look-up the TLLI
in a special way, using the old RA as indicated in the 04.08 GMM
message.
There is still another bug remaining: As we somehow create a new LLC,
the sequence numbers of our responses start from 0 again, which is not
what the MS expects. This needs to be fixed in a follow-up patch.
In the GPRS NS protocol stack, the amount of NS/BSSGP headers like MS RADIO
CAPA INFO can be quite long. In order to fit the full user message and
those headers, we have to enlarge the head/tailroom of the msgb allocations.
On a nanoBTS, this command can be used to manually switch a given 'dynamic
pdch/tch' timeslot from one mode into the other.
There are no safeguards that the timeslot is not in use at the given time.
We send a LU Accept with the TMSI as the MI. According to the
spec the phone should store this new TMSI and send a TMSI
REALLOCATION COMPLETE to us. We will release the LU then and this
should trigger the release procedure.
This was introduced by a recent change to gsm_data.h to include
less header files. We really need to access the RSL information
here so it is fine to include the file.
In commit 39e2eadc99 a bug was introduced
that used the 'trans' after trans_free() had already been called.
This became visible now when the openbsc+lcr combination was calling
an unknown/invalid telephone number in a MO call, resulting in
a segfault.
Currently the nanoBTS bootstrap code requires a high delay
otherwise we are not bringing the device up properly. Changing
the init code turns out harder than it seems like. So this is
a workaround for that to allow a high speed RSL/OML connection
after the bringup.
The line driver can have a default TS delay. It is set to the
current default for the nanoBTS and the BS11. For the ipaccess
case we will set the delay lower for the RSL connection and
inside the ipaccess-config we can set it low right away to
have fast firmware flashing and such.
Instead of sending many messages we will queue the OML
messages and wait for the ACK/NACK before sending the
next message from the queue. We tag the msgb to remember
if we need to wait for an ack or not.
We keep the order of all messages, on ACKs and similiar
occassions we will drown the queue until we reach a message
that needs to be acked and then wait for that ack again.
Possible breakage can appear when we send an OML (e.g.
BS11 specific message) msg which does not need to be acked
through the abis_nm_sendmsg call. The fix will be to use
the _direct version of this method.
Re-Enable as it might have fixed something... who knows.
Conflicts:
openbsc/include/openbsc/abis_nm.h
openbsc/include/openbsc/gsm_data.h
openbsc/src/abis_nm.c
openbsc/src/gsm_data.c
Assume that a NACK is a onetime failure and that on the next
attempt it will work better. If that is not the case we might
even send a reboot to the BTS.
Sometimes the operative change for the NSE is getting nacked,
this might be due that we send it before we get the OPSTART ACK
for this object class. Send it from the CELL availability as
a workaround. This init code needs to be changed to make these
dependencies work more reliable.
Forget about the ho_lchan inside the gsm_subscriber_connection
in case of a handover failure, also clear the gsm_subscriber_connection
pointer before the lchan is passed to the lchan_free routine.
Do not use the NULL context for this allocation. It should hang
off the gsm_subscriber_connection but for now at least make it
the child of the BSC so it is showing up in the talloc report.
Can't declare it in gsm_04_08.h tough ... gsm_cbfn is defined in
gsm_data.h and trying to include that in gsm_04_08 just creates a
huge mess.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
The default values are those where the parameters are encoded
as '0' and they're not output in the config file if that case
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
When switching the RF off we will always go through the grace
period, add a direct off mode to switch it off directly. Make
the query return a 'g' if we are in the process of switching
things over.
Use the ipaccess_drop_oml and ipaccess_drop_rsl functions
instead of closing the socket and hoping this is picked up
somehow. This just leads to some weird hangs. And gdb was
not really helpful to say where it was coming from.
In the future we should avoid using a gsm_subscriber at all
and pass the imsi/tmsi to the paging function directly. For
now we can use the old model for paging and go through the
gsm_subscriber. This has the benefit of load balancing on
the BTS and such.
Sending this as the RTP_PAYLOAD2 will produce a MDCX NACK
as we send the RTP_PAYLOAD in the CRCX. It does not seem to
be necessary to send anything != 0 for the RTP_PAYLOAD2.
Refactor the closing code of the CC timeout to a new function,
also make sure that the SCCP Connection is forced closed before
we destruct the connection for real.
This will change the LAI of a LU accept message to the LAI
used for the on-air network. It will also detect when to
send a welcome ussd to the subscriber.
Set conn to NULL before starting the release procedure, remove
code to check for a lchan->conn as it can not happen. If there
are any memleaks we will notice them.
Detach the lchan->conn from the channel before detaching.
The timedout could come between lchan_release and the
S_CHALLOC_FREED signal. In the future we might want to
use the gsm0808_clear to stop the RLL timeouts and such.
For SAPI=3 on a TCH it might be nice to use the SACH to submit
the message. The api allows to automatically use the SACH if
a message like this is submitted.
The cipher mode reject will be send in case the BSC is not
able to support the requested cipher. So this reject can be
handled by however attempts to enable ciphering.
For certain messages we will need to call other GSM0808 functions. To
keep the bsc_hack working we will try to send this through the normal
messages first and then fallback to dtap if no handler is registered.
The gsm_04_08.c code is not forced to handle the IPA activation
and channel modify ack anymore. This is done transparently by the
BSC API now.
The implementation of bsc_hack would call subscr_con_free before
the BSC API has had the chance to call gsm0808_clear to try to
release other channels. Fix that by adding a return value.
This is used by the paging code of the osmo_bsc. When we get
a paging response there should be an active subscriber with
the TMSI or IMSI and we can stop paging. There is no need to
allocate a new subscriber.
In case of a inflexible network it is better to hardcode
the rtp payload to a given type. E.g. when using AMR5.9 on
a TCH/F and TCH/H having the same payload is helpful. For
now this will be only used by the osmo-bsc.
Use the offsetof/__builtin_offsetof to determine the
offset of a variable inside a structure instead of going
via a NULL pointer and taking the address.
This fixes:
warning: variably modified ‘dummyhalen_offset’ at file scope
Make sure that the MSC endpoint exists on the NAT, otherwise
we end up trying to free this endpoint when the SCCP connection
is taken down and will corrupt our memory. This issue started
to pop up as we have reduced the number of endpoints to 60
to allow transcoding on them.
Do not reset statically allocated local_port. The port
might be different to the calculation of endpoint number
and base port. This might be the case for the coming remote
transcoding.
Send a RLSD down to the BSC in case the USSD Provider is gone. It
is not sending a Clear Command and ut depends if the BS+ will
like this kind of behavior. At least the data on the NAT will
be freed soon afterwards due the RLC message.
We need to simulate OML/RSL failure in an easy and fast way
and adding a command to do so seems like a good way to achieve
this. The command is a bit misplaced, in one way it is no config
and does not belong into the config node but then again it does
not belong into the VIEW_NODE either as it is manipulating content.
On this merge I have changed it to the ENABLE_NODE.
Remove a lot of code in favor of a new function that is freeing
the old string and copying the new one. I should have gotten the
context and the strings right.
Extract the IMSI from the first message as well and safe it
in the connection structure. The problem is that we do not
have this structure at this point, so we will allocate the
imsi as child of the bsc_connection and then move/steal it.
Split the trace based on SCCP Connections, in case an error is
detected, the trace will be stored instead of being deleted and
the full log can be viewed afterwards.
Right now only LU Rejects are recognized, but this can be extended
to other things as well.
Currently it is not is not easily possible to disable
everyone and then only allow certain SIMs. By changing
the order we can do:
access-list imsi-deny only-something ^[0-9]*$
access-list imsi-allow only-something ^123[0-9]*$
and still keep the usecase of only forbidding certain
SIMs on certain LACs. Adjust test case, test that the
other cases are still functional.
Rename NAT_IPAC_PROTO_MGCP to IPAC_PROTO_MGCP and place it in
the enum. We need to be prepared to change this number if IPA
is ever going to use it for something else.
Remove a lot of code in favor of a new function that is freeing
the old string and copying the new one. I should have gotten the
context and the strings right.
OSX does not provide an endian.h, use the other header files that
should define/include what we need. Also check that the byteorder
define is available.
Make it possible that one BSC is serving multiple
cells. Introduce a list of lacs, add functions to
manipulate the lists. The current test cases for
paging by lac continue to work.
This makes sure that someone can call bsc_msc_lost multiple times
even if there is no MSC connection. This makes sense as bsc_msc_lost
is public and be called from client code.
The filter code will return < 0 for error, 0 for unknown
subscriber, 1 for subscriber checked. Use the same if construct
as for the CR message. This should fix passing LU when it
starts with a TMSI of a different network.
Thanks to the person on the ml that pointed this bug. Sorry I
don't remember who (it was a while ago and somehow didn't got
fixed at that time)
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
The transcoder RESET is using the same extensions to reset all
endpoints on a remote site. This makes sure that all allocations
can be made in a properly configured network.
Bind a new port for the transcoder, forward data from the BTS
to the transcoder, and from the transcoder to the network. Leave
BTS-IN where it is, BTS-OUT can now be after the transcoding took
place. We send the data from the BTS RTP port.
This whole route will be guarded by the transcoder_ip and if it is
NULL (current default) it will not go through the transcoder.
The timeslot one is blocked and should not be used, replace the
code with a warning and watch out for it. Tis is most likely due
the uncovered in the previous commit due the wrong TLV definition.
Do not free the GSM Subscriber Connection when a channel is failing
or if a clear is requested, instead just give up _all_ the channels,
reset them to NULL and free the remaining channels.
When we reject the IMSI we do not have the msc_con set on the
SCCP connection, but we do have a remote_ref. So the nat_send_rlsd
will end up with a crash due the msc_con being zero. Fix the
crash by only sending a released to the MSC when the connection
is not local.
Add the code that is forwarding data, from and to the MSC, also
handling ping/pong timers and authentication. Hook it into the
osmo_bsc. The code is only compile tested and ported from the
on-waves/bsc-master branch.
The grace code will decide if a given connection is allowed to
be made or if it is going to be rejected. For active connections
it is going to send a USSD message.
Keep a back pointer to the rf struct inside the connection,
resolve the network through the back pointer. Also assume
that the RF is on. In case we start with RF locked, the policy
is on but we will not see any MS talking to us.
This way we avoid seeing many warnings that we will not forward
data to the MSC. For the con_local connections that is actually
the idea, we will not forward them to the MSC.
Attempt to disconnect the connection and make both sides happy
about this. Right now it only handles the LU and should be extended
to the CM Service Request.
Return early in case the IMSI was already checked, if not we need
to look at the connection and check if the message could contain a
imsi we want/need to filter.
Return -1 if the IMSI should be filtered, 0 if the IMSI could not
be checked and 1 if the IMSI was checked and allowed to pass. In
the future this will be used to inspect every message coming by.
Add some code to count TCH/H and TCH/F and also handle
the neci bit of the network. Our channel allocator will
allocate a TCH/F if we request a TCH/H but can not allocate it.
Only page if we have a load that is acceptable for paging. This
option is off by default, and can be enabled per bts. The idea
is that when we have no resources right now we will not page as
it will only create more RACHs and increase the load.
By default we are keeping the old behavior to always page and
only by changing a setting one is using the new behavior.
Instead of throwing a huge pile of paging commands to the BTS
we will submit one paging command every half second. This way
we can have different messages between the paging commands.
This is done to avoid crashes of the nanoBTS when too much
paging messages are send.
It might be that we run down to zero available slots but the BTS
might not send us a load indication. This can happen if we think
we send paging requests and the BTS disagrees and considers them
as errors and does not count the paging message.
When we drop to zero we will start a credit timer to give us extra
credit after six seconds, if we get a CCCH load indication before
we will stop the timer.
It is possible that the MSC is not sending the channel type it
needs for the operations it wants to do. Add a configuration option
to assign a TCH in case of paging any requests. It can be a good
idea to leave SDCCHs free for location updating requests and use
the TCH for SMS-MT and CC-MT.
Store the mapping from request to channel type in the GSM Network
struct as there is some policy involved with handling the request.
E.g. in a half rate network we don't want emergy calls to be getting
a TCH/F, or we want to have a different policy for early/late assignment
of phone calls. Update the table when creating the network and when
the neci is changed.
Allow the MS to use uplink discontinous transmission by
setting the right bit in the SystemInformation and set
DTXd/DTXu on the RSL channel commands.
This is configurable via dtx-used (0|1) on the network
level and still considered as experimental.
When the cell becomes visible we will be bombed with location
updating requests and to reduce the load on the network we should
assign as many channels for it as possible. During load peek it
is even more important than to have a spare voice channel and in
general the LU procedure is pretty fast.
Assume that if the MSC has assigned a timeslot/multiplex it will
also be used for the MGCP. So we just assume that it was allocated
on the BSC as well... in the worse case we will send a DLCX downstream
but it should be fine.
We are going to have more than one trunk, so all code hardcoding the
multiplex to zero must go. Avoid this kind of problem by saving the
MGCP endpoint number and comparing that.
This uses the osmo_daemonize() function of libosmocore >= 0.1.18,
and is now implemented for bac_nat, osmo-bsc, bsc_hack, osmo-gbproxy
and bsc_mgcp. This means only osmo-sgsn is missing, which currently
has no option parsing at all.
When gprs_ns_sendmsg() succeeds in sending the message, we free()d the
msgb after transmitting it on the socket. However, if the NS-VC is
blocked or some other error condition exists, we returned an error
code but didn't free the msgb.
This resulted in an error leak which is now being addressed.
If the CRCX is failing, we will send a DLCX downstream and the next
time the callagent tries to do a CRCX we will be more lucky. This is
for the case where we have an endp allocated.
Do not use the CI_UNUSED to decide if an endpoint is allocated
but introduce a new flag. This way only the CRCX and free_endp
play with the allocated field.
If we have found the BTS and we receive data on the RTCP port
from the IP of the BTS we will set our RTCP port and forward it
to the network and hope it will be useful.
Remove wrong code that is luckily not called. We would end up
in a reconnect and attempt to bsc_fd_register the same socket
again. I am removing this part of the code as it is not used
and it would need to know if the fd has ever been registered
or not...
For debugging it is useful to forward (tee) UDP packets to another
system and use gstreamer to inspect the rtp stream. This is untested
code and might contain bugs.... and of course only tap your own calls.
Once we have discovered the bts we will not accept data from
anything else. The call will drop if the BTS is changing the
ip address of the nat anyway.
Allow to switch to a dynamic port allocator and not reuse
the ports for a long time... This should help with a crazy
network sending two streams at the same time.
This allows a more strict check on the source of RTP messages
and we can more easily reject those. For the BTS without an ip
address we will also update the ip address.
We plan to have two different ports for the network and for the
BTS to avoid detecting the BTS and to dynamically allocate the
port to have old data not go to a new socket.
common_vty.c was including bsc_nat.h which tried to
get the sccp/sccp_types.h which is not required to be
installed. Move all structs using/embedding SCCP structures
into the bsc_nat_sccp.h and include. This should fix
the compilation.
Currently every SAPI release indication will trigger the channel. It
was possible that we had SAPI=3 and SAPI=0 allocated and we tried to
release the channel by sending a RF Channel Release, the BTS answered
with a RF Channel Release ACK but also sent the SAPI Release Indication
which triggered a channel release here. So it was possible that we
would have released a newly allocated channel because of the SAPI
release of the old connection.
This code now works by releasing all SAPIs from highest to lowest,
then sending a SACH Deactivate and finally releasing the channel. This
approach is in use on the on-waves/bsc-master.
Add --enable-nat and --enable-osmo-bsc to build applications
requiring the Osmo SCCP library to be installed. We are not
using autodiscover as this is out of fashion.
This code compares the UDP sequence numbers of two RTP messages
and guesses if packets are missing. It is guessing in two ways:
1.) by default the sequence number is 0, so on the first
value we ignore the jump... we might ignore a real issue
in case of a wrap around which is easily possible as the
sequence should be a random number.
2.) the UDP stream might have been reordered on the network
and we would see the jump...
In any case these two shortcomings are acceptable for the feature
that is meant to provide some basic analysis..
We need to release the USSD unit, otherwise it is staying blocked
and will stop to function (even across LUs on my a1200). This code
should encode the transaction and the direction depending on the
network state but this is omitted right now.
... while asking the BTS to perform tests for us. The length of the
ARFCN whitelist is the actual length in bytes, not the number of 16bit
ARFCN numbers.
Also, implement a limit, either by rxlevel or by number of ARFCN
that should end up in the whitelist.
Also, we now re-start the network listen test after it has finished,
so if you run a test from ipaccess-find, the test will get re-started
and re-started all the time.
* We should create the transaction for SMS, CC on the CM Service Request
but for now we will use a band aid and create a dummy operarion to wait
five seconds for the transaction to be opened.
* Return msg'es to the right MSC Con. Right now it is nat->msc_con.
* When forwarding from BSC to MSC, use the msc_con inside the
sccp_connections. This means we will only forward data with a
connection to the BSC.
The FCS isn't computed yet (because of ciphering).
It _will_ be tested and reported as wrong later in the code
so we can just display it here and let the latter code report the
error if any.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This was causing weird crashes when running in 32 bit linux.
Thanks to horiz0n for taking the time to debug this with me on IRC.
Written-by: horiz0n <cscan@gmx.net>
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
The LLC layer tells us the PDU length, and we have to use it
in SNDCP rather than to re-calculate it if we want to avoid copying
the CRC24 into the defrag elements.
When we defragment the segments from the defrage queue, we have
to iterate all the way up to (and including) the last segment number
that we have received.
sgsn_rx_sndcp_ud_ind() can no longer make the assumption that msgb_bcid() is
valid, as this is only true for an un-fragmented SN-PDU. So instead,
we now store the RAID in the SNDCP Entity and pass it as an explicit
argument to sgsn_rx_sndcp_ud_ind().
Once The TLLI (or P-TMSI of which it is derived) change has been
confirmed by the MS, we need to unassign the old TLLI but keep
the new TLLI _without_ re-setting the LLC entity structure such
as VUsend /VUrecv counters.
The problem is that sms_from_text returns NULL in case the
subscriber is not attached which a) leaks memory of the
previously allocated sms and b) runs into a null ptr
dereference in _send_sms_str().
There may be a better solution than this but this is the
easiest way of noticing and taking action I could find
without changing return values of sms_from_text.
lchan_free only free's the local resource of the BSC but
does not release the channel at the BTS. Use lchan_release
to properly release the channel. This code assumes that the
timeout happens after a CHAN ACT ACK/NACK otherwise we have
some problems. The comment indicates that this is the case.
The transaction should not know on which lchan we are operating
as this can change due handover. Add untested code to share the
subscriber connection of the new and old lchan and move the pointer
in case of success/failure. Also on a clear command we will free
any resources allocated...
This code is not tested and needs to be debugged, but it should
have the right structure. I am going to fix a potential memleak
in the next commit.
1.) memset the gsm48_chan_desc to avoid sending dummy data
2.) According to the GSM08.58 9.3.5 the Mobile Allocation
shall be included but the empty (by setting the length
to zero).
3.) use msgb_tlv_put and calculate the length via the l3h
msgb_l3len and assign it.
On expired paging we might access a GSM Subscriber that has already
been deleted. To avoid this we will add a subscr_get/subscr_put for
the subscriber to the allocation and release path of the request.
Reported-by: Richard Zahoransky
there are now human-readable names so you can do something like
ipaccess-config -U dhcp-enabled -S static-ip -S static-gw 192.168.100.120
to unset DHCP and to set static IP and gateway attributes.
This looks so much better than the *cur++ type code.
Also, we now terminate ipaccess-config once the NV flags or Unit ID have
been set, not just for the OML IP address.
A channel will be released in case of
* Errors via the clear_request callback...
* no more transactions and operations are going on.
This means that if we do something without a transaction
the channel might be closed down right away. The bug fix
will be to create a transaction/operation.
This is a big change to the way we use the subscriber
connection. From now on it is is dynamically allocated
and we will slowly move from a 1:1 lchan to conn to
having more than one lchan per connection.
This is the first commit, the subscr_con* methods will
move to gsm_data once the use_count is removed from the
connection, the freeing of the connection will also change.
The Channel Activate might be sent to a different TRX than the
Immediate Assignment. So we need to make sure that the channel
is activated before we send the immediate assignment for the RACH.
Another reason for that is according to GSM 08.58 we should take
the frame number from the activate and use it for the starting
time inside the immediate assignment message. We obviously do not
do this yet.
The code assumes that the BTS will either respond with a CHAN ACK
or a CHAN NACK if not the lchan will remain in the request state.
gmtime(NULL) returns NULL at least in glibc and *can not* be used as
time(NULL). Since we compare two time_t values when checking the validity
period this can be replaced by time(NULL)
The value of the in_addr might not be 32 bit aligned and reading
it can generate an alignment error on ARM. Fix it by using memcpy
to copy the data into a local variable.
There are many more potential alignment issues that we will fix
when we hit them.
For Siemens BS-11, the 'length' value of the ARFCN_LIST IE is interpreted in
violation of the spec. The spec says it is a length in octets, while Siemens
treats it as 'count of 16bit ARFCN values'.
Also, make sure the bit ordering in the pre-computed MA is correct,
as well as the cell channel description of the target cell being
present in the HO CMD.
We now compute the Cell Channel Description for SI 1 by bit-wise
OR of the ARFCN bitmask of each timeslot on all the TRX of the BTS.
Also, support generating a GSM 04.08 Channel Description IE for
the hopping case (with HSN/MAIO instead of ARFCN).
What's still missing now: Sending the 04.08 Mobile Allocation IE
In some cases, we get a DL_INFORMATION_IND with a wrong channel
number, and only in the DL_ESTABLISH_IND we will see the real
channel number that is to be used for this (TEI, SAPI) tuple.
Now it properly parses message types and IEs that are defined different
depending on the BTS vendor / A-bis implementor. This fixes a lot of
decoding bugs with Siemens BS-11 traces.
Do not use the lchan for the paging but operate on the
subscriber_connection, change the signals too to not carry
the lchan but the subscriber connection... the silent call
and vty code still assume there is a lchan inside the
subscriber connection.
The lowlevel BSC paging API is a simple wrapper around
the RSL command. The BTS will automatically repeat these
messages but if we end up with two MSC inputs we will
need to count these messages somewhere...
With handover and late/early assignment there might be two channels
for one subscriber and only the BSC knows which one to use, so use
the gsm_subscriber_connection everywhere...
The GSM04.08 Section 10.5.2.19 specifies the L2 Pseudo Length
and the length does not include rest octets, so we will need
to use a zero for the length.
The patch is coming from Dieter Spaar.
Inside the access-list we have a list of entries that have
either one allow or one deny rule... we do not allow to remove
a single rule but one has to remove the whole list, in that case
talloc will handle cleaning all entries.
Right now the matching is O(n*m) as we traverse the list
(multiple times) and run the regexp multiple times. One
way to make it faster would be to concat all regexps into
one.
One can set one access-list to one BSC and one
access-list to one NAT. The matching of IMSIs
remains the same for now, also applying the
white/blacklist. Access lists can not be deleted
for now and no perf opt is done (e.g. one could
cache the result of the last lookup in the bsc
struct).
Allow to set the TOS field via the VTY interface. The
SO_PRIORITY was not used as it has no effect on the
packets being sent (in contrast to the documentation).
We will need to confirm the connection, then we can send the
GSM48 message, then we need to close the connection... the
embedding in the refusal method was way too easy..
Right now it was not possible to just find a connection, by returning
the connection that is created we will have direct access to it. It
will be used by the local connection handling.
A local connection is only between the MUX and the real BSC. We will
not forward anything to the MSC. This will be needed for the IMSI
filtering as sending a CREF is not liked by every BSC...
In case of a RLC message we will destroy the SCCP connection. This means
that accessing the con and con->bsc will access old memory. Keep the status
local and move the con into an inner scope.
Now we are parsing a CM Service Request, Location Updating Request
and the Paging Response. For all other messages we claim to not
support it and force a refuse.
The code should be shared among the GSM0408 implementation
and this one, and like the LU we are not handling a TMSI
properly as we have no idea where it is coming from.
For now we have:
1.) bsc imsi deny to deny at the BSC level
2.) bsc imsi allow to allow a SIM at the BSC level
3.) nat imsi deny to deny at the global level
We have tried to send a refuse for arbitary things and ended
up with a segfault... separate the exi2 and exit3 label to have
separate exits and cleanups.
First we have the Complete Layer3 Information, then we have
the IE for the Layer3 information, then the GSM48 hdr, then
the actual content with data. Right now we are parsing the
LU but we are not filtering anything yet.
The MSC does not respond to a SCCP CR with Paging Response as GSM
payload, when the response comes in 'too late'. Prevent the MUX having
stale connections and start removing old connections every 20 minutes.
The adding of the innocent looking code was actually overwrote
the fd and then stupid things happened. Rename variables to avoid
that. rc,ret should be scratch variables...
We do want to send PING/PONG in both ways to have a heartbeat
on the TCP connection. When switching over to SCTP we can rely
on the builtin heartbeat functionality.
We will send a ping every 20 seconds and if we have no pong
within 5 seconds we will close down the BSC connection and
wait for a reconnect. We will start this after having
authenticated the BSC and we stop the timer when destructing
the BSC connection.
The code needs to be refactored but this is fixing the leak for
now. We used to forward everything to the BSC but now we handle
the DLCX locally and this means we need to clear the patched
message. We should refactor it to not generate the patched msg
until a lot later.
In case we can not find the SCCP connection we still want to
free any pending transaction ids and reset the BSC inside the
endpoint. In most cases this should be already done when the
SCCP connection or the whole BSC is gone.
Remember that we have seen a CC and have a valid destination
local reference now and only send a fake RLC to the MSC when
we had connections in this state.
For now close the connection when having a short read. This might
be due a network issue (loss of segment) or similiar. As we are not
handling these issues well, let us close the connection.
When setting a new MSC timeslot to a SCCP connection check if
any of the existing connections have this timeslot, if so we will
send a DLCX down the stream to make sure it is closed there, when
we will CRCX this new timeslot we will happily reallocate it.
When the SCCP connection goes away, or we get a DLCX from the
network, or the BSC is gone we will send a DLCX message down the
stream as well.
When we receive a CRCX from the network we will forward the CRCX
as usual and send a dummy MDCX after it.
For the DLCX and the dummy MDCX we send a custom MGCP message
that will not provoke an answer. Even if the downstream MGCP GW
will answer we will ignore it due the dummy transaction id that
is not used anywhere else.
This change should make sure that we close the dowstream endpoint
all the time, even when the DLCX arrives after the SCCP connection
is torndown.
When sending a MSG to the MSC try to find the to be used "src" reference
by comparing the reference on the BSC and the BSC connection. Only this
tuple needs to be unique.
Actually only when looking at the SRC REF we need to compare the BSC as the
dest reference should be unique but we are just making the check a bit stronger
to make it look symmetric.
If we find the connection of a different BSC at least log the
BSCs that had duplicated references. We should also dump the
src ref and such but i am not doing this right now.
We will reset the multiplex in a DLCX message and then
we can reset the multiplex as well...even if the MGCP
connection is staying open. or at least this is a theory.
The MSC likes to leave a connection open during CallControl
when hanging up early enough in the process.
In case we have a stale SCCP connection with an Endpoint that
we want to reassign...use the newest (last) occurence of that
as it is most likely the one we want to handle.
Create the GSM network at the end of the init, send the
GSM reset on each reconnection and close a small window
when we would send a SCCP msg before being authenticated.
For that we have introduced an authenticated into the bsc_msc
struct and will manage it inside the bsc_msc_ip.c
Count number of SCCP connections, number of BSC reconnects,
number of calls. For most of them we have a per BSC and a
global count.
Right now all structs using the counters survive until the
end of the application so we do not need to free them.
It was possible that the nat detected the core network
gateway as the bts just due being the first to send data
to the port. Fix it by setting a dummy bts_ip to force
the mgcp_network code to compare the in_addr.
This method currently prepends the IPA header and sends
the data. In the future we might be able to use SCTP for
it.
We have to remove the IPA header from the static messages
for that to work.
This code is untested.
E.g. when the MGCP on the BSS is not responding we could block
all of our endpoints. As we are mostly in the middle and forward
bits we will happily reallocate the endpoints.
When not being able to allocate the msgb for the forwarded data
there is no point in keeping and preparing the transaction. So
we can move the msg creation a bit up and only do the allocations
after having done the msgb allocation.
When receiving a DLCX we will now delete the endpoint right away. This
means when a BSS does not respond to the DLCX our endpoint will not
be blocked. E.g. this could happen when the MGCP is restarting or
in similiar conditions. When the BSS is not responding we move the
burden up the chain to the CallAgent. We have to still keep track
of the transaction id and the bsc pointer to keep the mgcp forward
routine working.
Sending a RLSD with SCCP failure makes the MSC free all the resources
(MGCP, audio channels), right now we are ignoring the RLC we get from
the network and print a unhandled message.
This value is copied into the bts_audio_payload when allocating
a BTS MGCP endpoint. For the nat we have actually no interest in
patching MGCP messages. We will patch them to the network because
the code will do it anyway, we will not patch things back to the
BTS.
Remove the code to parse port as we need to discover the
BTS behind the nat and most likely it will have a different
port than the one advertised by the BTS.
This reverts commit c6a1fe773d.
Fix the test to search for the original message instead
of the already patched one that should not find any items
anyway.
The remove is called on already patched connections so we
need to match it with the patch reference count.
Instead of checking the token for NULL we need to check if running
was set to null. Look at the data of the token and check if the line
was ending with a \r\n or \n and then when rewriting a line use that
line ending as well. Add a new test for that.
The MGCP protocol parsing is adding '\0' to make sure we do not
parse beyond where we should parse. This does not mix with strtok
or similiar routines.
For now we will read the msg into a global array first, then copy
it to the msgb for mgcp protocol handling and if we are required
to forward it to the MGCP we have a untouched copy we will modify
into our own msgb.
Attempt to find the message by transaction id, then patch
the response and use the IP/PORT of the local network, update
the ci with the one from the BSC.
This is currently not tracking any state of the MGCP and will
not handle two bsc's... this will need to happen later.
With this in we should be feature complete and now enter the
mode of making all of this work reliable and fixing thinko's
and other bugs.
* Forward a rewritten msg to the BSS. We change the IP and port
to point to the NAT instead of the core network. We also keep
track of the BSC and the transacition id.
* Handle the case where we have not found a SCCP connection and
need to send a response ourselves.
Add code to change the ip and port for audio data inside
MGCP messages. This is needed because the BSS might be
behind the NAT and can not reach the network directly and
might be behind a nat so the announced sourceport is not
the one as we see it.
When losing the SCCP connection make sure that we free all
endpoints. The disconnection of the BSC should already make
sure they are closed but this makes sure everything is
properly reset.
For the nat we will have NAT and MGCP in the same process
and this commit starts with that. We are linking in the MGCP
code and one can embed MGCP config snippets...
* Return the SCCP connection. This will be needed to store the
assigned timeslot in there.
* Update code to work with this change
* This uncovered a bug in the CC handling, at the time the BSC was
passed it was still a null pointer and the code would have failed.
Moving it here means we can more easily test this code, there is one
behaviour change with the code that we only support paging messages
with one LAC and will silently ignore the others.
This test case tests connectiont tracking by sending
a CR, getting a CC, sending a DTAP, receiving a DTAP,
receiving a RLSD, sending a RLC. It verifies that the
messages are properly patched specially the references
at the BSC.
When sending a message to the MSC in the case of DT1
messages we only have the address of the MSC, so we
need to go with that, otherwise (e.g. in case of a CR, RLC)
we do have the source address and need to patch it.
When forwarding a message to the BSC we do receive
a msg that should contain the patched address, we need
to unpatch it...
On a CC message we will need to remeber where the source local
reference of the network belonged so we can properly identify
the connection when receiving UDT messages.
When we disconnect from the MSC handle it by pushing the problem
to our connected clients. We will simply close all connections,
reject all new BSC connections and attempt to reconnect to the MSC.
Create a BSC<->MSC interface and use it for the BSC MSC IP and the
BSC NAT to reduce code duplication on handling reconnects to the MSC
and cleaning up the local state. The code is only partially tested
and will contain bugs. Currently both the BSC and the NAT will just
exit on connection loss and this way have the current behavior.
The latency of setting up of the TCP connection can be quite high,
it is better to connect in a non blocking way. This code is working
by setting the socket nonblocking and temporarily replacing the
bfd callback with the connect handling.
Once the OS has connected our socket we switch back to normal operation.
In case we disconnect with some pending operations we will need to
signal the MSC that something is wrong. This could be by sending a
RLSD directly, or a clear command. Another part of the fix is to
respond with a RLC on unknown RLSD messages.
* Provide access to the GSM0808 TLV attributes so we can use it in
the nat code.
* Read the PAGING message, if it is paged by LAC we go through each
LAC and then attempt to find the proper BSC connection and then
send the message to that BSC.
Based on the token the NAT/MUX is capable of figuring out
which LAC this BSC is supposed to satisfy. This will be
needed for messages like paging that can be done by LAC.
* Create struct bsc_nat and move the various lists into this structure
* Create the VTY code
* Call the VTY init and parsing code
* Create functions to create the types..
* Add some stuff into the bsc_connection to be used for the NAT with
proper config files. E.g. to close the connection if the BSC does not
respond to a given command.
For the one MSC and n BSC case we need to patch the SCCP source
local reference on connection orientated links to avoid a clash.
For simple UDT packages we just let them pass and for SCCP connection
we have to:
1.) Create an entry on Connection Request
2.) Patch the entry on Connection Confirm, Connection Refuse,
Connection Release, DT1, Connect Release Complete
3.) Remove the entry on Connection Release Complete
The current code is blocking CRs, Release Complete from the MSC, and
creates the connection state only from the BSC side. The code to
assign a source reference is taken from sccp.c and handles wrap
arounds and such properly. We rely on the SCCP parser to fill out the
place to the source reference correctly so we can easily fix it.
The whole code is young and might contain bugs we need to resolve..
Introduce a bsc_nat_parse method to parse a IP Access method
into various parts. Write out the IPA Proto, in case SCCP is used,
store the msg type, pointers to the source/dest local reference and
other information.
Use the result of bsc_nat_parse inside the bsc_nat_filter method
to decide if the message should be dropped or not.
In the future the bsc_nat_parse result will be used for patching
SCCP references and other parts of the message.
The filter language should be able to filter the msg type of SCCP
messages and gain the "NOT" word in the filter language.
The first part is to analyze the IP Access Header and only forward
SCCP messages for now. In the future we might want to do MGCP
signalling through this protocol and connection as well and need to
update this then.
Harald actually pointed out that this feature is just NAT. We want
to connect n-real BSCs to one BSC Mux. We will talk the ip.access
protocol and SCCP over of this link.
The mux will drop certain GSM messages (like the reset), it will
replace source local reference (NAT functionality) and it will handle
some GSM08.08 specially.
Get the thing started...
* gsm_04_08_utils.c will directly send the message...
* gsm_04_08.c will use the DTAP API, add a new method to pull
in the data from the transaction...
When submitting a DTAP message, the BSC API will attempt to
establish the RLL layer and then send the message or send an
SAPI n REJECT. This will be used by the SMS code.
This will take care of the auth/check/enable cipher sequence
and call a callback function when done.
Currently the negotiated Kc is saved but not re-used, so
there is an authentication each time ...
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Ultimately, we'll need to store both the last used tuple by a
subscriber and a list of known tuples (for unknown Ki). What's
currently implemented for AuthTuples is the former behavior, so
reflect that.
The second use case will be added as a separate table with separate
accessors later on.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
According to the GPRS NS spec the maximum framesize
is 1600 octets for FrameRelay, it can be bigger if
configured to be so. Make it 2048 octets to have some
space available...
We now have a function that generates BSSGP PS and CS paging request.
It is called from the libgtp code when we receive a GTP packet from
the GGSN for a MM context that is in SUSPEND state. We then issue
a PS paging request to the Cell with the BVCI where the last RA update
was being performed.
TODO: We still don't enqueue the GTP packet (and transmit it on paging
complete), and we don't rate-limit the paging requests, i.e. every GTP packet
will trigger another paging request.
We probably also need some kind of logic that marks the phone as UNREGISTERED
if it doesn't respond to paging requests for some time.
The paging message should not be called directly and the GSM Subscriber
can handle multiple requests at the same time... Now a subscr_put_channel
should be called after the message sending. But it is not very clear when
this can be called. The current code works by luck that the SAPI=0 will
be released...
The MT-SMS was tested via the VTY interface and a N900.
We will tell the BTS where we are listening, but the ACK
will return the original settings... this should make it
possible to intercept the GPRS stream..
As we don't support compressed SMS, we have to properly reject it.
In the existing code, we segfaulted at some later point since the error
handling was incomplete.
This was triggered by some obscure STK SIM card that insisted on sending a
compressed SMS after registering to the OpenBSC network.
Some phones (notably a Ericsson Mobile Platform based E-TEN M800)
insist on sending PDP CTX DEACT messages for contexts that have already
been deactivated. The spec doesn't really say what we should do in
this case. But since there is no "reject", we simply acknowledge it.
This is a good interim solution for messages not handled by us,
right now this would include the NVRAM attributes that I do not
feel like caching right now.
Right now the memcpy with the data will copy data to itself as
the new_msg->data and msg->data are the same due the previous
copying of the header which included copying the list entry..
We allocate a message as big as the current one, then we have to
set all pointers by looking of how far they are away from the
msg->_data and add that to the new pointers.
Also copy the OpenBSC/GPRS specific CB data, also do the same
for calculating the offset to the data... At the end we should
end up with a copy...
Do not use RSL to release the SAPI/Channel from within the code,
the normal channel release procedure will take care of releasing
the SAPIs and there should be no issue in keeping the SAPI=3
established until the end of the session.
If we send the IDENTITY REQUEST for IMEI before sending the IDENTITY
REQUEST for IMSI, the probability is higher that we receive the IMEI
response and associate it with the respective subscriber.
Using the code of this commit, it was possible to provision GPRS
services and access a website from a G1 phone (Qualcomm MSM7k baseband chipset)
using a nanoBTS, Osmo-SGSN and OpenGGSN.
There is still no fragment re-assembly in the uplink path yet,
despite the (untested) code present in the gprs_sndcp.c file
This only works for packets that are small enough to not need
fragmentation at the SNDCP layer (dns queries, ntp and the like).
It requires libgtp built from OpenGGSN dc3744fda045f9fca83de6881176987335a309a8
or later. Plain 0.90 will NOT work.
Using this version, I could see bi-directional traffic from various
phones going all the way through BTS, OsmoSGSN, OpenGGSN and being routed
to and from the real internet. Time to celebrate...
We have to copy the sin_addr.s_addr, rather than the entire sin_addr. The
latter results in the destination interpreting it as an IPv6 address, as
the only differentiator between IPv4 and IPv6 is the size of the payload
of this IE.
* separate the LLME and LLE state in the LLC layer
* introduce gprs_llgmm_assign() function for LLGMM-ASSIGN.req primitive
* change QoS profile to match 'real' SGSN
* Update the new TLLI when assigning a P-TMSI
The result now is that the LLC layer is notified of TLLI changes, which in turn
means it doesn't allocate a new LLE structure every TLLI change, which again
in turn means that the UI frame sequence number does not reset to zero.
As a result, MS should no longer ignore frames based on wrong UI sequence number.
When we send a downlink unit-data request via BSSGP, there is a lot
of information that needs to be copied from the mm context, such as
the IMSI, DRX parametes, MS radio access parameters, ...
This is a quite strange layering violation, since we now need to pass
a pointer to the MM ctx from GMM through LLC into BSSGP :(
Our state transitions and timers now reflect 04.08 for GMM much
better than before. Also, we allocate a new P-TMSI on every ATTACH
and RA UPDATE, as some phones seem to get confused if they don't
get a P-TMSI.
When we issue a RF Channel Release in case of a failure we receive
RLL release indications after the channel was tearn down and we
issue another RF Channel Release as a result. The channel allocator
might have already allocated this channel and we release the channel
again with another MS on it.
Make rsl_rf_chan_release take an error argument and make it set
a new state in case of an error and change the RF Channel Release
ack to not set the state back to none in case of an error but wait
for a timeout that is a bit higher than T3111.
I tested this with removing the battery during a phonecall and
waiting for the channel failure. With this test we only send the
release once.
We assume that the lchan_free will initiate the release and
that when we handle the RLL release indication or the release
request as part of the shutdown sequence.
The current channel release has a couple of issues we will
need to fix in a set of upcoming commits.
The issues include:
1.) sending release twice
2.) reassigning the channel inbetween the relase..
This is of course not the correct way of dealing with it, but for
now it should make the Ericsson Mobile Plafrom based phones happy
(they insist to do a suspend/resume cycle before pdp ctx act)
GRE has the strange notion of keepalive messages being encapsulated IPv4
packets adressed back to the sender. Since we actually really only care
about frame relay, this is a bit strange. However, we'll do some sanity
checks and send it back through our GRE socket...
0 Reserved for ANSI Annex D and CCITT Annex A link management
1 - 15 Reserved
16 - 1007 Any PVC
1008 - 1018 Reserved
1019 - 1022 Reserved for LMI multicast
1023 Reserved for LMI link management
According to the spec, after an incoming RESET or RESET_ACK, we shall start the
TEST procedure, not the ALIVE procedure.
Also, when we start the TEST procedure, we have to always send a NS_ALIVE
packet at the same time (we didn't in the case of incoming RESET).
Furthermore, we now only start TIMER_TNS_ALIVE from within the
TIMER_TNS_RESET callback code, where we also make sure that the
alive_retries counter is reset to zero.
We previuosly had a 'subscriber node' under the 'configure node'
which is strange, since subscriber data is not part of the config file.
The relevant operations have now all been moved to the ENABLE node
of the VTY.
Furthermore, 'show subscriber' does no longer require the IMSI but
can also identify the subscriber by ID, TMSI or other identifier.
Change gprs_nsvc_reset to return void instead of a int
as the gb_proxy.c currently ignores the reutnr value anyway.
Change the caller inside gprs_ns to return the newly allocated
nsvc instead of the return of gprs_nsvc_reset.
Almost all parameters about the SGSNs NS-VC can be specified in the NS
protocol node. All that needs to remain in the gbproxy config node
is "nsip sgsn nsei XXX".
* store LLC SAPI as part of PDP ctx
* store NSEI + BVCI as part of MM ctx
* export gsm48_tx_gsm_act_pdp_acc() and call it from sgsn_libgtp.c
* create and use gsm48_tx_gsm_act_pdp_rej for error cases
* print SAPI as part of VTY show pdp
libgtp of the OpenGGSN project will allow us to speak the GTPv0/v1
protocol of the interface between SGSN and GGSN.
This commit includes code for the main libgtp integration (file
descriptor, select loop, timer) as well as code to encode/send
a CREATE PDP CONTEXT request.
We want the VTY and telnet code to be independent from the BSC
application(s). As a side note, we also like to eliminate static
global variables for 'struct gsm_network' all over the code.
As such, telnet_init() is now passed along a "private" pointer,
which getst stored in telnet_connection.priv. This telnet_connection
is then stored in vty->priv, which in turn gets dereferenced if
anyone needs a reference to 'struct gsm_network' from the BSC vty
code.
Also:
* vty_init() now calls cmd_init()
* the ugliness that telnet_init() calls back into the application by means of
bsc_vty_init() function has been removed.
* telnet_init() now returns any errors, so the main program can exit
e.g. if the port is already in use.
This enables us to make the VTY completely independent of any
compile-time program-specific information, i.e. one step closer
to using VTY as a shared library from multiple programs.
Rather than deleting the NSE from memory, we simply mark it as non-persistent.
This makes sure that there are no invalid references (e.g. from gbprox_peer)
to the gprs_nsvc structure, but at the same time ensures it will no longer
be stored as part of writing the config file.
So far, we only started the ALIVE procedure on RESET-ACK if the
remote end was the SGSN. This resulted in the BSS->Proxy connections
only being tested for alive-status from the BSS side, but not from
our side.
Also: export nsvc_by_nsvci() function as a public API function.
This is a generic MI extraction for the MI if it is followed
after a classmark. For the Phase1 Phones the classmark2 is not
four bytes but it might be different. This code can be used
by the CM Service Request handling as well.
We go from no size checks to some content checking. We should
refactor the whole classmark2 + mi parsing that is used throughout
the code into one place with proper size checking. This is the
start and requires a new libosmocore as well.
Using "end" you can always return to the "enable" level, and from
there the "show" commands are available. So no more need for
exit/exit/exit/exit/disable.
Some BSS that connect to the proxy do not continue to perform the
RESET procedure after a timeout. In order to resurrect them, we
simply start a RESET procedure.
We now actually are much more in line with what the specification
says. We track the blocked/unblocked state, we don't accept
signalling messages on PTP functional entities (and vice versa),
and we don't simply create a BVC context with messages other than
BVC-RESET.
Don't allocate a LLC Entity just because BSSGP passes any random
SAPI/TLLI up to us. We can only do this for XID and UI frames
of the GMM SAPI.
Furthermore, add more comments and debug messages.
I want to have a shorter lchan summary but with the same
config parameters. Change the current code to be a method
that takes a dump routine as parameter.
Add the rach emergency call allowed (0|1) setting and implement
it by directly manipulating the t2 value. It is the third bit which
is set to 0 when emergency calls are enabled and to one if it is
only enabled for access classes 11 to 15.
Add the rach emergency call allowed (0|1) setting and implement
it by directly manipulating the t2 value. It is the third bit which
is set to 0 when emergency calls are enabled and to one if it is
only enabled for access classes 11 to 15.
In the previous code we used a static fake_nsvc structure in
case we needed to send a message to an unknown NSVC for which
we don't have a real 'struct nsvc'. However, since we now have
a rate_ctr_group hanging off the nsvc, the fake structure didn't
have that.
So now we keep a nsi->unknown_nsvc around to be used whenever
we need a nsvc but don't have a real one. The gprs_ns_vty.c
code explicitly does not list that NSVC in 'show ns'
If a second ends, we add the number of events in that just-ended second
to the number of events in the currently running minute. The same happens
at the end of a minute: We add the number of events in that just-ended
minute into the number of events of the still-running hour, etc.
This gives a much more meaningful numbers and we don't end up with
"12 events per second, but 0 events per minute" kind of situations
anymore.
Every NS-VC now has a set of counters for incoming and outgoing
number of packets and bytes.
We also split the VTY part of the gprs_ns.c implementation into gprs_ns_vty.c
to make sure the protocol can actually be used without the VTY code being
present.
A 'rate counter' is a counter that counts events but also keeps
track of the rate of events (per second, minute, hour and day).
'rate counters' are generally abstracted in 'rate counter groups',
which are instances of a 'rate counter group description'. This
way we can have e.g. a description describing what kind of counters
a BTS (or TRX) has - and we can then create one instance of that
group for every BTS or TRX that exists.
As only NS-UNITDATA messages are ever passed into the Gb Proxy,
we need to do the msgb_free() at a much higher point in the calling
stack, i.e. inside the NS protocol layer. This means it is now
the same logic as in OpenBSC itself.
The old idea was to take a msgb from gbprox_rcvmsg() and then
modify it and finally send it all the way down to nsip_sendmsg()
to the remote peer.
However, this introduces memory management difficulties, as we then
have to distinguish three cases:
* msgb was sent to a remote peer
* we sent some error message and need to free the msgb
* we need to make n-1 copies in case of a BSSVC-RESET from the SGSN
So instead we now simply always copy the message if we pass it on.
All messages received by gbprox_rcvmsg() are msgb_free()d in the very
same routine
All messages allocated by tx2peer() or tx2sgsn() are freed after
nsip_sendmsg()
For the multi TRX setup we will need to specify the right trx->nr
to be able to flash the BTS. For the BS11 case we are ignoring the
additional argument.
Send the IPA Restart to a given BTS/TRX, change the signal callbacks
to carry the trx instead of the BTS so we have an easy access to the
right TRX and change the ipaccess-config to use that TRX. This is
fixing the restart with a multi TRX setup.
Even if we have the msg->trx, use the gsm_bts_trx_by_nr and get
the TRX from the fom header. This is because the OpenBSC and the
BTS numbering might not match for the multi TRX case.
Currently we are connecting to the BTS and once the OML is established
we are bootstrapping the OML. This does not work for a multi TRX setup
as we will need to use a trx_nr != 0 for it.
Change the code to wait for a message (in this case NM OC_BASEBAND_TRANSC)
to detect the trx_nr used by the BTS and then use that TRX to bootstrap
the network.
I have tested setting the unit id on a single and multi trx system for
the first and second trx.
With persistent NS-VC configuration (configured through VTY),
we can respond properly to BSS with a somewhat strange NS
implementation Such as the BSplus. It enables us to respond
with a proper NS-RESET (including NSVCI/NSEI) when receiving
a NS-ALIVE or other PDU for a BLOCKED/DEAD NS-VC after our
end of the connection is rebooted.
If a PTP BVC is BVC-RESET by the BSS, the PDU contains the
Cell Identifier. We can snoop this into our gbprox_peer structure
for better visualization of each peer in they vty.
As the logging config is getting more and more complex, it is good
if it can be displayed interactively.
WARNING: This needs libosmocore 0.1.6 or later!
'logging level' can already parse a human-readable level such as
'debug' or 'notice'. By setting the global mask within the same
command we can also parse it there.
In order to reuse the existing bssgp_tx_* functions without pulling
in the dependencies of gprs_bssgp.c, we have to move those functions
to gprs_bssgp_util.c
Furthermore, we can remove gbprox_nsi and replace it with bssgp_nsi,
and we can do proper processing of BVC-RESET messages coming from
the SGSN on the signalling BVC. In that case we need to send RESET
messages to all the BSS.
In order to finish PDP context activation and start the transfer
of SNDCP N-PDUs, we simply confirm to the MS whatever XID parameters
it requests. This of course has to be implemented with a proper
XID handshake at some other point.
The message looks now fine (from wireshark point of view). However,
we cannot simply echo back the QoS parameters, as the meaning in
uplink and downlink connection is not the same.
BSSGP stores a pointer to the Cell Identifier IE in msgb->cb, which
is later used by the GMM layer to identify the cell that has sent a
given message.
This now also means that the gsm_04_08_gprs.c code is free of any
legacy references to msg->trx or struct gsm_bts.
We now expect the highest level (actual SGSN GMM code) to know
all identifiers for every element in the protocol stack, i.e.
TLLI, SAPI, BVCI and NSEI. The layer-inetrnal state is looked
up based on those identifiers.
The reason for this is to ensure only the highest level state
needs to be persistent, while everything else can be regenerated
dynamically (e.g. in a SGSN restart)
In the old code
l3h = BSSGP, l4h = LLC, cb[gmmh] = 04.08
Now, this has been changed to
cb[bssgph] = BSSGP, cb[llch] = LLC, l3h = 04.08
This way, GSM general 04.08 and GPRS 04.08 code can expect a
GSM 04.08 header at msgb->l3h
Instead of continuing to add more and more functionality to the
bsc_hack binary, we should have the new SGSN code run as a separate
executable.
After this commit we now build a 'osmo_sgsn' executable, using its
own osmo_sgsn.cfg config file.
However, the SGSN is not yet functional, mainly due to the fact that
the BSSGP and GMM code are written with the assumption that there
is a msgb->trx->bts and the according 'sturct gsm_bts' data model
around - which clearly is no longer the case outside of bsc_hack.
The ida of the Gb proxy is to aggregate Gb links with a number of BSS
and then present all the BSSGP-VC's together inside one NS-VC to the
actual SGSN.
The code is not yet expected to be complete.
According to TS 08.16, the BSSGP layer needs to specify NSEI and BVCI when
executing the NS UNITDATA REQUEST primitive of the underlying NS layer.
Rather than passing around a pointer to the 'struct gprs_nsvc', we now
have NSEI and BVCI as members of 'struct obsc_msgb_cb' and set them
when BSSGP hands a message down to NS.
NS then does a lookup of the 'gprs_nsvc' based on the NSEI parameter.
* move UDP listener code for NSIP from input/ipaccess.c and into gprs_ns.c
* add PDU type, IE and CAUSE values for later IP based 3GPP TS 48.016
* support multiple NS-VCs and their lookup based on NSVC and sockaddr_in
* maintain the remote_state (blocked/alive) for each NSVC
* introduce the concept of GPRS_NS instances, move all global vars to instance
* remove hardcoded calls to gprs_bssgp_rcvmsg() and replace it by callback
WARNING: This is not finished code. While it will compile, it will not work
yet, as BSSGP needs to be converted to properly indicate the NSVC to which it
needs to send data.
The explicit 'tlli, gmmh' members of struct msgb are gone from
current libosmocore and have been replaced by the more generic
'control buffer' mechanism.
While doing 'nm' on a VTY-using object file I noticed that all
cmd_elements are global symbols, which is not good.
Unfortuantely there are some vty-internal cmd_elements that need
to span across object files, so I had to introduce gDEFUN()
and gALIAS(). The old macros now all declare static structures.
I assume the original code crashed with a double free as we
have a cleanup at the end of the method. Return from the routine
like the case label below. This is fixing a memory leak I am
experimenting.
Stop using the global vty context for all allocations
and allow to embed the buffer into a given context, and
allocate sub buffers with the context of its parent.
The previous code just hardcoded RSL_BCCH_CCCH_CONF_1_C, but
we need to inspect the timeslot config to know what to use.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This breaks the ARM build in osmocom-bb. Besides uint??_t seems to
be the preferred type in osmocore. (coming from stdint.h vs sys/types.h)
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Stop the tx_timer when deleting the link on top of that ts. Otherwise
bad things might happen. E.g. when scheduling a write on OML and then
the OML link vanishes...
This is a slight layering violation as there could be more than
one signalling link on the timeslot (at least in theory) so the
queue and the timer should move to the e1inp_sign_link.
Be able to tune the RACH settings of the BTS via the vty interface,
by default they are initialized to -1 which means we will use the
content of the static array (BTS default) and can be changed via
the VTY interface. I have verified the setting on the nanoBTS with
wireshark and I have tested writing the config file.
When allowing to reallocate an allocated endpoint we will need
to free it first. When freeing we will free the call id and other
ids that we would have leaked otherwise.
This routine should operate on different packets and the
dummy load is smaller than a legitimate RTP header so it
is unlikely we will filture out genuine traffic.
The reason is the dummy load might be send more than once.
This can be used by higher level code to send one dummy
message from the audio port to the network. This can be
used to make the remote discover the nated port of this
endpoint.
My previous attempt to only add the hunks I changed broke the
format of the patch and this time I am just dumping my current
patch on top of these patches.
Right now I'm seeing crashes when removing a link and deleting
it and I need this hack to make it not crash. We will have to
understand if llist_for_each_entry_safe has a bug or if we are
doing something bad with the list (anchors not properly initialized).
Before this patch, there was a bug in the code caused by a memcpy
from one data structure to another. unfortuantely the data structures
were not the same, so we have to explicitly iterate over the array
and assign the structure members manually.
2010-03-26 22:04:03 +08:00
353 changed files with 40607 additions and 34759 deletions
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.