Compare commits

...

660 Commits

Author SHA1 Message Date
Neels Hofmeyr
6950d14c5b Merge branch 'master' into sysmocom/iu, with tweaks
Numerous manual adjustments are included to make sense on the sysmocom/iu branch:

* gsm_04_08_gprs.h has moved to libosmocore on the master branch, but
  sysmocom/iu has added some entries. Until it is clear whether to move the
  additions to libosmocore as well, keep gsm_04_08_gprs.h on sysmocom/iu with
  merely the additions.
* Thus, keep using the old gsm_04_08_gprs.[hc] from openbsc in the Makefiles,
  but only where the sysmocom/iu additions are needed.
* In openbsc's gsm_04_08_gprs.h,
  * include the libosmocore gsm_04_08_gprs.h,
  * use '#pragma once' instead of #ifndef and
  * add a TODO comment about moving the rest to libosmocore.

* Apply the addition of an osmo_auth_vector to gsm_auth_tuple: in the Iu auth
  vector hacks, use the gsm_auth_tuple.vec instead of a local struct.
  See iu_hack__get_hardcoded_auth_tuple() and gsm48_rx_gmm_att_req().

* In the si2q tests, pass NULL as ctx to gsm_network_init().

* In cscn_main.c, add a debug log that was originally added to osmo-nitb.

* openbsc/.gitignore: keep only one addition of 'writtenconfig'

Conflicts:
	openbsc/include/openbsc/gprs_sgsn.h
	openbsc/include/openbsc/gsm_04_08_gprs.h
	openbsc/src/gprs/gsm_04_08_gprs.c
	openbsc/src/libmsc/gsm_04_08.c
	openbsc/src/osmo-cscn/cscn_main.c
	openbsc/tests/gsm0408/Makefile.am
2016-05-09 00:26:01 +02:00
Harald Welte
cd5e52605c sgsn_test: Adapt test case to now-existing InsertSubscriberData
We recently implementd InsertSubscriberData in the SGSN, adapt the test
to reflect that.
2016-05-06 13:49:20 +02:00
Harald Welte
7c55ede8b1 Add human-readable name of SGSN_AUTH_AUTHENTICATE
In commit 4adb136da6 we introduced
a new authentication state SGSN_AUTH_AUTHENTICATE, but we didn't
add that to auth_state_names[] resulting in log messages printing
it abut 'unknown 0x1' rather than something more useful.
2016-05-05 18:31:37 +02:00
Harald Welte
5f2524fe3d sgsn/GSUP: Support MAP-style nested LU/ISD
The existing GSUP code expected the subscriber data to be piggy-backed
onto the location update response, rather than a separate (and nested)
insert subscriber data request/response phase.

With this patch we should now support both the nested as well as the
piggy-backed version.
2016-05-05 18:25:12 +02:00
Daniel Willmann
cf2ca648e9 gprs: Update mm_ctx ra_id from ue_ctx 2016-05-04 19:05:05 +02:00
Daniel Willmann
62ee416d95 libiu: Keep current ra_id in ue_conn_ctx 2016-05-04 19:05:05 +02:00
Daniel Willmann
e42a2ab158 libiu: Also get routing area code if present in InitialUE Message 2016-05-04 19:05:05 +02:00
Daniel Willmann
9336cede84 libiu: Fix memory leaks on receive and transmit
The ranap_handle_* functions generate a msgb and pass it on to the receive
callback. After processing the message the msgb needs to be freed again.

iu_tx() takes a msgb and uses ranap_new_msg_dt() to generate a new msgb from
it. The old msgb needs to be freed.
2016-05-04 19:05:05 +02:00
Daniel Willmann
8c6732909b gprs: Track PMM states
For Iu mode it is important to know when the UE is in PMM-IDLE mode since the
SGSN will need to page the UE if there is data for it.
2016-05-04 19:04:10 +02:00
Neels Hofmeyr
960d28087e IuCS: upon sec mode compl, check that a sec op is pending
Safety check: discard Security Mode Complete messages when there is no
security operation pending.
2016-05-04 16:06:59 +02:00
Neels Hofmeyr
a27b295100 msc: fix: two missing security operation releases
When receiving authentication response or security mode complete messages,
actually release the security operation stored with the subscriber conn.
2016-05-04 16:06:59 +02:00
Neels Hofmeyr
9015d4db52 msc: ignore cb retval on auth/sec mode rx
Just return 0 regardless of the security callback's return value when
receiving authentication response or security mode complete messages.
2016-05-04 16:06:59 +02:00
Neels Hofmeyr
3cda077541 IuCS: properly clean up conn on release
Don't call msc_subscr_con_free() directly, instead use
gsm0408_clear_request(), which properly cleans up all pending operations
before freeing the connection.
2016-05-04 16:06:59 +02:00
Neels Hofmeyr
c3da27fa98 gsm0408_clear_request(): actually free the released conn
By having conn->in_release == 1, calling msc_release_connection() has no
effect and thus never frees the conn. So, after all pending requests have
been discarded, also discard and free the unused connection.
2016-05-04 16:06:59 +02:00
Neels Hofmeyr
bfc190e0fc gsm04_08_clear_request(): release loc with arg release=0
In gsm04_08_clear_request(), in_release == 1 anyway and
msc_release_connection() would exit immediately without any effect. Don't
confuse the reader by passing release=1 arg.
2016-05-04 16:06:59 +02:00
Neels Hofmeyr
f959ad8991 cosmetic: move subscr_conn alloc&free to gsm_04_08.c
Subscriber conn stuff doesn't really belong in gsm_subscriber.c.

(I moved because I thought it would call some static functions in gsm_04_08.c,
which ended up not being the case; anyway, it makes more sense to stay in
gsm_04_08.c.)
2016-05-04 16:04:36 +02:00
Neels Hofmeyr
f3bcdd272b msc subscr: add paging timeout
In NITB, the paging timeout would be handled from the BSC side. In IuCS, we
need to invalidate the paging request from libmsc alone, so add a paging timer
to gsm_subscriber.

Possibly, the HNB-GW should respond with a paging failure and libmsc could
trigger on that, nevertheless libmsc should not rely on a failure message to
expire pending pagings.
2016-05-04 13:23:34 +02:00
Neels Hofmeyr
1d125c902f subscr_paging_dispatch(): add assertions
Make sure that subscr and conn are valid:

* a subscr must always be present.
* on success, a conn must be present and the subscr must match the conn's
  subscr.

Also check the hooknum.
2016-05-04 13:20:11 +02:00
Neels Hofmeyr
35ebbbea7a gitignore dir for python config tests 2016-05-04 13:20:11 +02:00
Neels Hofmeyr
a95927c1de comment tweak 2016-05-04 13:20:11 +02:00
Neels Hofmeyr
03ded61060 debug log for SMS 2016-05-04 13:09:01 +02:00
Neels Hofmeyr
26d0326157 debug log tweaks for paging 2016-05-04 13:09:01 +02:00
Neels Hofmeyr
885a11b33e Revert "subscr_paging_dispatch(): use conn->subscr instead of separate param"
This reverts commit 6f4e83beb0, but note:
this is not a 1:1 revert since the subscr_paging_sec_cb() semantics have changed.

In subscr_paging_dispatch(), the separate subscr parameter is needed in cases
where paging expired and there is no conn available.

For subscr_paging_sec_cb(), a conn must always be available. Hence it avoids
any duplicity by only passing the conn and deriving the subscr from that.

Callers of subscr_paging_sec_cb() pass NULL as param, so pass conn->subscr when
calling subscr_paging_dispatch() from subscr_paging_sec_cb().
2016-05-04 13:05:36 +02:00
Neels Hofmeyr
99f2477653 cosmetic: IuCS logging 2016-05-02 19:51:12 +02:00
Neels Hofmeyr
a9791df3b9 add enum iu_event_type to string conversion 2016-05-02 19:49:58 +02:00
Neels Hofmeyr
d9202b342c comments and debug log for paging response 2016-05-02 17:05:13 +02:00
Neels Hofmeyr
c902bd4032 msc_paging_request(): remove unused parameters
The network is known from subscr; the type is not applicable after MSCSPLIT;
cbfn and data are obsoleted by explicit subscr_rx_paging_response().
2016-05-02 17:03:36 +02:00
Neels Hofmeyr
ad21c3b8e3 msc_paging_request(): make static
it is never called outside of gsm_subscriber.c
2016-05-02 17:03:36 +02:00
Neels Hofmeyr
28fdbdcd53 msc: paging: use gsm_subscriber API to add Integrity Protection for IuCS
During peliminary paging response testing, I introduced some code duplication.
Remove that and instead call the code that was there before 63b99ced83
("add preliminary paging response handling, incomplete").

By calling the gsm_subscriber API, the connection is also secured and hence
Integrity Protection is enabled for IuCS.
2016-05-02 17:03:36 +02:00
Neels Hofmeyr
903ad2e135 cosmetic: msc: handle_paging_resp() tweaks
Tweak debug logging, use paging category DPAG.

Change the order of arguments to make more sense in the causal relationship.
2016-05-02 17:03:36 +02:00
Neels Hofmeyr
04bfcdd6c2 paging: actually verify subscriber authorization
Before this, any paging response would be accepted by the CN, without
checking the database whether the subscriber is in fact authorized.

The probability that a subscriber would be able to take unauthorized action
is slim, nevertheless checking authorization status with the database should
happen before we accept a connection.
2016-05-02 17:03:36 +02:00
Neels Hofmeyr
3a9c52a5dc paging: change subscr_paging_cb() into subscr_rx_paging_response()
Remove one layer of callback indirection in paging. When a paging response
arrives, we always want to first secure the connection, thus a fixed
subscr_rx_paging_response() function is more appropriate and avoids having
to store a cbfn. The actual actions to be taken upon successful paging are
of course still in callback functions stored with each subscriber.
2016-05-02 16:30:10 +02:00
Neels Hofmeyr
c6580c5b2c Allow paging even though is_paging is false
It doesn't really hurt to see whether we have paging responses queued for
a given subscriber. Possibly a subscriber replied with a paging response
later than we assumed the paging to be valid.
2016-05-02 16:30:10 +02:00
Neels Hofmeyr
fb845bb1df cosmetic: subscr_paging_dispatch() comments/indent 2016-05-02 16:30:10 +02:00
Neels Hofmeyr
6f4e83beb0 subscr_paging_dispatch(): use conn->subscr instead of separate param 2016-05-02 16:30:10 +02:00
Neels Hofmeyr
214302b306 cosmetic: subscr_paging_dispatch() comments/indent 2016-05-02 16:30:10 +02:00
Neels Hofmeyr
defe78f1e1 add comments on MSCSPLIT and paging 2016-05-02 16:30:10 +02:00
Neels Hofmeyr
061787878c gsm_04_08 mscsplit: subscr_request_channel() -> subscr_request_conn()
Rename subscr_request_channel() to _conn() and remove the channel_type arg.
The "channel" is a term from closely tied MSC+BSC code, after separation we
shall call it a "connection", i.e. over IuCS or A.

The channel_type arg is already unused from a previous MSCSPLIT commit.
2016-05-02 16:30:10 +02:00
Neels Hofmeyr
00007897d4 gsm_04_08: factor out subscr authorization check
Add function subscr_authorized(), absorbing the guts of static
authorize_subscriber() from gsm_04_08.c, except the parts specific to Location
Updating.

subscr_authorized() is a check that is to be added to validation of a paging
response.
2016-05-02 16:30:10 +02:00
Neels Hofmeyr
5c4386c692 cscn: (re-)add SMPP initialization
Remove legacy code from the original NITB version -- the SMPP init functions
have since been refactored in 1b0e5540db.

Add SMPP initialization in the refactored version: call the alloc_init
before reading config file, and call start with the global network struct
after config is read.
2016-05-02 14:04:11 +02:00
Harald Welte
fc68c83ddb Support raw IPv4 address in RAB Assignment Response
There are different Iu dialects in terms of encoding the
transport layer address inside RAB Assignment req + resp.

Let's be liberal in what we accept, and simply use the length
as an indicator of the format.  Wireshark uses similar heuristics.
2016-05-01 15:35:59 +02:00
Harald Welte
74101106a1 RAB Assignment Response: Handle TEID changes
When the RNC confirms the RAB Assignment, it can each time indicate a
new TEID for the GTP-U endpoint on the RNC side.  We need to update our
information about the PDP context and include that in the UPDATE PDP
CONTEXT that we're sending towards the GGSN.  This is similar to
updating the RNC-side IP address of the GTP endpoint.
2016-05-01 15:35:58 +02:00
Harald Welte
db916bfd8d iu_rab_act_ps: Use GGSN-side TEI in RAB Assignment Requeset
When we send the RAB Assignment Request to the RNC, we need
to tell it the GGSN-side TEI for data, not "our" (SGSN side)
TEID.

In the RAB-Assignment.req we inform the RNC of the TEID on the GGSN
side, and in the RAB-Assignment.resp the RNC informs us of the TEID
on the RNC side.
2016-05-01 15:35:58 +02:00
Harald Welte
a54358879f Identify PDP context by RAB ID, not TEI
When receiving an RAB-Assignment response from the RNC,
we should use the RAB ID (=NSAPI) to resolve the PDP context.

We cannot use the TEID, as the TEID chosen by the RNC for this RAB has
no relationship to the TEID we were using for the RAB-Assignment
request.  TEIDs are local to each of the peer, like UDP port numbers.
2016-05-01 15:35:57 +02:00
Harald Welte
a54b47b048 libiu: Fix missing break statements in switch in cn_ranap_handle_co() 2016-05-01 15:35:56 +02:00
Harald Welte
3b922064a4 SGSN: Use PDP Context NSAPI as RAB ID
As Dieter has pointed out, the RANAP spec requires the RAB ID to be
equal to the NSAPI of the PDP context for which it is established.
2016-05-01 15:35:52 +02:00
Harald Welte
5b3fd465d1 Fix parsing of auto-generated config file
When starting with empty config file, saving it by 'write file',
and then re-starting osmo-cscn, it would complain:

Error occurred during reading below line:
 long name Osmocom Circuit-Switched Core Network

The problem is that the vty parser is configured to expect a single
token and not a list of tokens here, but we initialize the default value
with multiple words (which are treated as separate token).
2016-05-01 15:34:08 +02:00
Harald Welte
5d547a4358 osmo_oap_decode(): Use common argument ordering
In general, if a function generates output data like a msgb (or in this
case filling an osmo_oap_message structure), the output argument
precedes the source.  This is what we use all over libosmo*, and it is
modelled after memcpy(), where dst is the first argument, before src.

Let's align osmo_oap_decode().  Intestingly, osmo_oap_encode was already
correct, so the encode/decode functions used different conventions
before.
2016-04-29 13:10:37 +02:00
Harald Welte
d8aa412c46 OAP: Various coding style fixes
* we always declare stack variables at the top of the function / block
* 'switch' is not a function, so there's space ahead of the opening (
2016-04-29 13:10:37 +02:00
Harald Welte
564c06525b OAP: use osmo_oap_ prefix for OAP, rather than plain oap_
this is in preparation of moving related code to libosmocore.
2016-04-29 13:10:37 +02:00
Harald Welte
31760a1f60 oap_message.h: Remove dependency to openbsc include
This is a first step to moving oap_messages.h to libosmocore
2016-04-29 13:10:37 +02:00
Harald Welte
23d77d56ea Move osmo_gsup_messages.[ch] to libosmocore
This requires the corresponding commit in libosmocore.
2016-04-29 13:10:37 +02:00
Harald Welte
50f1c0af56 move utils.h functions to libosmocore
This needs the corresponding commit in libosmocore which imports
the related functions
2016-04-29 13:10:37 +02:00
Harald Welte
eff215a8bb osmo_gsup_messge.[ch] documentation update (doxygen) 2016-04-29 13:10:37 +02:00
Harald Welte
7ca035deca gsup_messages: Add UMTS AKA related encoding/decoding support 2016-04-29 13:10:37 +02:00
Harald Welte
85234a32db move osmo_shift_* / osmo_match_shift_* to libosmogsm 2016-04-29 13:10:37 +02:00
Harald Welte
842674b8b3 rename gprs_shift_*() to osmo_shift_*()
This rename is the first step of moving the associated functions into
libosmocore.

Also, rename gprs_match_* to osmo_match_shift_* to indicate that it is
not just matching the TLV, but also shifting the data portion.
2016-04-29 13:10:37 +02:00
Harald Welte
28903a99ea Rename gprs_gsup_* to osmo_gsup_*
This is a preparation to move the related code to libosmocore, whilst
at the same time generalizing it from GPRS Subscriber Update Protocol
to the Osmocom Generic Subscriber Update Protoco.
2016-04-29 13:10:37 +02:00
Harald Welte
d3fa84dbba use new libosmocore gsm_23_003.h for IMEI/IMSI length
... rather than our private definitions everwhere.  As an added benefit,
gprs_gsup_messages.h is now free of any header dependencies within
openbsc.
2016-04-29 13:10:37 +02:00
Harald Welte
53373bca8f move gsm_04_08_gprs.h to libosmocore
This requres the corresponding commit in libosmocore.
2016-04-29 13:10:37 +02:00
Harald Welte
121e9a4164 Start to use struct osmo_auth_vector from gsm_auth_tuple
Rather than having a 'private' structure for kc, sres and rand, we
now finally (with 4 years delay) use osmo_auth_vector from libosmogsm,
which encapsulates authentication vectors that can be either GSM
triplets or UMTS quintuples or a combination of both.

gsm_auth_tuple becomes a wrapper around osmo_auth_vector, adding
use_count and key_seq to it.

key_seq is no longer initialized inside gprs_gsup_messages.c, as there
is no CKSN / key_seq inside the message anyway.  If a usre of the code
needs key_seq, they need to manage it themselves.
2016-04-29 13:10:37 +02:00
Max
3ffce19cb4 Disconnect calls with incompatible channel types / modes
In case both TCH/H and TCH/F or different codecs are configured and
internal MNCC handler is used we might end up in a situation where call
legs with incompatible channel types or codecs would be connected
resulting in a broken audio.  Disconnect such calls with appropriate
error message.

Fixes: OS#1663
2016-04-29 13:10:00 +02:00
Max
35697b9a10 Adjust si2quater ranges
Change ranges of arguments for si2quater neighbor lists to proper values
according to 3GPP spec.
2016-04-29 12:57:53 +02:00
Max
299a999465 Fix comment typo 2016-04-29 12:57:53 +02:00
Neels Hofmeyr
0991c684d3 debug log for paging: add/tweak 2016-04-27 00:15:26 +02:00
Neels Hofmeyr
dc4b14b269 RAB: add debug log for PS RAB assignment 2016-04-25 19:24:30 +02:00
Neels Hofmeyr
687270de3a RAB parameters: apply use_x213_nsap parameter addition
Add use_x213_nsap parameter to iu_rab_act_ps(), pass the new parameter
from two callers as 1 such that there is no functional change.
2016-04-25 19:24:30 +02:00
Neels Hofmeyr
96f88fda06 paging_signal_data: remove unused lac member 2016-04-25 19:24:30 +02:00
Neels Hofmeyr
2ae1f5b7e0 paging response: remove extraneous null check, assert conn and msg further up
In handle_paging_response(), don't check conn against NULL after using it all
the time anyway.

To ensure beyond doubt that it is actually never NULL, assert conn further up
in the call stack, i.e. in gsm0408_dispatch(), the main entry point for
receiving data from the BSC/RNC level. Also assert msg while at it.

Fixes: CID#93769
2016-04-25 19:24:30 +02:00
Max
e01f5050ef Add missing include 2016-04-23 18:12:01 +02:00
Max
8db12e4263 Add extra debug output with channel mode and type
This provides helpful information for debugging internal MNCC handler.
2016-04-22 15:53:51 +02:00
Max
aafff96c40 Add vty check for max si2quater size
Explicitly check if added (U|E)ARFCN will fit into available si2quater
message.
2016-04-22 14:56:06 +02:00
Max
26679e0475 Add basic UARFCN support
* add data structures, generation functions
* vty interface for neightbor UARFCNs specific to SI2quater
* vty test
* unit test

Fixes: OS#1666
2016-04-22 14:55:33 +02:00
Max
27c3e76aa7 Cleanup shared data structure
* remove unused variable.
* lower max number of (e|u)arfcns to more realistic value.
2016-04-22 14:54:39 +02:00
Max
0c1bc26b64 Fix earfcn deletion
* fix typo in arg index
* fix sign in error reporting
* add vty test
2016-04-22 14:50:42 +02:00
Max
36212f2850 Fix documentation for command parameters 2016-04-22 14:50:29 +02:00
Neels Hofmeyr
63b99ced83 add preliminary paging response handling, incomplete
In gsm_04_08.c, add a static handle_paging_resp() to take over from the libbsc
function gsm48_handle_paging_resp(). Use the subscr->requests listing to handle
a Paging Response and call the pending cbfn.

In NITB, this used to be done via BTS, and I haven't entirely resolved yet how
exactly to rewire this in standalone libmsc. So far, this "works for me", but
is worth another visit.

Still missing: enable Integrity Protection.
2016-04-20 11:30:14 +02:00
Neels Hofmeyr
0b8e6dd2df gsm_04_08.c: fix security mode cmd: use auth tuple from MM auth 2016-04-20 11:23:00 +02:00
Neels Hofmeyr
9f2eaf8f56 cosmetic: auth tuple memcpy: rather use target's sizeof() 2016-04-20 11:23:00 +02:00
Neels Hofmeyr
afce55a4bc tweak tmp_rand[] type to avoid compiler warnings 2016-04-20 11:23:00 +02:00
Neels Hofmeyr
f3a1ca5d04 gprs_gmm.c: include openssl/rand.h against RAND_bytes() compiler warning 2016-04-20 11:23:00 +02:00
Neels Hofmeyr
c7fcdeb18e IuCS auth: generate auth tuples, factor out
Factor out hardcoded-Ki and auth tuple creation into a static function.

Add generation of fresh random bytes and generate a valid auth tuple so that
the authentication token is different for every MM Auth.
2016-04-20 11:23:00 +02:00
Neels Hofmeyr
3aa8b30bb3 cscn: enable SMS queue (by removing an '#if 0') 2016-04-20 11:22:59 +02:00
Neels Hofmeyr
208250558f cscn: enable 'subscriber' vty commands for libmsc
This involves removing the openbsc_vty_print_statistics() from
vty_interface_layer3.c, as this would link across the MSC/BSC border.
2016-04-20 11:22:59 +02:00
Neels Hofmeyr
bdb3f26668 cn_ranap_handle_co: add error rc and logging for PR Outcome 2016-04-20 11:22:59 +02:00
Neels Hofmeyr
69d3c26e43 cosmetic: debug and error logging, comment tweaks 2016-04-20 11:22:59 +02:00
Neels Hofmeyr
3f18cfce85 cscn: don't redefine talloc_asn1_ctx from iu.c 2016-04-20 11:22:59 +02:00
Neels Hofmeyr
658d1c3e14 IuCS: more detailed debug log upon IuCS rx 2016-04-20 11:22:59 +02:00
Neels Hofmeyr
6d1df9ad96 Add Iu paging
Add iu_page_cs() and iu_page_ps() API, also add to libiudummy for linking in
tests.

Implement msc_paging_request() by calling iu_page_cs().
2016-04-20 11:22:59 +02:00
Neels Hofmeyr
9bc1ddc849 iu.c: add registry of RNC-Ids in LACs
Introduce struct gsm_rnc, stored in a global list, static to iu.c.
(This list is not part of gsm_network so that the code can be
used from both MSC and GPRS code, i.e. both for CS and PS.)

Parse RANAP Global RNC Id, add GSM flags to build for gsm48_mcc_mnc_from_bcd()
to decode the PLMN Id.

Upon every Initial UE message, record/verify RNC Id and LAC for that
connection. In case of mismatch, so far just log an error.
2016-04-20 11:22:59 +02:00
Neels Hofmeyr
90e2c751e9 iu.c: introduce talloc_iu_ctx
Introduce talloc_iu_ctx, setup during iu_init() as child of the talloc_ctx
passed in by the caller.

Allocate ue_conn_ctx from talloc_iu_ctx, used to be from NULL.

Allocate osmo_sua_user and talloc_asn1_ctx from talloc_iu_ctx, used to be from
the ctx passed in by iu_init() caller.
2016-04-19 22:51:38 +02:00
Neels Hofmeyr
15f6c9f1e8 cosmetic: comment, whitespace 2016-04-19 22:27:32 +02:00
Neels Hofmeyr
5d5a25bc5a iu.h: add iu_link_del() 2016-04-19 22:24:47 +02:00
Neels Hofmeyr
95c9f29634 Iu RANAP event: add IU_EVENT_LINK_INVALIDATED
See in-code comment...
2016-04-19 22:11:39 +02:00
Daniel Willmann
30753e4a28 libmsc: Pass KeyStatus to iu_tx_sec_mode_cmd 2016-04-19 20:05:55 +02:00
Daniel Willmann
8fe0feb21b gprs: Activate RABs from RoutingArea update request as well 2016-04-19 20:05:18 +02:00
Daniel Willmann
444a516f18 gprs: Keep track of key negotiation and set the key status flag in sec_mod_cmd 2016-04-19 20:04:00 +02:00
Holger Hans Peter Freyther
3a434f8e8c nat/ussd: Add an example of the USSD gateway side-channel
This adds a very basic, use once example in python on how to connect
and deal with the app specific payload and messages. The code is not
complete as the invokeId should be patched according to the initial
invoke. This excercise is left to future readers of that code.
2016-04-16 15:56:13 -04:00
Holger Hans Peter Freyther
e43f8e0400 nat/vty: Do not print token update statement
On start this would print one line per BSC and this doesn't add
a lot of value. Let's just remove this logging message.
2016-04-16 15:56:13 -04:00
Max
59a1bf3dae Add basic SI2quater support
* support for sending arbitrary static SI2quater.
* vty interface for neightbor EARFCNs specific to SI2quater.
* dynamic generation of SI2quater messages.
* unit test for SI2quater messages.

Fixes: OS#1630
2016-04-16 13:47:56 +02:00
Max
5fa7e36bbc Refactor SI-related code
Move define to header file.
Use inline functions where appropriate.
Change int variables which are used as boolean into actual bool to make
code easier to follow.
2016-04-16 13:47:56 +02:00
Max
f3f3505f49 Add SI2quater support to SI3
Advertise SI2 quater presence and location (if available) using SI3
according to 3GPP TS 44.018 § 10.5.2.34
2016-04-16 13:47:52 +02:00
Neels Hofmeyr
c9ac20ea43 gbproxy_test: assert msg allocation (CID #57873) 2016-04-16 13:33:22 +02:00
Neels Hofmeyr
a6e81a0986 bsc_nat: forward_sccp_to_msc(): assert con presence (CID #57872) 2016-04-16 13:33:21 +02:00
Neels Hofmeyr
312bf6ce8b gtphub_unmap_header_tei(): don't dereference unmapped_tei arg if not present (CID #57687) 2016-04-16 13:33:14 +02:00
Holger Hans Peter Freyther
8bb6204d50 nat/vty: Fix construct not working with python 2.6
Use the simpler approach and just call encode('hex') on the str and
then convert it to lower case to keep the tests working.

reproduce:

Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> d = '\0\0'
>>> d
'\x00\x00'
>>> "".join("{:02x}".format(ord(c)) for c in d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <genexpr>
ValueError: zero length field name in format

fixes:

======================================================================
ERROR: testBSCreload (__main__.TestVTYNAT)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./vty_test_runner.py", line 658, in testBSCreload
    b0 = nat_bsc_sock_test(0, "lol")
  File "./vty_test_runner.py", line 1150, in nat_bsc_sock_test
    ipa_handle_small(bsc, verbose)
  File "./vty_test_runner.py", line 1116, in ipa_handle_small
    s = data2str(x.recv(4))
  File "./vty_test_runner.py", line 1100, in data2str
    return "".join("{:02x}".format(ord(c)) for c in d)
  File "./vty_test_runner.py", line 1100, in <genexpr>
    return "".join("{:02x}".format(ord(c)) for c in d)
ValueError: zero length field name in format

----------------------------------------------------------------------
2016-04-14 21:40:04 -04:00
Holger Hans Peter Freyther
2abf2b072d nat/vty: Remove second assumption about lo and binding
If we want to separate the BSCs we should separate based on
the source port and not the source ip (at least in the current
test setup).

Fixes:
======================================================================
ERROR: testBSCreload (__main__.TestVTYNAT)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./vty_test_runner.py", line 658, in testBSCreload
    b0 = nat_bsc_sock_test(0, "lol")
  File "./vty_test_runner.py", line 1145, in nat_bsc_sock_test
    bsc.bind(('127.0.0.1' + str(nr), 0))
  File "<string>", line 1, in bind
error: [Errno 99] Cannot assign requested address

----------------------------------------------------------------------
2016-04-14 21:13:51 -04:00
Holger Hans Peter Freyther
e98c9c7136 nat/vty: And move to a different port.. 2016-04-14 10:58:58 -04:00
Holger Hans Peter Freyther
84ae27e731 nat/vty: Convert into str for the VTY command
======================================================================
ERROR: testBSCreload (__main__.TestVTYNAT)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./vty_test_runner.py", line 656, in testBSCreload
    nat_msc_ip(self, ip, port)
  File "./vty_test_runner.py", line 1096, in nat_msc_ip
    x.vty.command("msc port " + port)
TypeError: cannot concatenate 'str' and 'int' objects

----------------------------------------------------------------------
2016-04-14 10:40:06 -04:00
Holger Hans Peter Freyther
44ed4979c9 nat/vty: Use different port for the mock MSC
Update the comment to reflect that the NAT itself will bind to port
5000 and then the mock MSC will fail to bind to it. Try to move the
mock MSC to another port.

Could fix:

======================================================================
ERROR: testBSCreload (__main__.TestVTYNAT)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./vty_test_runner.py", line 654, in testBSCreload
    msc = nat_msc_test(self, ip)
  File "./vty_test_runner.py", line 1101, in nat_msc_test
    msc.bind((ip, 5000))
  File "<string>", line 1, in bind
error: [Errno 98] Address already in use

----------------------------------------------------------------------
2016-04-14 10:05:13 -04:00
Holger Hans Peter Freyther
f1a61bb99f nat/vty: Don't assume one can magically add IPv4 addresses to lo
Don't assume that one can just bind to a local address that has
not been configured. Remove the unspecific comment as I don't know
to which other tests it is referred to.

This should fix:
======================================================================
ERROR: testBSCreload (__main__.TestVTYNAT)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./vty_test_runner.py", line 655, in testBSCreload
    msc = nat_msc_test(self, ip)
  File "./vty_test_runner.py", line 1102, in nat_msc_test
    msc.bind((ip, 5000))
  File "<string>", line 1, in bind
error: [Errno 99] Cannot assign requested address

----------------------------------------------------------------------
2016-04-14 08:51:57 -04:00
Max
4936448761 NAT: reload BSCs config dynamically
Add vty tests for BSC configuration reloading.
Load BSCs configuration on bscs-config-file command:
* remove all runtime configured BSC not in the config file
* close connections to all BSC with updated token value

Fixes: OS#1670
Sponsored-by: On-Waves ehf
2016-04-14 08:37:34 -04:00
Max
82f5ecde6a NAT: move BSC config into separate file
Introduce new configuration option bscs-config-file which includes BSC
configuration from the given file. Both absolute and relative (to the
main config file) paths are supported.
Add 'show bscs-config' command to display current BSC configuration.
Note: it is still possible to have BSC configuration in the main
file (provided proper index number is used) and in runtime but BSC
configuration is no longer saved automatically. The management of
included configuration file is left to external tools.
Update configuration examples.

Fixes: OS#1669
Sponsored-by: On-Waves ehf
2016-04-14 08:34:49 -04:00
Max
70cf7290da vty_test_runner: update ipa sending code
Factor out 2, add 3 functions. Those functions are simple wrappers
around hex strings specific to IPA protocol. Not all of them are
utilized at the moment but they were checked with wireshark while
working on the tests. It might come in handy if we'd like to further
expand related test harness in future. The same goes for optional
verbosity argument which is not used right now but will be handy for
future debugging.
2016-04-14 08:33:47 -04:00
Holger Hans Peter Freyther
a47b401990 jenkins: Add the build script from jenkins here
This can be used to replicate a build issue more easily.
2016-04-13 19:03:38 -04:00
Max
714b170f89 NAT: allow allocating BSC in arbitrary order
Check for existing BSC before allocating new one.
Track number of remaining BSCs on deallocation.
Explicitly use BSC number in allocation function.
2016-04-12 10:15:02 -04:00
Max
7a301d3576 Remove trivial wrapper function
Rename gsm48_tx_chan_mode_modify() to gsm48_lchan_modify() and remove
corresponding wrapper code.
2016-04-12 10:13:57 -04:00
Max
f220b52df3 NAT: extend debug output for ipaccess errors 2016-04-12 10:13:07 -04:00
Max
e5686f21d6 NAT: vty command to display number of BSCs
Add command 'show nat num-bscs-configured' to display number of configured BSCs.

Sponsored-by: On-Waves ehf
2016-04-12 10:12:36 -04:00
Daniel Willmann
0f3bce4aef gprs: Change auth key for every new Iu connection 2016-04-12 12:11:59 +02:00
Neels Hofmeyr
edafdc14f3 cscn: record and use LAC on incoming InitialUE msg
Add lac argument to gsm0408_rcvmsg_iucs(), to record the LAC in newly
allocated gsm_subscriber_connections.

In effect, fix the LAC sent to UE during Location Updating Accept message.
Before, 0 was stored as LAC and sent to the UE, regardless of the actual
LAC in use.
2016-04-11 20:45:32 +02:00
Neels Hofmeyr
54fc3a1318 remove subscr_conn_allocate_iu() from public header
It is only used statically in iu.c
2016-04-11 20:37:12 +02:00
Neels Hofmeyr
baefda5d64 add osmo-cscn.cfg example
Include a cscn section with subscriber-create-on-demand even though that is
the default.
2016-04-11 20:37:12 +02:00
Neels Hofmeyr
8dfe9690c5 iu.c: check return value of ranap_parse_lai() 2016-04-11 20:37:12 +02:00
Max
687f048ab0 Fix segfault with broken config
Fixes OS#1691
2016-04-11 10:22:55 +02:00
Daniel Willmann
fafb074268 sgsn: Reset mm ctx state in service request and after authorization 2016-04-08 18:04:04 +02:00
Daniel Willmann
a3dfdcb308 sgsn: Don't send the pdp context accept every time the RAB activates 2016-04-08 18:04:04 +02:00
Daniel Willmann
bae2594424 gprs: Save integrity protection status inside ue ctx, not mm ctx 2016-04-08 18:04:04 +02:00
Daniel Willmann
5e007d9445 gprs: Use different RAB IDs for activation 2016-04-08 12:14:56 +02:00
Daniel Willmann
42024336fe sgsn: Pass RAB ID to iu_rab_act_ps() function 2016-04-08 12:11:35 +02:00
Holger Hans Peter Freyther
9bcb1a56cb ctrl: Extend ctrl command to optionally handle alg+ki
Extend the existing ctrl command to be able to specify the
algorithm and Ki. In contrast to the VTY no size check is
done. Together with the VTY this code only supports a small
part of what is supported by libosmocore.

The algorithm and ki are considered optional but if a valid
algorithm other than "none" is passed, a KI must be passed as
well.

Extend the test coverage by passing the potential values. It
is not verified that the KI/algorithm is stored.
2016-04-07 09:27:07 +02:00
Holger Hans Peter Freyther
adb86759da db: If creating a subscriber in the db fails, return NULL
We should not return a subscriber in case it was not written to
the database. Instead free the memory allocated and return NULL.
Callers in gsm_04_08.c are prepared to have the creation fail.

Related: OS Issue #1657
2016-04-06 21:21:24 +02:00
Holger Hans Peter Freyther
2826df56b2 subscr: Make db_create_subscriber fail on duplicates
The issue of db_create_subscriber updating an already existing subscr
is that the same subscriber will then have two entries in the active
subscribers list. In general this will break assumptions that a subscr
can be compared by comparing the pointer.

In the case of the VTY this was not an issue as the created subscr
was immediately destroyed again but it is better to avoid this problem.

Change the VTY command to find the subscriber and then call sync to
have the updated time set. The side-effect is we will now have two
queries for the subscriber. Once through subscr_get_by_imsi and once
through db_create_subscriber.

Change the db_create_subscriber to fail if a subscriber already exists,
and add a testcase for this behavior and do not updated the 'updated'
timestamp of an already existing subscriber.

Add a testcase for this behavior.

Related: OS Issue #1657
2016-04-06 21:19:53 +02:00
Holger Hans Peter Freyther
de392254ff subscr: Add testcase creating an already created subscriber
Add testcase to issue the subscriber create twice. db_create_subscriber
in db.c will first try to find the subscriber and if it exists, it will
update the "updated" column in the database.

Related: OS Issue #1657
2016-04-06 21:18:36 +02:00
Max
7dd2eed6d3 Ignore vty test byproducts 2016-04-05 22:34:54 +02:00
Neels Hofmeyr
bb81326719 vty l3 help: fix typo 'comamnds'; fix english s/his// 2016-04-05 12:06:35 +02:00
Holger Hans Peter Freyther
c6a65511f3 bsc: Add parameter to restart a bts
The ip.access nanoBTS seems to have severe issues with BSSGP when
changing the country code and/or network code. It is unlikely that
the proprietary code is getting fixed so we extend the parameter
for the apply-configuration command to carry the 'restart' param.
2016-04-01 19:34:42 +02:00
Holger Hans Peter Freyther
740e65fb7b bsc: Add code to send ip.access reboot command to nanoBTS
The nanoBTS continues to be buggy and seems to have broken BSSGP
when changing SIs across new OML connections. Add an easy command
to force the reboot of the system through OML.
2016-04-01 19:34:42 +02:00
Holger Hans Peter Freyther
3a38ee6c3d abis: Send the message without enforcing to wait for a response
The user might issue restarts while no BTS is connected and we
should not block the abis queue because of these messages.
2016-04-01 19:34:42 +02:00
Neels Hofmeyr
276192d27c cosmetic: comments, debug log, msgb alloc name 2016-03-31 16:15:18 +02:00
Neels Hofmeyr
c4b9b4edbb mscsplit: rewire MSC gsm0808_submit_dtap() to msc_tx_dtap() 2016-03-31 16:15:18 +02:00
Neels Hofmeyr
b70dfa610d Merge branch 'master' into sysmocom/iu
Conflicts:
	openbsc/src/libmsc/auth.c
	openbsc/src/libmsc/gsm_04_08.c
	openbsc/src/osmo-bsc/osmo_bsc_vty.c
	openbsc/tests/Makefile.am
2016-03-31 16:14:13 +02:00
Neels Hofmeyr
cf1302e4cb Fix MM Auth: zero-initialize auth tuple before first use
Make sure a new auth tuple is initialized after
db_get_lastauthtuple_for_subscr() returns an error, i.e. if no tuple is present
for the subscriber yet.

Before this patch, the first key_seq depended on the typically uninitialized
value that was present in auth tuple's key_seq upon calling
auth_get_tuple_for_subscr().

The very first key_seq used for a new subscriber will now always be 0. Before,
it used to be mostly 1 ("(0 + 1) % 7"), but depended on whether the key_seq was
indeed initialized with 0, actually by random.
2016-03-31 11:56:49 +02:00
Neels Hofmeyr
0d929be826 Fix MM Auth: disallow key_seq mismatch
In auth_get_tuple_for_subscr(), add missing condition to match incoming
key_seq with stored key_seq, so that re-authentication is requested for
mismatching key_seqs.

Add test for this issue.
2016-03-31 11:56:48 +02:00
Neels Hofmeyr
4e875aec0f MM Auth: return AUTH_NOT_AVAIL instead of hardcoded zero
AUTH_NOT_AVAIL == 0, so this is no functional change.
2016-03-31 11:56:47 +02:00
Neels Hofmeyr
f9b212fabd MM Auth: introduce AUTH_ERROR constant.
Instead of using hardcoded -1 for errors, include -1 in the enum auth_action
type; apply its use.

In the mm_auth test, the string output changes from '(internal error)' to
'AUTH_ERROR', since now the proper enum value is used in auth_action_names[].
2016-03-31 11:56:29 +02:00
Neels Hofmeyr
d617c5d3ac MM Auth test: add test to re-use existing auth 2016-03-31 11:56:21 +02:00
Neels Hofmeyr
4554a62c4d MM Auth test: add two tests for AUTH_THEN_CIPH
Test two situations for AUTH_DO_AUTH_THEN_CIPH:
- when no auth tuple is available
- when the key sequence from LU is marked invalid

Add convenience auth tuple comparison function using stringification.
2016-03-31 11:56:14 +02:00
Neels Hofmeyr
37984bdb1b Add MM Auth test; add auth_action_str() function
Add basic MM Authentication test setup, with fake DB access and RAND_bytes().

So far implement simple tests for IO error during DB access and missing auth
entry.

To print the auth action during tests, add struct auth_action_names and
auth_action_str() inline function in auth.[hc].
2016-03-31 11:56:00 +02:00
Neels Hofmeyr
56ea30ff3f osmo-bsc: fix compiler warning: store struct in vty->index
Don't store an MSC index number in the vty->index void* value. Instead,
store the osmo_msc_data struct directly. Thus avoid warnings about
differences in int vs void* sizes, and save some index lookups.
2016-03-27 10:48:14 +02:00
Neels Hofmeyr
4b940126a3 comments about incomplete MM ciphering 2016-03-22 19:55:45 +01:00
Neels Hofmeyr
debb0e3868 cscn: implement integrity protection
Upon authentication response, initiate integrity protection for Iu by sending a
Security Mode Command (IK), with hardcoded auth tuple so far.

Implement RANAP event handling to receive Security Mode Complete message,
adding stubs for the other events; in new files osmo-cscn/iucs_ranap.[hc] to
keep RANAP dependencies separate, and particularly out of libmsc.

Upon receiving Security Mode Complete, call the security operation callback
(conn->sec_operation->cb) to complete the Location Update.

Introduce enum integrity_protection_state constants to indicate integrity
protection, record in gsm_subscriber_conn.iu.integrity_protection.

Make subscr_conn_lookup_iu() non-static and declare in iu_cs.h to be able to
call from iucs_ranap.c's Security Mode Complete event.

Implement dummy iu_tx_sec_mode_cmd() to allow tests to build without RANAP
dependencies.

In cscn_main.c, call iucs_rx_ranap_event(), to populate the struct gsm_network
struct with cscn_network explicitly (don't share cscn_network across
compilation scopes because it's ugly).
2016-03-22 19:54:09 +01:00
Neels Hofmeyr
d025a3cfbb in gsm8_rx_mm_auth_resp(): call sec_operation.cb() instead of finish_lu() directly 2016-03-22 19:53:36 +01:00
Neels Hofmeyr
4b3b13e10c fix various compiler warnings
sgsn_libgtp.c: missing include, for asn1str_to_u32()

iu_cs.c: missing include, for subscr_name()

osmo_bsc_vty.c: int/pointer conversions
(note: this was discussed on the list to be solved by passing a pointer
instead. Until then...)

iudummy.c: opaque struct declarations
2016-03-22 19:28:06 +01:00
Neels Hofmeyr
fa48a98e71 gsm0408_authorize(): remove unused msgb arg, make non-static
Prepares for calling from IuCS RANAP events.
2016-03-22 01:13:07 +01:00
Neels Hofmeyr
9fd87ecd11 iu_tx_sec_mode_cmd(): add send_ck flag parameter
In this way the caller can distinguish between sending an IK or an IK+CK
Security Mode Command.
2016-03-22 01:13:07 +01:00
Neels Hofmeyr
8e5c63f032 cosmetic: whitespace, comment, rename static func rx_iu_event() 2016-03-22 01:12:26 +01:00
Neels Hofmeyr
2cd36e87ae fix build: match Iu event cb enum argument type from declaration 2016-03-22 01:07:20 +01:00
Neels Hofmeyr
0bc6c11cbf debug log fixes
gprs_gmm.c: remove extraneous debug print arg.
iu_cs.c: increment should not be in debug statement.

Fixes at least one coverity warning.
2016-03-21 11:56:28 +01:00
Neels Hofmeyr
182adecb98 debug: log list of subscribers upon lookup 2016-03-18 15:57:42 +01:00
Neels Hofmeyr
3d0a500f2d iu.c: log conn_id on outgoing messages 2016-03-18 15:57:42 +01:00
Neels Hofmeyr
a5c9cea22c logging: add DSUA to default_categories[] 2016-03-18 15:57:42 +01:00
Neels Hofmeyr
f45dc35321 logging: add DRANAP to default_categories 2016-03-18 15:57:42 +01:00
Neels Hofmeyr
2f6c4b6479 IuCS: fix logical flip in same_ue_conn() 2016-03-18 15:57:42 +01:00
Neels Hofmeyr
2385074cba fix build: iu.h: remove iu_rab_act_ps()'s rab_id parameter
Error was introduced in d04db9d907
'libiu: Replace RAB assignment response callback with a general one'

For iu_rab_act_ps(), the rab_id parameter was added in iu.h but not in the
implementation, nor for the callers. Make the iu.h signature match the
implementation, again.
2016-03-18 15:57:42 +01:00
Daniel Willmann
d8b0b61ca8 gprs_gmm: Call gsm48_gmm_authorize from RA upd request
In Iu mode the RA upd request can be called from a new Iu connection so we
might need to reauthenticate the connection as well as turn on integrity
protection.
2016-03-18 14:08:14 +01:00
Daniel Willmann
19f0735752 cscn: Follow libiu move to generic event handler 2016-03-18 14:00:03 +01:00
Daniel Willmann
ffd9968d3a libiu: Change gprs_transp_upd_key to be useful for CS as well
gprs_transp_upd_key only sends a security mode command which is needed for CS
as well so change it.

Make sure it is called after the UE is authenticated in Iu mode.
2016-03-18 13:58:20 +01:00
Harald Welte
3ad0346f00 Revert "move to hex TMSI representation"
This reverts commit 044fbe6568.
2016-03-17 14:42:24 +01:00
Vadim Yanitskiy
044fbe6568 move to hex TMSI representation
In OpenBSC, we traditionally displayed a TMSI in its integer
representation, which is quite unusual in the telecom world.  A TMSI is
normally printed as a series of 8 hex digits.

This patch aligns OpenBSC with the telecom industry standard.

Signed-off-by: Vadim Yanitskiy <axilirator@gmail.com>
2016-03-17 14:15:16 +01:00
Neels Hofmeyr
d2fa7a509a fix confusing typo in constant (THAN -> THEN) 2016-03-17 14:15:16 +01:00
Daniel Willmann
deb227b98e gprs_gmm: Fix RA UPD handling for IU mode 2016-03-16 18:39:52 +01:00
Daniel Willmann
5e611021b0 Move event callback to gprs_gmm 2016-03-16 18:38:58 +01:00
Holger Hans Peter Freyther
f4afcf0b23 mgcp: Fix compiler warnings on size_t on AMD64
mgcp_transcode.c: In function 'decode_audio':
mgcp_transcode.c:332:4: warning: format '%d' expects argument of type 'int', but argument 7 has type 'size_t' [-Wformat=]
    LOGP(DMGCP, LOGL_ERROR,
    ^
mgcp_transcode.c:332:4: warning: format '%d' expects argument of type 'int', but argument 8 has type 'long unsigned int' [-Wformat=]
mgcp_transcode.c: In function 'encode_audio':
mgcp_transcode.c:390:4: warning: format '%d' expects argument of type 'int', but argument 7 has type 'size_t' [-Wformat=]
    LOGP(DMGCP, LOGL_INFO,
    ^
mgcp_transcode.c:390:4: warning: format '%d' expects argument of type 'int', but argument 8 has type 'size_t' [-Wformat=]
mgcp_transcode.c: In function 'mgcp_transcoding_process_rtp':
mgcp_transcode.c:542:5: warning: format '%d' expects argument of type 'int', but argument 9 has type 'size_t' [-Wformat=]
     LOGP(DMGCP, LOGL_NOTICE,
     ^
mgcp_transcode.c:571:4: warning: format '%d' expects argument of type 'int', but argument 7 has type 'size_t' [-Wformat=]
    LOGP(DMGCP, LOGL_NOTICE,
    ^
2016-03-16 11:16:06 +01:00
Daniel Willmann
d04db9d907 libiu: Replace RAB assignment response callback with a general one
The new iu event callback will now be called for RAB assignment response, IU
release and security mode complete
2016-03-16 10:35:09 +01:00
Neels Hofmeyr
10cd11345c bsc_scan_msc_msg: check protocol discriminator
The function assumed an MM protocol discriminator without verifying it.
2016-03-15 14:26:00 +01:00
Holger Hans Peter Freyther
8c515272c3 meas: Do not retry to close the database
There is no concurrency involved and if it failed the first time,
it will fail the second, third, ... time as well. Simply print that
we will leak the database instance.
2016-03-15 14:22:57 +01:00
Neels Hofmeyr
961bd0b121 04.08: apply new transaction id inline functions
libosmocore recently added inline functions to relieve callers from applying
bitmasks and bit shifts to access the transaction id of a GSM 04.08 header.
Apply these functions.
2016-03-15 14:18:52 +01:00
Neels Hofmeyr
531734a547 04.08: apply new bitmask functions, fix bitmask use
Replace hardcoded protocol discriminator and message type bitmasks with
function calls recently introduced in libosmocore.

Note that the release 98 bitmasks slightly differ from the release 99 bitmasks.
This patch uses the "default" gsm48_hdr_msg_type invocation, thus it depends on
libosmocore whether 98 or 99 bitmasks are used.

In some places, use of the bitmask was erratic. Fix these implicitly by
employing the bitmask functions:

 * silent_call.c: silent_call_reroute(): add missing bitmask for MM.
 * bsc_msg_filter.c: bsc_msg_filter_initial(): RR vs. MM messages.
 * osmo_bsc_filter.c: bsc_find_msc() and bsc_scan_bts_msg(): RR vs. MM
   messages.
 * bsc_nat_rewrite.c: bsc_nat_rewrite_msg(): SMS vs. CC messages.
 * bsc_ussd.c: no bitmask is applicable for the message types used here.
 * gb_proxy.c: gbproxy_imsi_acquisition(): missing bit mask for pdisc.

In gprs_gb_parse.c: gprs_gb_parse_dtap(), add a log notice for unexpected
message types.
2016-03-15 14:15:00 +01:00
Neels Hofmeyr
3c94c2c597 bsc_scan_msc_msg: check protocol discriminator
The function assumed an MM protocol discriminator without verifying it.
2016-03-15 13:14:56 +01:00
Neels Hofmeyr
372a3bd346 04.08: apply new transaction id inline functions
libosmocore recently added inline functions to relieve callers from applying
bitmasks and bit shifts to access the transaction id of a GSM 04.08 header.
Apply these functions.
2016-03-15 13:14:19 +01:00
Neels Hofmeyr
51bf76ef47 04.08: apply new bitmask functions, fix bitmask use
Replace hardcoded protocol discriminator and message type bitmasks with
function calls recently introduced in libosmocore.

Note that the release 98 bitmasks slightly differ from the release 99 bitmasks.
This patch uses the "default" gsm48_hdr_msg_type invocation, thus it depends on
libosmocore whether 98 or 99 bitmasks are used.

In some places, use of the bitmask was erratic. Fix these implicitly by
employing the bitmask functions:

 * silent_call.c: silent_call_reroute(): add missing bitmask for MM.
 * bsc_msg_filter.c: bsc_msg_filter_initial(): RR vs. MM messages.
 * osmo_bsc_filter.c: bsc_find_msc() and bsc_scan_bts_msg(): RR vs. MM
   messages.
 * bsc_nat_rewrite.c: bsc_nat_rewrite_msg(): SMS vs. CC messages.
 * bsc_ussd.c: no bitmask is applicable for the message types used here.
 * gb_proxy.c: gbproxy_imsi_acquisition(): missing bit mask for pdisc.

In gprs_gb_parse.c: gprs_gb_parse_dtap(), add a log notice for unexpected
message types.
2016-03-15 13:14:17 +01:00
Neels Hofmeyr
aa60582036 cosmetic: comments 2016-03-15 13:13:15 +01:00
Neels Hofmeyr
6b2623d944 cscn: fix VTY port: don't use SGSN's port number 2016-03-14 23:58:23 +01:00
Neels Hofmeyr
8b1272a6d3 msc: allow only authentication without ciphering
So far the code did only auth+ciph or none. Add case handling for only
authentication without ciphering (basically just fill in the blanks).
2016-03-14 23:58:23 +01:00
Neels Hofmeyr
080921a551 HACK: hardcode subscriber auth tuple for IuCS 2016-03-14 23:58:23 +01:00
Neels Hofmeyr
8e7f4c6f21 cosmetic 2016-03-14 23:58:23 +01:00
Neels Hofmeyr
4a9b871de5 Adjust authentication logic for Iu, move a log notice
Depending on conn->via_iface, fail upon missing auth for 3G.

Move the log notice saying "skipping auth" to gsm48_secure_channel() where
conn->via_iface is actually known.
2016-03-14 23:58:23 +01:00
Neels Hofmeyr
93f6fa5a81 spread a few debug logs around authentication 2016-03-14 23:58:23 +01:00
Neels Hofmeyr
f1777ee843 fix confusing typo in constant (THAN -> THEN) 2016-03-14 23:58:23 +01:00
Neels Hofmeyr
9e8e0e6a29 Remove unused auth code and add comment
As commented in the code, the GSM_SECURITY_AUTH_FAILED path is never invoked by
the gsm48_secure_channel() function as it is today.

Note that the upcoming Iu auth will probably add a GSM_SECURITY_AUTH_FAILED
status. In that case, sending a LU Reject immediately may be desirable, but
arguably a bit of timeout could make life harder for auth attackers.

The code removed by this patch doesn't send out a LU Reject ever, since a call
to release_loc_updating_req() only releases the connection. To reject, a call
to gsm0408_loc_upd_rej() would be necessary, as seen in loc_upd_rej_cb().

And finally, if _gsm0408_authorize_sec_cb() doesn't do anything about anything,
the same loc_upd_rej_cb() will be run by a timeout and send a LU Reject
properly (as commented in the code).
2016-03-14 23:58:23 +01:00
Neels Hofmeyr
cf3d2a1fad fix build: add xsc to osmo-bsc and tests/bsc-nat 2016-03-04 15:36:59 +01:00
Neels Hofmeyr
e4baf402cb move two gsm0480_send_*() to xsc as gsm0480_gen_*()
Have two separate gsm0480_send_ussdNotify() and gsm0480_send_releaseComplete()
for each of libbsc and libmsc. Move their core into libxsc as generator
functions returning a msgb.

Add src/libbsc/gsm_04_80_utils.c (note, not 04_08) to implement the libbsc
side of it.

The code is identical, but the linked structs and functions differ in each
case. There could be a common source file built for both, but I decided against
it, for more clarity I hope.
2016-03-04 15:34:18 +01:00
Neels Hofmeyr
53d782fc38 fix two minor Makefile.am errors 2016-03-04 15:27:48 +01:00
Neels Hofmeyr
33a343858d move sms_next_rp_msg_ref() to libxsc, for gsm0408test
Also change the signature to avoid using gsm_subscriber_connection, which
has different members in libbsc and libmsc.
2016-03-04 14:58:09 +01:00
Neels Hofmeyr
15b1fce69c rename nitb vty config to cscn, move to cscn_vty.c 2016-03-04 14:58:09 +01:00
Neels Hofmeyr
2f8117d214 disable code trying to reach across BSC/MSC bounds, make build pass
Disable ipacc_rtp_direct, Osmo SMPP TLVs, Ctrl interface and channel_test.
These need to be reimplemented with proper separation of libs.

Add some tall_* pointers the linker requires for osmo-cscn.
2016-03-04 14:58:09 +01:00
Neels Hofmeyr
8927bb46d5 libmsc: stubify paging (A-/Iu-interfaces need to reimplement this) 2016-03-04 14:57:59 +01:00
Neels Hofmeyr
d52b1c4342 add libmsc/a_iface.c for A-interface stubs (so far only mock) 2016-03-04 14:57:09 +01:00
Neels Hofmeyr
5d9004bc9b gsm_subscriber_connection: further split between BSC and MSC
Move some Iu/A members into the MSC #ifdef.

Have separate allocate and free functions for the two scopes.
2016-03-04 14:57:09 +01:00
Neels Hofmeyr
a4198d1922 create libxsc and move some code, never link libbsc and libmsc
libbsc and libmsc have conflicting definitions of gsm_subscriber_connection
and do no longer belong together anyway.

Create libxsc, meaning 'lib[bm]sc', to hold all code used by both libmsc
and libbsc, and make sure gsm_subscriber_connection isn't used there.

In various binaries and tests, do not link libbsc and libmsc.

(Note: this commit was reshaped out of a large wip chunk, it may not
compile properly without the subsequent commits)
2016-03-04 14:57:09 +01:00
Neels Hofmeyr
544a203f67 Remove osmo-nitb, cannot link libbsc with libmsc anymore 2016-03-03 16:19:12 +01:00
Neels Hofmeyr
b40df4c09e cscn: apply vty bind addr configuration 2016-03-03 16:19:12 +01:00
Neels Hofmeyr
5c1c0bad89 debug: set almost everything to LOGL_DEBUG for easier dev 2016-03-03 16:19:12 +01:00
Neels Hofmeyr
1e361301d1 cscn_main.c: fix ctrl init
Include control_vty.h so that ctrl_vty_get_bind_addr() is properly declared.
Add ctrl iface vty commands.
2016-03-03 16:19:12 +01:00
Neels Hofmeyr
9e8322ca0c wip: exclude more bsc stuff from gsm_subscriber_conn 2016-03-03 16:19:12 +01:00
Neels Hofmeyr
9bd121b75b cscn: minor dbg log tweak 2016-03-03 16:19:12 +01:00
Neels Hofmeyr
fa029f08c2 cscn: apply socket path / bind addr changes after rebase
After rebasing onto 1b0e5540db, some changes need to be applied to
cscn_main.c, originally a copy of bsc_hack.c before the rebase. On master,
configurable MNCC socket path and Control interface bind address were added.
2016-03-03 16:19:12 +01:00
Neels Hofmeyr
db9c064dd4 osmo-bsc: half-fix tz override to allow compilation
As described in a comment, for MSCSPLIT the tz data has been moved to network
level. To allow compiling osmo-bsc on the sysmocom-iu branch, move tz up to
network level in osmo-bsc as well.

This could be done better for osmo-bsc, rather easily too, still allowing
per-BTS timezone settings. But I'm trying to focus on IuCS and would like to
come back to this later.
2016-03-03 16:19:12 +01:00
Daniel Willmann
a0da2dbe9e WIP: gprs_gmm: Get mm ctx from RA update in Iu mode
Iu mode doesn't have tlli, so look up according to p-tmsi
2016-03-03 16:19:12 +01:00
Daniel Willmann
7df5705251 WIP: Try and activate RABs after service request 2016-03-03 16:19:12 +01:00
Daniel Willmann
da7424cc54 gprs_gmm: Log service request if not receieved from Iu mode 2016-03-03 16:19:11 +01:00
Daniel Willmann
8146cfa782 gprs_gmm: Send gmm_service_accept from gsm48_gmm_authorize() 2016-03-03 16:19:11 +01:00
Daniel Willmann
330898afb7 gprs: Update ue ctx from msg
In case a Iu connection is reconnected we need to update the ue ctx
2016-03-03 16:19:11 +01:00
Daniel Willmann
77544a65b5 sgsn_test: Fix mmctx llme and tlli struct names after merge 2016-03-03 16:19:11 +01:00
Daniel Willmann
4e5ddfa91a gprs_gmm: Fix mmctx tlli member rename after merge 2016-03-03 16:19:11 +01:00
Daniel Willmann
cba441f3de gprs: Handle GMM service request (Iu mode only)
Iu mode has a GMM service request message which a UE in PMM-IDLE mode
can use to switch back to PMM-CONNECTED mode.
2016-03-03 16:19:11 +01:00
Daniel Willmann
3acbc817f6 osmo-bsc: Pass gsmnet to bsc_vty_init() 2016-03-03 16:19:11 +01:00
Neels Hofmeyr
bcb98b1754 libmsc/smpp: disable lchan access for now
To make the IuCS build work, disable the BSC-land access from MSC's SMPP code.
Some way shall be found to make the Osmocom vendor-specific SMPP TLVs work over
the A-interface (after the MSCSPLIT), but we're concentrating on IuCS for now.
2016-03-03 16:19:11 +01:00
Daniel Willmann
2a7426d7cb libmsc: Don't use bts field of gsm_subscriber_connection
Use gsm_subscriber_connection does not have a bts field if building as
libmsc. Use network directly.
2016-03-03 16:19:11 +01:00
Daniel Willmann
b9bb2a4f54 sgsn: fix use of opaque RANAP_RAB_SetupOrModifiedItemIEs_s decl 2016-03-03 16:19:11 +01:00
Neels Hofmeyr
098c14800f cscn: fix use of opaque RANAP_RAB_SetupOrModifiedItemIEs_s decl 2016-03-03 16:19:11 +01:00
Neels Hofmeyr
a46c651a4a iu.h: fix opaque declaration of RANAP_RAB_SetupOrModifiedItemIEs_s
struct RANAP_RAB_SetupOrModifiedItemIEs_s; may be declared, but not the
corresponding typedef. It leads to a redefinition error in our coverity
build.
2016-03-03 16:19:11 +01:00
Daniel Willmann
4cc1f72cb7 Revert "iu.c: avoid warning by declaring ranap_free_rab_setupormodifieditemies()"
There should be no need to silence this warning, the ranap_free_*
functions are declared in libranap headers. In any case this will only
obscure any real issue. Maybe osmo-iuh was not rebuilt completely
(including generation of the c files from the python script).

This reverts commit 05ae5b1245f95bf765b42e49af7b2596e013f0a0.
2016-03-03 16:19:11 +01:00
Daniel Willmann
4f143e52b6 libiu: Use custom setupormodifieditemies function
The one generated by the python script doesn't really do what we want.
Instead of futzing around with the script again just write our own
version.
2016-03-03 16:19:11 +01:00
Daniel Willmann
e3407f8884 libiu: Indicate in log where we don't handle a specific message 2016-03-03 16:19:11 +01:00
Daniel Willmann
7d1b6b1c79 libui: Don't assume gsm_network and gsm_subscriber_conncetion in libiu
The sgsn uses other data structs so don't require them inside libiu.
Instead keep a private list of ue contexts and iterate through that.

This commit reverts the libui changes of commit
d03faa4bacd4d2a8b9155faf5219a948b73f481c
2016-03-03 16:19:11 +01:00
Neels Hofmeyr
656d7cd0b4 iu.c: avoid warning by declaring ranap_free_rab_setupormodifieditemies() 2016-03-03 16:19:11 +01:00
Neels Hofmeyr
553d2a8ceb add tests/libiudummy 2016-03-03 16:19:11 +01:00
Neels Hofmeyr
23f22b1183 msc: define extern iu_tx() 2016-03-03 16:19:11 +01:00
Neels Hofmeyr
090aabe052 gsm0408_rcvmsg_iucs: remove unused link_id arg. 2016-03-03 16:19:11 +01:00
Neels Hofmeyr
be37fbd85d msc: implicitly link to iu_tx, don't have callbacks.
This is more akin to the way openbsc do, as well as less code.
2016-03-03 16:19:11 +01:00
Daniel Willmann
3cc0836b1a gprs/sgsn: Use RAB assignment response cb in PDP context activation 2016-03-03 16:19:11 +01:00
Daniel Willmann
8cd32937da osmo-cscn: Add dummy function for RAB assignment response 2016-03-03 16:19:11 +01:00
Daniel Willmann
377a9f5dea libiu: Add support for RAB assignment response callback 2016-03-03 16:19:11 +01:00
Daniel Willmann
b8df4d5318 sgsn_libgtp: Update rab (de)act function names to libui version 2016-03-03 16:19:11 +01:00
Daniel Willmann
daa0652d3f sgsn_test: Make sgsn_test compile again after libui change 2016-03-03 16:19:11 +01:00
Daniel Willmann
f7436b22b3 sgsn_iu/libgtp: Update pdp context with new IP address after RAB assign
In the IU case the RNC and ggsn communicate directly on the user plane.
Since the IP address of the RNC is not known in our case (it sits behind
the hnbgw) we need to update the PDP context with the new IP address
after receiving the RAB assignment response (which includes the IP
address).
2016-03-03 16:19:11 +01:00
Daniel Willmann
711333c113 sgsn_iu: Parse the RAB assignemnt response and get pdp ctx form it
The RAB assignment response includes the gtp teid that we sent along in
the assignment request. Retrieve the correct pdp context from there and
activate it.
2016-03-03 16:19:10 +01:00
Daniel Willmann
91f04dfe3a sgsn: Add a function to return the pdp ctx for an mm ctx and tei 2016-03-03 16:19:10 +01:00
Daniel Willmann
4371ff8cce sgsn: Get gtp ip and teid from pdp context in gprs_iu_rab_act() 2016-03-03 16:19:10 +01:00
Daniel Willmann
92223cc32e gprs_gmm: Apply the auth hack only for UTRAN_Iu RAN type
Try to limit the effect 3G support has on the remaining code base. The
sgsn test still fails, but at a later test.
2016-03-03 16:19:10 +01:00
Daniel Willmann
2f5cc8abe0 tests/sgsn: Fix compilation of sgsn_test
The sgsn test still fails, but at least it is compiling again..
2016-03-03 16:19:10 +01:00
Daniel Willmann
ba47b525ff sgsn_libgtp: Use the address provided by the GGSN for RAB activation 2016-03-03 16:19:10 +01:00
Daniel Willmann
cf1707af7f gprs: Fix some misleading comments 2016-03-03 16:19:10 +01:00
Daniel Willmann
d6d0d8b86f WIP: Wait for radio bearer before sending pdp context accept 2016-03-03 16:19:10 +01:00
Daniel Willmann
38137e84f7 HACK: ranap_decode_rab_setupormodifieditemies crashes so disable it 2016-03-03 16:19:10 +01:00
Daniel Willmann
82724653e7 sgsn_iu: RABAssignment response is an Outcome, not a Successful one 2016-03-03 16:19:10 +01:00
Daniel Willmann
da8d9bc355 gprs_gmm: Fix bit mask when determining update/attach type
Bit 4 is reserved in 3GPP TS 04.08 so exclude it from the type.

In 3GPP TS 24.008 it indicates if a follow-on request is pending by the
MS, but only in Iu mode. According to the spec it is not required to
react to that request with a follow-on proceed so this field can be
ignored for now.

See 3GPP TS 24.008 Ch. 4.4:
"Unless it has specific permission from the network (follow-on proceed)
the mobile station side should await the release of the RR connection
used for a MM specific procedure before a new MM specific procedure or
MM connection establishment is started."

as well as Ch. 4.4.4.6:
"If the network wishes to prolong the RR connection to allow the mobile
station to initiate MM connection establishment (for example if the
mobile station has indicated in the LOCATION UPDATING REQUEST that it
has a follow-on request pending) the network shall send "follow on
proceed" in the LOCATION UPDATING ACCEPT and start timer T3255."
2016-03-03 16:19:10 +01:00
Neels Hofmeyr
c59e52a6aa doc: rename nitb graph to bsc, add msc graph
NITB is already gone from this branch. We may even resurrect it, but I prefer
to name the realms 'libmsc' and 'libbsc', hence the nitb graph is the BSC graph
now. Also add a libmsc graph.
2016-03-03 16:19:10 +01:00
Neels Hofmeyr
24c4af1d82 doc: add lists to nitb graph 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
f918920d65 cscn: use iu_tx for msc_ifaces.iu_cs. some #include cosmetics. 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
292f1ce533 mscsplit: fix compilation and comments. move msc_api.h. 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
23e7f28c5c mscsplit: getting grips on header scopes 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
243c7cb044 msc: clarify msc_api and msc_ifaces scopes 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
cf2591f6fc rename IFACE_IUCS to IFACE_IU 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
6a2d8985bf cscn: rename msc_api 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
c6794eed1d cscn: some file moves/renames 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
7a70a4f52a cscn wip: direct dtap responses to IuCS 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
c6172a320b cscn: fix missing network backpointer 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
5280ed558c cscn: own talloc root and gsm_network instance; misc.
Heading towards a sovereign CSCN.
2016-03-03 16:19:10 +01:00
Neels Hofmeyr
b36b910366 mscsplit: exclude some more vty nodes 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
b47e52c958 cosmetic: remove unused extern. 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
267f6c7e0d introduce vty CSCN_NODE, cosmetically. 2016-03-03 16:19:10 +01:00
Neels Hofmeyr
5e47b1a1d3 mscplit: try to clarify root talloc ctx and global gsm_network.
The aim is to allow osmo-cscn to pass its own root talloc context and
global gsm_network struct instance cleanly. This may stir up some old and
dusty globals, but I hope it's for the better, since not all is a BSC.

To ensure that a global gsm_network pointer for the bsc_vty is set, have it as
argument to bsc_vty_init(). The vty configuration commands are added only after
bsc_vty_init(), which are needed to configure the network struct. So split up
the bsc_bootstrap_network() function into bsc_network_init() to allocate a
gsm_struct, and bsc_network_configure() to read the config file once the vty
commands are in place. In this way, no global bsc_gsmnet pointer is needed for
the bsc vty. The atomic super glue is dissolved and osmo-cscn will be allowed
to have a different name for it.

Admitted, it's still called the bsc_vty, but a split thereof is probably coming
soon, because the CSCN doesn't want any of the BSC nor BTS specific vty
commands.
2016-03-03 16:19:09 +01:00
Neels Hofmeyr
b9e5403ef4 mscsplit: remove bts and lchan pointers from libmsc
The diff between this and master will probably need a lot of review and fixes.
The current state does compile, but I expect pretty much everything to be
broken now. Future development will reinstate proper functionality piecemeal.

The first goal is to get basic signalling to work, then SMS. The voice control
(RTP) is completely disabled now (see "#if BEFORE_MSCSPLIT") and will be fixed
last AFAICT.
2016-03-03 16:19:09 +01:00
Neels Hofmeyr
b6769b99de cosmetics: link_id=42, s/Iu-CS/IuCS, debug logs.
Until I get the proper link id from the SUA SAP, make sure we recognise it
as hardcoded by setting it to 42.
2016-03-03 16:19:09 +01:00
Neels Hofmeyr
39daffd7a5 cscn: allocate IuCS conn, properly return rc. 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
71d1e17e5e cscn: call msc_compl_l3() from subscr_conn_allocate_iu()
Pubish msc_compl_l3() decl in new file libmsc/msc_api.h (but see comment).

Call msc_compl_l3() when establishing a subscriber connection for IuCS.

Remove bts from subscr_conn_allocate_iu() signature, use network, link_id and
conn_id instead.

Move subscr_conn_allocate_iu() to the top of the file, because it semantically
belongs before subscr_conn_lookup_iu().
2016-03-03 16:19:09 +01:00
Neels Hofmeyr
2c9e65051c cscn: default to osmo-cscn.cfg, not opencscn.cfg 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
a2ce4aa615 cscn: move gsm0408_rcvmsg_iucs() decl to proper place.
Add noinst-header iu_cs.h and move the gsm0408_rcvmsg_iucs() declaration
there.
2016-03-03 16:19:09 +01:00
Neels Hofmeyr
ee1541d504 put Iu-common and Iu-CS stuff in proper places
Add libiu to contain the parts used by both Iu-CS (in osmo-cscn) and Iu-PS (in
gprs) into libiu. It's rather thin and may make sense to move to osmo-iuh
altogether, eventually.

iu.c is half moved to libiu/, and half to osmo-cscn/iu_cs.c.
2016-03-03 16:19:09 +01:00
Neels Hofmeyr
9dcae17866 wip 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
c2c5176328 todo / #if 0 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
a2c182df6d minor fixes 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
070f673b12 func declaration, comments 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
e2a10dbe35 fix: it's called msgb.dst. 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
bf30ec26e5 wip 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
dcbc852125 Indicate A-interface for new A subscr-conn. 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
48e091ea2b Add some Iu-CS functions (in the wrong place though, wip) 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
712074cb17 cosmetic: a rename, comments.
Rename conn_ctx_list -> ue_conn_ctx_list.
Indicate Iu-CS 'siblings' for a couple of functions.
Tweak/add comments.
2016-03-03 16:19:09 +01:00
Neels Hofmeyr
a34aedf7f9 Add Iu-CS indicator to struct gsm_subscriber_connection.
Introduce enum interface_type and gsm_subscriber_connection.via_iface to
distinguish between A-interface and Iu-CS-interface connections.

Add gsm_subscriber_connection.iu.link_id and iu.conn_id.
2016-03-03 16:19:09 +01:00
Neels Hofmeyr
2e5c13129d log level: DIUCS = debug 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
da5b3fcd32 wip (reminders to self, whitespace) 2016-03-03 16:19:09 +01:00
Neels Hofmeyr
5291ee5c16 make osmo-cscn compile and receive first Iu-CS buf (and log it only) 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
5773987881 iu_init: add addr and port args 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
836b904e77 add DIUCS debug id 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
444d50b77f various small fixes 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
b3b8ccfa54 sai arg back to pointer 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
231aa60ce4 some fixes 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
8b713f817d generalize rab_act for ps and cs 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
ce3b41fdb6 move struct ue_conn_ctx to header 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
0f93bb80e4 sgsn_iu -> iu 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
477a054c2c sai arg 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
52ddce4378 iu_common 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
2945fd4611 rename sgsn_iu.c to iu.c.
That code seems to be usable for the CS side, as well. A more general name
is applicable. todo: move out of gprs even.
2016-03-03 16:19:08 +01:00
Neels Hofmeyr
2449c0ce58 tweak ..rcvmsg_iu()'s sai arg.
It was a uint16_t*, but is passed as a uint16_t, and never used anyway, yet.
2016-03-03 16:19:08 +01:00
Neels Hofmeyr
5d145b5477 iu_common wip 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
45b13244f0 gitignore 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
cb91aa7e6c cscn 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
7ef6d9893f asn_debug 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
6aeee0a0d9 cosmetic 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
17d061bd8e typo 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
ef3548c0a1 wip 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
add0953692 cscn: adjust header comment. 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
ca3977c8fe Add osmo-cscn, as a copy of osmo-nitb.
CSCN means "Circuit Switched Core Network" (-in-the-box) and will become a
NITB-without-BSC, so that it talks Iu-cs to the HNBGW and talks 'A' to an
external BSC.

Copying NITB is debatable: on the one hand, we've agreed on the name Osmo-CSCN
for the end result (without internal BSC). On the other hand, I will probably
add Iu-cs into the NITB code incrementally, in such a way that theoretically,
both Iu-cs and the internal BSC functionality could be used at the same time.
So Osmo-CSCN will be a NITB plus Iu-cs for a while. Instead of adding to NITB,
I prefer to work on a copy, so that the original NITB remains more or less
unchanged.

Only a later step will clearly distinguish CSCN from NITB: when the BSC part is
split off for the benefit of a proper A-interface, and CSCN talks to an
external BSC.
2016-03-03 16:19:08 +01:00
Neels Hofmeyr
a234287d09 doc: add call graphs from MSC to BSC or HNB-GW (wip) 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
8440c9f04b disable some sgsn_tests to pass the status quo.
while working on this, I need to see whether I break any more things.
So remove some noise temporarily.
2016-03-03 16:19:08 +01:00
Neels Hofmeyr
2cb732aeb9 sgsn_test build 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
a7551e033e sgsn_test: apply addition of gb member 2016-03-03 16:19:08 +01:00
Neels Hofmeyr
08ed1d73f2 fix sgsn_mm_ctx_cleanup_free: TLLI unass. after sgsn_mm_ctx_free.
The comment says so and it was moved above sgsn_mm_ctx_free in a commit
marked as ugly hack.
2016-03-03 16:19:07 +01:00
Neels Hofmeyr
af9bfac58d fix ranap_handle_co_dt, failed to pass struct pointer 2016-03-03 16:19:07 +01:00
Harald Welte
ac9951e54a gsm_04_08.c: Don't set msg->lchan nor msg->dst
the BSC-side of the API behind gsm0808_submit_dtap() is doing
this resolving again anyway.  So let's avoid doing it twice, and avoid
having more dependency of the MSC down into the lchan details.
2016-03-03 16:19:07 +01:00
Harald Welte
75cdeaf1e3 gsm_04_11.c/04_08.c: s/lchan/conn/ where we don't use lchan for years 2016-03-03 16:19:07 +01:00
Harald Welte
41f8f047bc remove dead code from Makefile.am 2016-03-03 16:19:07 +01:00
Harald Welte
195d2dc724 migrate WIP osmo-iuh hack to use system-installed libosm-ranap.so
this means we no longer try to link to hard-coded files outside of the
openbsc.git repository.
2016-03-03 16:19:07 +01:00
Harald Welte
315abfd46b WIP: Really ugly hacks to get up to (and including) PDP CTX ACT 2016-03-03 16:19:07 +01:00
Harald Welte
648b9db47f add sgsn_iu.c that was missed in large WIP commit 2016-03-03 16:19:07 +01:00
Harald Welte
8291623054 rtp_proxy.c: Ensure msgb_alloc is large enough for largest AMR frame
In AMR 12.2 (mode 7), the actual RTP payload is 33 bytes.  Howeerver,
as we store the length of the (dynamically-sized) AMR payload in the
first byte, our buffer needs at least 33+1 byte in size.
2016-03-03 16:19:07 +01:00
Harald Welte
5331cf8dbd subscr_name(): Handle case for subscr == NULL
subscr_name() was called from several places:
* either without a check for subscr being NULL, which for example
  was causing a segfault if we hand-over a channel before identifying the
  subscriber
* or with an explicit NULL check and the ternary operator (?).

We now simplify the code by checking for the NULL Subscriber in subscr_name()
itself.
2016-03-03 16:19:07 +01:00
Harald Welte
cf8e56cd1e WIP 2016-03-03 16:19:07 +01:00
Harald Welte
e157174447 gprs_gmm.c: Preform LLME operations only if we have one
In case the GMM message did not arrive over a Gb interface, there is no
LLME (and thus the associated pointer is NULL).  Don't try to perform
operations on a NULL LLME.
2016-03-03 16:19:07 +01:00
Harald Welte
493534bf56 gprs_gmm.c: Make TLLI handling specific to Gb interface
Soem of the operations we perform in the GMM layer are specific to the
GPRS/EDGE radio access network and its Gb interface.  Let's make them
conditional to that in preparation of supporting an Iu interface.
2016-03-03 16:19:07 +01:00
Harald Welte
342f59d92e gprs_gmm.c: Don't try to de-reference NULL mmctx
There was a comment in the code that certain GMM messages require a
valid mmctx pointer.  However, nothing actually checked if that pointer
was in fact non-NULL.  We plainly crashed if a MS would send us the
wrong message in the wrong state.
2016-03-03 16:19:07 +01:00
Harald Welte
aefb0c45e9 rename gsm0408_gprs_rcvmsg() to gsm0408_gprs_rcvmsg_gb()
This is the entry point for GMM from Gb.  We will create a new one
for Iu, so let's be explicit rather than implicit.
2016-03-03 16:19:07 +01:00
Harald Welte
692f31446e prepare sgsn_mm_ctx for Gb and Iu mode (UMTS)
Let's explicitly mark those sgsn_mm_ctx members that apply for Gb mode
and (upcoming) Iu mode, respectively.
2016-03-03 16:19:07 +01:00
Neels Hofmeyr
2cde90e904 Fix two rc values in gsm0408_dispatch()
I do hope the unimplemented/unknown messages did not return 0 intentionally.
2016-03-03 16:19:07 +01:00
Neels Hofmeyr
f6672ab8b0 move subscriber conns list into struct gsm_network.
Replace the global sub_connections llist with gsm_network.subscr_conns.
Initialize and apply where applicable. Remove bsc_api_sub_connections().
2016-03-03 16:19:07 +01:00
Neels Hofmeyr
51273157fa channel_test: don't segfault if paging fails
Add due assertions of return value validity, otherwise leading to segfaults.
2016-03-03 16:12:04 +01:00
Neels Hofmeyr
6a1d172c95 db: evaluate return value of sqlite3_finalize(), tweak log output. 2016-03-01 13:05:27 +01:00
Neels Hofmeyr
45ee133d1d check return value of sqlite3_close(), retry up to three times. 2016-02-29 16:44:13 +01:00
Neels Hofmeyr
5b38312b92 use sqlite3_close() instead of sqlite3_close_v2()
This allows using sqlite3 v3.7.13, used by our current debian installation in
the test setup. _v2 was added in v3.7.14.
2016-02-29 16:42:00 +01:00
Neels Hofmeyr
49b83d8f67 minor comment 2016-02-29 10:31:07 +01:00
Neels Hofmeyr
a7313dd886 osmo_bsc_filter.c: add fixme note 2016-02-29 10:31:07 +01:00
Neels Hofmeyr
fea1df8587 bsc_test.c: fix tz.override val and note a FIXME 2016-02-27 23:38:28 +01:00
Neels Hofmeyr
1b0e5540db smpp: refactor initialization, add bind address
Make the SMPP bind address configurable (used to be harcoded as "0.0.0.0").

Add VTY command

    smpp
     local-tcp A.B.C.D <1-65535>

while keeping the old command 'local-tcp-port <1-65535>'. Both the old and the
new command immediately change the SMPP listening address and port.

Add a LOGL_NOTICE log when the SMPP listening address and/or port change.

However, to be useful, this patch has to go somewhat further: refactor the
initialization procedure, because it was impossible to run the VTY commands
without an already established connection.

The SMPP initialization procedure was weird. It would first open a connection
on the default port, and a subsequent VTY port reconfiguration while reading
the config file would try to re-establish a connection on a different port. If
that failed, smpp would switch back to the default port instead of failing the
program launch as the user would expect. If anything else ran on port 2775,
SMPP would thus refuse to launch despite the config file having a different
port: the first bind would always happen on 0.0.0.0:2775. Change that.

In the VTY commands, merely store address and port if no fd is established yet.

Introduce several SMPP initialization stages:

* allocate struct and initialize pointers,
* then read config file without immediately starting to listen,
* and once the main program is ready, start listening.

After that, the VTY command behaves as before: try to re-establish the old
connection if the newly supplied address and port don't work out. I'm not
actually sure why this switch-back behavior is needed, but fair enough.

In detail, replace the function
  smpp_smsc_init()
with the various steps
  smpp_smsc_alloc_init() -- prepare struct for VTY commands
  smpp_smsc_conf() -- set addr an port only, for reading the config file
  smpp_smsc_start() -- establish a first connection, for main()
  smpp_smsc_restart() -- switch running connection, for telnet VTY
  smpp_smsc_stop() -- tear down connection, used by _start() twice

And replace
  smpp_openbsc_init()
  smpp_openbsc_set_net()
with
  smpp_openbsc_alloc_init()
  smpp_openbsc_start()

I'd have picked function names like "_bind"/"_unbind", but in the SMPP protocol
there is also a bind/unbind process, so instead I chose the names "_start",
"_restart" and "_stop".

The smsc struct used to be talloc'd outside of smpp_smsc_init(). Since the smsc
code internally uses talloc anyway and employs the smsc struct as talloc
context, I decided to enforce talloc allocation within smpp_smsc_alloc_init().

Be stricter about osmo_signal_register_handler() return codes.
2016-02-25 12:18:04 +01:00
Neels Hofmeyr
73828152d9 enable ctrl bind config for various programs
Add ctrl_vty_init() calls and feed the ctrl_vty_get_bind_addr() return value to
ctrl_interface_setup() in the following programs:

  osmo-bsc
  osmo-bsc_nat
  osmo-nitb
  osmo-sgsn

For osmo-sgsn, move the control interface setup invocation below the config
parsing, so that the ctrl_vty_get_bind_addr() can return the configured
address.
2016-02-25 12:18:04 +01:00
Neels Hofmeyr
fc7add20e1 osmo-nitb: be strict about cmdline args
Abort upon unknown options and missing option arguments. This came to my
attention while rewiring the -m and -M options: passing -M without argument
would launch nitb with wrong configuration. So, rather exit immediately.

If there are legacy options that should be ignored, they deserve an own 'case:'
in the option switch. There are none that I'm aware of though.
2016-02-25 12:18:04 +01:00
Neels Hofmeyr
f4a3123145 osmo-nitb: cosmetic: rename to rf_ctrl_path, following mncc_sock_path
Strictly speaking, the unix domain socket location is not a name but a path.
The MNCC socket is called path, so it is confusing to call the ctrl socket
a 'name'.
2016-02-25 12:18:04 +01:00
Neels Hofmeyr
0ade63233b osmo-nitb: add -M to pass specific MNCC socket path
The old -m option without argument is still available and marked deprecated,
to not make users' lives more difficult than necessary.
2016-02-25 12:18:03 +01:00
Neels Hofmeyr
fa0f71526c enable telnet VTY bind address config for various programs
Following the 'line vty'/'bind A.B.C.D' command added in libosmocore, use the
configured address to set the telnet bind for the VTY line. It is now possible
to publish the VTY on a specific local interface (including 0.0.0.0 aka "any").

Implement in all of:
  osmo-gbproxy
  osmo-gtphub
  osmo-sgsn
  osmo-bsc
  osmo-bsc_nat
  osmo-bsc_mgcp
  osmo-nitb

In some of these main programs, move the telnet initialization below the
configuration parsing.

Historically, this was not a good idea for programs using bsc_init.c (aka
bsc_bootstrap_network()), since they expected a gsm_network struct pointer in
((struct telnet_connection*)vty->priv)->priv, so that telnet had to be either
initialized or replaced by a dummy struct. In the meantime, the gsm_network
struct is not actually looked up in a priv pointer but in the static bsc_vty.c
scope (bsc_gsmnet), so this limitation is mere legacy (even though said legacy
is still there in an "#if 0" chunk).

In the other binaries I have briefly looked at the init sequence dependencies
and found no reason to initialize telnet above the config file parsing. In any
case, I have tested every single one of abovementioned binaries to verify that
they still parse the example config successfully and launch, allowing VTY
connections on the configured address(es). I hope this suffices.

In all of the above, log VTY address and port. LOGL_INFO is disabled by default
in some of the logging scopes, and since it is a single log message right at
program launch, I decided for the slightly more aggressive LOGL_NOTICE.
2016-02-25 12:18:03 +01:00
Neels Hofmeyr
58d5430dd5 gsm340_rx_tpdu: comment-out two unused vars
Kills two compiler warnings.
2016-02-25 12:18:03 +01:00
Neels Hofmeyr
127fc93a13 ipaccess_rcvmsg: fix returncode, add partial write warning
Kills a compiler warning.
2016-02-25 12:18:03 +01:00
Neels Hofmeyr
547f048c89 bsc_nat: fail if VTY telnet port cannot be bound, clarify comment 2016-02-25 12:17:07 +01:00
Neels Hofmeyr
fd1187e2e9 minor fixes in bsc_vty.c and bsc_nat.c
Remove unused talloc.h from bsc_vty.c.

In bsc_nat.c, use OSMO_CTRL_PORT_BSC_NAT instead of hardcoding port number, and
include ctrl/ports.h for that.

Fix comment typo "COMAMND"
2016-02-24 00:43:41 +01:00
Neels Hofmeyr
1901b92f0c osmo-bsc: fix checking wrong pointer for ctrl setup success 2016-02-24 00:43:25 +01:00
Neels Hofmeyr
69da1d453c gtphub: tweak default logging level 2016-02-23 13:28:04 +01:00
Neels Hofmeyr
03933a49de gtphub: include ports.h instead of redefining OSMO_VTY_PORT_GTPHUB 2016-02-23 13:26:02 +01:00
Holger Hans Peter Freyther
389a62d752 Merge branch 'jerlbeck/fixes/sgsn'
Remove the assert in the llme by avoiding the usage of foreign to local
mappings of TLLIs. The asserts had been hit at 32C3 and the fixes were
created by Jacob and had been tested at the convention.
2016-02-22 11:02:36 +01:00
Jacob Erlbeck
5ac4aadd1a sgsn: Re-add searching for MM ctx based on TLLI / P-TMSI matches
If an MM context cannot be found based on BBSGP info and a RA UPDATE
REQUEST is received, try to find an MM context with an P-TMSI from
which the TLLI could have been derived. This also checks, whether the
routing area matches.

This is similar to the old behaviour removed by the commits
"sgsn: Only look at TLLIs in sgsn_mm_ctx_by_tlli" and
"sgsn: Remove tlli_foreign2local", except that this will only
be done for RA UPDATE REQUESTs now.

Sponsored-by: On-Waves ehf
2016-02-22 10:52:08 +01:00
Jacob Erlbeck
1330478aa5 sgsn/test: Add test case test_gmm_routing_areas
This test add different cases of routing area changes.

Sponsored-by: On-Waves ehf
2016-02-22 10:52:08 +01:00
Jacob Erlbeck
d35957a7d9 sgsn: Change handling of missing mmctx in gsm48_rx_gmm_ra_upd_req
Currently the MM context is just overwritten by a call to
sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &old_ra_id) even if it
has already been found by using the BSSGP info. With the changes
made to sgsn_mm_ctx_by_tlli this will never find a MM context if
the routing area has changed. If the routing area has not changed,
the mmctx has already been found if it exists.

This commit splits searching for an MM context (if it hasn't been
found already) from checking, whether a found one can really be
used. The actual search is removed, so that the MS will be forced to
restart the attach procedure, which is less efficient but safe.

Sponsored-by: On-Waves ehf
2016-02-22 10:52:08 +01:00
Jacob Erlbeck
d58c033305 sgsn: Only look at TLLIs in sgsn_mm_ctx_by_tlli
Currently the code also matches the TLLI against LOCAL and FOREIGN
mappings of the P-TMSI, thus eventually finding MM contexts not
consistent with the TLLI (both tlli and tlli_new differ). On
the other hand, tlli_new is not checked at all.

This commit changes the function to only look at mmctx->tlli,
mmctx->tlli_new, and the routing area.

Sponsored-by: On-Waves ehf
2016-02-22 10:52:08 +01:00
Jacob Erlbeck
e7bcdc3bda sgsn: Make ra_id_equals available as gprs_ra_id_equals
The function is moved to gprs_utils.c, renamed, and made non-static
to be usable in other modules, too.

Sponsored-by: On-Waves ehf
2016-02-22 10:52:08 +01:00
Jacob Erlbeck
9158089fa8 sgsn/test: Add bssgp_raid parameter to send_0408_message
The BSSGP cell identifier is used to get the RA for the TLLI lookup.
The send_0408_message function used in the tests does not set this,
so the RA identifier is always 0-0-0-0.

This commit adds a parameters to pass the RAID and adds missing
dummy RAIDs.

Note that the CI can still not be set and thus is always 0.

Sponsored-by: On-Waves ehf
2016-02-22 10:52:08 +01:00
Jacob Erlbeck
3fbf0a3735 sgsn: Remove tlli_foreign2local
Currently foreign TLLI are sometimes mapped to local TLLI in the
hope that they will match. This seems to sometimes introduce
inconsisties, possibly leading to a failing assertion in
_bssgp_tx_dl_ud.

This mapping should probably reduce the allocation of additional
LLME during routing area changes.

This commit removes tlli_foreign2local.

Sponsored-by: On-Waves ehf
2016-02-22 10:52:08 +01:00
Ruben Undheim
2259c7528e Patch to make openbsc find libsmpp34
This patch lets the build script for openbsc find the libsmpp34 installation
with the help of pkg-config instead of assuming the header files are in
/usr/include.
2016-02-18 19:39:32 +01:00
Harald Welte
28e9f60404 rename ipaccess-find into abisip-find
The tool is not used only to find ip.access devices, but used to find
any Abis/IP implementing devices, including those supported by OsmoBTS.
2016-02-18 11:15:16 +01:00
Harald Welte
bafc1e4cfe add DOT graph showing NITB data structures and their references 2016-02-14 17:38:26 +01:00
Holger Hans Peter Freyther
e9f420d487 msc: Remove oversimplified todo entry and add a comment
Add a comment of why we want to accept this connection anyway.
2016-02-10 10:42:20 +01:00
Holger Hans Peter Freyther
8239e063b9 gsm0408: Provide unique strings for the gsm 04.08 message
At Rhizomatica we see that some GSM 04.08 messages are leaked and
have no other indication if that is Call Control, SMS or something
else.
2016-01-30 09:57:49 +01:00
Neels Hofmeyr
1da0a7e229 openbsc/README: some fixes, add CSCN and Iu*
OsmoNITB stated to include BTS, should be BSC. Reword some outdated
statements. Add OsmoCSCN and mention IuCS and IuPS interfaces.
2016-01-28 13:36:07 +01:00
Neels Hofmeyr
6d575cbe57 Add README.vty-tests 2016-01-28 13:36:07 +01:00
Neels Hofmeyr
34cf923704 remove src/libgb/Makefile.am
libgb has been obsolete for years, but the Makefile.am is still there.
src/Makefile.am does not list it as a subdir, so it's just dangling legacy.
2016-01-28 11:51:21 +01:00
Neels Hofmeyr
9c4f1d6fd0 fix bsc_vty out: timeslot indented too deeply.
In 'show running-config', timeslot appears as a sub-element of rsl, but it is a
direct child of trx. Fix the timeslot section in vty_out by removing one space
of idention.

Adjust various config examples.

Rationale: it's not relevant for function, but confuses human operators. Fixing
it will save the next hacker some time.
2016-01-28 11:45:51 +01:00
Alexander Huemer
1bf8617610 gprs: use libgtp cflags 2016-01-26 11:05:14 +01:00
Holger Hans Peter Freyther
de76661cf3 gtphub: Fix use after free on failure
Even if fclose fails the stream is inaccessible and the second fclose
might cause memory violation.

Linux manpage says:
Upon  successful  completion 0 is returned.  Otherwise, EOF is returned
and errno is set to indicate the error.  In either case any further
access (including another call to fclose()) to the stream results in
undefined behavior.

Fixes: CID#57958
2016-01-23 10:28:09 +01:00
Holger Hans Peter Freyther
f9f44901a2 db: Avoid undefined behavior when copying cm2/cm3 from the db
memcpy has both the source and destination marked as non-null and
we were still passing NULL (with a zero size) to it. While this
makes sense it violates the constraints of the function. Add the
check to see if these values are NULL or not.

+db.c:583:2: runtime error: null pointer passed as argument 2, which is declared to never be null
+    #0 0x40d7f7 in get_equipment_by_subscr (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40d7f7)
+    #1 0x40f6d2 in db_get_subscriber (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40f6d2)
+    #2 0x40bfaa in sms_from_result_v3 (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40bfaa)
+    #3 0x40c847 in update_db_revision_3 (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40c847)
+    #4 0x40cbc3 in check_db_revision (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40cbc3)
+    #5 0x40cf85 in db_prepare (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40cf85)
+    #6 0x406f18 in main /home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test.c:179
+    #7 0x7fd625638a3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
+    #8 0x405598 in _start (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x405598)
+
+db.c:590:2: runtime error: null pointer passed as argument 2, which is declared to never be null
+    #0 0x40da23 in get_equipment_by_subscr (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40da23)
+    #1 0x40f6d2 in db_get_subscriber (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40f6d2)
+    #2 0x40bfaa in sms_from_result_v3 (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40bfaa)
+    #3 0x40c847 in update_db_revision_3 (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40c847)
+    #4 0x40cbc3 in check_db_revision (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40cbc3)
+    #5 0x40cf85 in db_prepare (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x40cf85)
+    #6 0x406f18 in main /home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test.c:179
+    #7 0x7fd625638a3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
+    #8 0x405598 in _start (/home/builder/jenkins/workspace/Osmocom_Sanitizer/source/openbsc/openbsc/tests/db/db_test+0x405598)
2016-01-23 09:21:04 +01:00
Holger Hans Peter Freyther
fec29ab4e9 gtphub: Make the two setter static as well
Same as with the previous gtphub commit. Make these static to deal
with the new semantic of inline in gcc5.
2016-01-22 23:36:22 +01:00
Holger Hans Peter Freyther
7ba088bdf0 dahdi: The driver has moved to libosmo-abis
We can remove this check from openbsc as the handling is done
in libosmo-abis.
2016-01-22 23:35:21 +01:00
Holger Hans Peter Freyther
91e0e1b038 gtphub: Fix compilation using gcc5
The semantic of inline has changed and we need to make it static
to not end up with undefined references.
2016-01-22 23:32:36 +01:00
Alexander Huemer
22a7142129 tests/abis: fix format specifiers 2016-01-15 15:41:19 +01:00
Alexander Huemer
6cacc56d8e tests/oap: depend on libgtp
exclude logic copied from src/gprs/Makefile.am
2016-01-15 15:06:03 +01:00
Holger Hans Peter Freyther
5cb480a4c0 bsc/vty: Provide a hint of available input 2016-01-15 15:05:42 +01:00
Neels Hofmeyr
cdc548cb0a gtphub VTY: add newlines to some VTY docs' final lines 2015-12-14 16:11:47 +01:00
Neels Hofmeyr
69a720f3be gtphub VTY: fix doc strings for show cmds 2015-12-14 15:52:01 +01:00
Holger Hans Peter Freyther
da5359f1b6 gtphub: Fix the VTY prompt to make the tests move forward 2015-12-14 15:24:50 +01:00
Neels Hofmeyr
720372e4e8 gtphub VTY test: use only 127.0.0.1.
Add a second example config file for gtphub so that the VTY test can use
nonstandard ports.
2015-12-14 11:29:55 +01:00
Neels Hofmeyr
4adca4e8af osmoappdesc.py: fix wrong index introduced by gtphub.
vty_app should reference osmo-nitb, but by adding gtphub, apps[-1] has
changed. Use index 5, which won't change when adding further items.
2015-12-13 15:22:01 +01:00
Harald Welte
0a8cf32a48 indicate the GSM 04.08 channel mode in 'show lchan' 2015-12-12 21:43:16 +01:00
Harald Welte
53d51f501c mncc: introduce 'struct gsm_mncc_bridge' for MNCC_BRIDGE
When a MNCC handler wants to issue the MNCC_BRIDGE primitive
overt the MNCC interface, this was not possible so far via the
MNCC socket.   This primitive was so far only available from the
internal MNCC handler, more or less by accident I suppose.  The reason
for this is in the way the array of two call references had been passed
into mncc_tx_to_cc().
2015-12-12 21:43:16 +01:00
Harald Welte
da8a19fec0 mncc.c: Convert mncc_names[] to 'struct value_string' 2015-12-12 21:43:16 +01:00
Neels Hofmeyr
36948bf7c7 gtphub: log: limit length of hex dumps.
The debug log prints the received/sent bytes in hex. When this data surpasses
the buffer size available for the log string (4096), the log is truncated
and lacks a newline character. Limit the amount of dumped bytes to 1000.

Sponsored-by: On-Waves ehi
2015-12-08 12:21:15 +01:00
Neels Hofmeyr
4d2b3ff6a2 gtphub: add VTY show for peers and peer stats.
Sponsored-by: On-Waves ehi
2015-12-07 13:37:28 +01:00
Neels Hofmeyr
d010c49407 gtphub: improve handling of restarted peer.
Handle peer restart earlier, so that all the tunnels are deleted by the restart
code path, instead of the first one being deleted due to reused TEI. That
caused confusing logging messages.

Also, when receiving Delete confirmations from the peer that didn't restart,
don't complain about unknown peer, but acknowledge and remove the half
invalidated tunnel. This means that the pending delete entry from the restart
code path is not needed / not used, so don't bother to add pending delete
entries upon peer restart.

The test test_peer_restarted_reusing_tei() hits the situation where a tunnel is
removed because of a reused TEI rather than the restart counter. Adjust the
test to expect the "out-of-band" delete request earlier on, and to still see
the half invalidated tunnel around. Enhance the test by adding the delete
response from the peer that didn't restart, and add a final tunnels_are()
verification.

Sponsored-by: On-Waves ehi
2015-12-07 13:37:15 +01:00
Neels Hofmeyr
bee75969cc gtphub: log most common message type names.
Sponsored-by: On-Waves ehi
2015-12-07 13:37:13 +01:00
Neels Hofmeyr
ee07e4f75d gtphub: simplify/fix: one TEI mapping per tunnel.
Because the sender is known, one unique TEI per tunnel suffices to map the TEIs
that the peers are sending to gtphub, instead of previously 4 (SGSN<->GGSN
interaction on User and Ctrl plane, where each had an own unique TEI).

Also, previously, a tunnel's endpoints should also have been checked against
each other for TEI reuse, not only against the endpoints of other tunnels. This
simplification fixes that problem for free.

Thus simplify TEI reuse detection and improve VTY show readability and
debugging.

Adjust log and VTY output for tunnels.
Adjust tests accordingly.

Suggested-by: Holger Hans Peter Freyther <holger@moiji-mobile.com>
Sponsored-by: On-Waves ehi
2015-12-07 13:37:11 +01:00
Neels Hofmeyr
f6e4d08219 gtphub: fix: when checking TEIs, skip 0.
Sponsored-by: On-Waves ehi
2015-12-07 13:37:10 +01:00
Neels Hofmeyr
328d2f78c1 gtphub: log: add TEI reuse msg, fix another TEI msg.
Sponsored-by: On-Waves ehi
2015-12-07 13:37:09 +01:00
Neels Hofmeyr
23d09cc904 gtphub_test: add test_parallel_context_creation()
Sponsored-by: On-Waves ehi
2015-12-07 13:37:08 +01:00
Neels Hofmeyr
ee1e5d758e gtphub: log: add side str to msg for reused TEI
Sponsored-by: On-Waves ehi
2015-12-07 13:37:06 +01:00
Neels Hofmeyr
e38fb66f4b gtphub: add more detailed I/O rate counters.
Count bytes and packets per peer port, as well es per tunnel enpoint, which
adds two more levels of detail.

Sponsored-by: On-Waves ehi
2015-12-07 13:37:05 +01:00
Neels Hofmeyr
956d856b61 gtphub: be strict about unknown cmdline args
Sponsored-by: On-Waves ehi
2015-12-07 13:37:04 +01:00
Neels Hofmeyr
ba0525e3d8 gtphub: tweak logging.
Less spaces in tunnel strings, adjust tests accordingly.

Use side_idx to remove code dup in rate counter output.

Sponsored-by: On-Waves ehi
2015-12-07 13:37:03 +01:00
Neels Hofmeyr
28a70f20cd gtphub: logging: have one newline per log.
Some logging was multiline to ease human reading of debug output. However,
in the VTY output, these newlines lack a CR motion. Split multiline logs into
separate lines.

Also add one missing space.

Sponsored-by: On-Waves ehi
2015-12-07 13:37:01 +01:00
Neels Hofmeyr
9d8f506f7f gtphub: fix missing newline in log output
Sponsored-by: On-Waves ehi
2015-12-07 13:36:57 +01:00
Neels Hofmeyr
5d5c31a367 gtphub: enhance gtphub-example.txt 2015-12-07 11:07:22 +01:00
Neels Hofmeyr
5c7dcf9665 gtphub: add gtphub-example.txt 2015-12-07 10:58:11 +01:00
Harald Welte
3f015f04b1 bring the README into the 21st century 2015-12-05 23:13:49 +01:00
Harald Welte
c14574b567 AUTHORS: Add Jacob and Neels 2015-12-05 23:04:11 +01:00
Harald Welte
d8352d75b6 remove old obsolete linux kernel and wireshark patches
Those were relevant in 2008/2009, but not today...

Also, move hlrsync to the contrib directory
2015-12-05 22:59:41 +01:00
Harald Welte
c696cc28d8 gsm_data_shared: compute/sprintf the lchan name only once
We now store the pre-printed lchan name in lchan->name to avoid having
to call sprintf every time there is a debug statement somewhere,
particularly as most of those debug statements are going to be inactive
most of the time.
2015-12-05 16:19:21 +01:00
Neels Hofmeyr
e1ba781f7b gtphub: tweak startup log for sgsn_use_sender 2015-12-03 14:48:27 +01:00
Neels Hofmeyr
f8c701008b gtphub: add test for SGSN behind NAT 2015-12-03 14:29:48 +01:00
Neels Hofmeyr
1ae3ebd68b gtphub_test: tweak test_user_data(): no seq routing.
Don't route User message back by sequence number, rather test that a
completely unrelated User message is routed back properly.

Sponsored-by: On-Waves ehi
2015-12-03 14:19:10 +01:00
Neels Hofmeyr
ca2361c237 gtphub: implement sgsn_use_sender for NAT.
If an SGSN is behind NAT, we cannot rely on the default ports. Specifically,
if a GGSN sends a message, the forwarding to the SGSN should go to whichever
port the SGSN last sent from (whether sequence nr is known or not).

Add sgsn_use_sender config and VTY command, and store the sender instead
of the GSN Address IE and default port if set.

Sponsored-by: On-Waves ehi
2015-12-03 14:14:43 +01:00
Neels Hofmeyr
d53c6046bc gtphub: prepare: keep tunnel ref in gtp_packet_desc.
Rather than passing a tunnel pointer as function arguments, keep it in the
gtp_packet_desc struct passed around anyway.

Reason: in the next commit (will add sgsn_use_sender), I need the tunnel to be
passed back out to gtphub_handle_buf(), and besides simplifying existing code,
this also makes passing the tunnel back out trivial.

Sponsored-by: On-Waves ehi
2015-12-03 13:59:50 +01:00
Neels Hofmeyr
e5a0798c9c gtphub: tweak an error log message 2015-12-03 13:47:05 +01:00
Neels Hofmeyr
8c5b073072 gtphub: Del PDP: replace unnecessary lookup with asserts. 2015-12-03 13:45:15 +01:00
Neels Hofmeyr
8defadbdd2 tests: fix condition to run sgsn, oap, gtphub tests
Sponsored-by: On-Waves ehi
2015-12-03 11:47:34 +01:00
Neels Hofmeyr
59c1b645e2 gtphub: check TEI presence in Create PDP Ctx Response
Sponsored-by: On-Waves ehi
2015-12-03 11:47:30 +01:00
Neels Hofmeyr
87c83d0b89 gtphub: improve logging for invalid packet
Sponsored-by: On-Waves ehi
2015-12-03 11:47:25 +01:00
Neels Hofmeyr
d8660ef090 gtphub: cosmetic
During the peer review session with Holger, these things were deemed fixable.

No need to have a static gtp_packet_desc in gtphub_handle_buf.

No need to memcpy, direct assignment does the job.

Remove obsolete comments.

Fix a stray space.

Sponsored-by: On-Waves ehi
2015-12-03 11:47:19 +01:00
Neels Hofmeyr
c6d51f5fb4 gtphub: fix restart cleanup peer matching.
Adjust test expectations accordingly.

Sponsored-by: On-Waves ehi
2015-12-03 11:47:16 +01:00
Neels Hofmeyr
996ec1d731 gtphub: wrap gtphub_write() for test suite.
Sponsored-by: On-Waves ehi
2015-12-03 11:47:12 +01:00
Neels Hofmeyr
18d3049612 gtphub: fix use after free.
A tunnel pointer was still being checked after deleting by a call to
expiring_item_del(). 'continue' to the next tun.

Sponsored-by: On-Waves ehi
2015-12-03 11:47:08 +01:00
Neels Hofmeyr
237fee649e gtphub: add restart counter test
Sponsored-by: On-Waves ehi
2015-12-03 11:46:57 +01:00
Neels Hofmeyr
936b890f71 gtphub: Add a debug log
Sponsored-by: On-Waves ehi
2015-12-03 11:46:29 +01:00
Neels Hofmeyr
be4bebaad0 gtphub: add test for reused TEI.
Sponsored-by: On-Waves ehi
2015-12-03 11:46:25 +01:00
Neels Hofmeyr
4573ca8834 gtphub: fix: add a missing NULL check
Sponsored-by: On-Waves ehi
2015-12-03 11:46:19 +01:00
Neels Hofmeyr
52c0bd3025 gtphub: cosmetic: early continue for less indent
Sponsored-by: On-Waves ehi
2015-12-03 11:44:39 +01:00
Neels Hofmeyr
bc44330671 gtphub: monitor GSNs' restart counters.
If a GSN indicates that it has reset, tear down each known tunnel for that GSN
individually (don't send the GSNs on the other side a different restart
counter, because they represent more than just this GSN).

Sponsored-by: On-Waves ehi
2015-12-03 11:44:37 +01:00
Neels Hofmeyr
3fdba2ed5a gtphub: cosmetic
Move the SGSN read callback next to the GGSN read callback.

Comments.

Tweak an initialization to NULL.

Sponsored-by: On-Waves ehi
2015-12-03 11:44:28 +01:00
Neels Hofmeyr
7559910e8c gtphub_test: add test for Del PDP from GGSN side.
Sponsored-by: On-Waves ehi
2015-12-03 11:44:25 +01:00
Neels Hofmeyr
99a50b3529 gtphub_test: add some cleanup asserts.
Sponsored-by: On-Waves ehi
2015-12-03 11:44:21 +01:00
Neels Hofmeyr
10fc024472 gtphub: handle Delete PDP Context.
During resolution of the header TEI, also return the tunnel struct that
resolved the TEI, so the Delete PDP Ctx code does not need to look it up
again.

Upon Delete PDP Ctx Request, remember the IEs and that a request was made.
Upon Delete PDP Ctx Response, find the pending delete and remove the
corresponding tunnel, iff the response indicates success.

Add a context deletion to regression tests, rename the test appropriately.

Sponsored-by: On-Waves ehi
2015-12-03 11:44:19 +01:00
Neels Hofmeyr
2f67125c32 gtphub: remove obsolete todo comment
Sponsored-by: On-Waves ehi
2015-12-03 11:44:13 +01:00
Neels Hofmeyr
800126b1f3 gtphub: fix segfault when empty config.
gsn_addr_from_str(): return error upon NULL string.
Add some debug logging.

With an empty config, no bind addresses were set, and the address parser
did not check for a NULL pointer, resulting in a segfault.

Sponsored-by: On-Waves ehi
2015-12-03 11:44:08 +01:00
Neels Hofmeyr
cd865d62f0 gtphub: be more fatal about not finding an unused TEI.
Sponsored-by: On-Waves ehi
2015-12-03 11:44:03 +01:00
Neels Hofmeyr
085500807c gtphub: fix some style complaints from cppcheck
Sponsored-by: On-Waves ehi
2015-12-03 11:43:57 +01:00
Neels Hofmeyr
ff4b630de9 gtphub: add two stubs for Delete PDP msgs
Sponsored-by: On-Waves ehi
2015-12-03 11:43:49 +01:00
Neels Hofmeyr
817bc32696 gtphub: vty: add missing SGSN-proxy output.
Sponsored-by: On-Waves ehi
2015-12-03 11:43:40 +01:00
Neels Hofmeyr
a9905a51f9 gtphub: refactor: use side_idx everywhere.
This is a mostly cosmetic change. Instead of separate buffer handling
functions, reduce some code duplication by using a side_idx just like the
plane_idx, with arrays.

Sponsored-by: On-Waves ehi
2015-12-03 11:43:25 +01:00
Neels Hofmeyr
7174b169e0 gtphub: make sure mapped TEIs aren't occupied (incomplete).
This could be done way better, discussion is pending/ongoing. It is indeed
quite unlikely that any user will ever hit this situation, so there is no
strong drive to invest effort in a more comprehensive implementation.

Sponsored-by: On-Waves ehi
2015-12-03 11:40:24 +01:00
Neels Hofmeyr
d121ea6124 gtphub: use a single TEI pool across planes.
There's no need to keep two separate number pools when both can be fed
from the same pool. User and Ctrl plane TEIs can technically overlap without
colliding, but it doesn't hurt if they don't overlap, either.

Sponsored-by: On-Waves ehi
2015-12-03 11:40:22 +01:00
Neels Hofmeyr
f977320736 gtphub: cosmetic: for_each_side,_plane macros.
Simplify looping over sides and planes. I'm tired of typing the same for
loops all the time.

Sponsored-by: On-Waves ehi
2015-12-03 11:40:18 +01:00
Neels Hofmeyr
ba9e9f63bc gtphub: implement restart counter properly.
Force passing a restart counter, by adding such arg to gtphub_start() (test
suite is not affected by this).

In gtphub_main.c, add -r,--restart-file <path> and next_restart_count() to
maintain the counter file. While at it, tweak the cmdline help to unify the
formatting (mostly commas and a missing line break).

Send gtphub's own restart counter. So far, the sender's restart counter was
copied through, which would break as soon as more than one GSN would talk to
the same peer with differing restart counters.

Also fix the in-mem restart counter data type (one octet, not two).

Sponsored-by: On-Waves ehi
2015-12-03 11:40:15 +01:00
Neels Hofmeyr
8d1ffbd3ba gtphub: complain about excess cmdline args.
Sponsored-by: On-Waves ehi
2015-12-03 11:40:12 +01:00
Neels Hofmeyr
005f175c3b gtphub: fix a conditional for log output
Sponsored-by: On-Waves ehi
2015-12-03 11:40:09 +01:00
Neels Hofmeyr
fc1be3a0c1 gtphub: avoid segfault for incomplete tunnels.
Sponsored-by: On-Waves ehi
2015-12-03 11:40:05 +01:00
Neels Hofmeyr
e54cd1555a gtphub: track tunnels explicitly.
So far, gtphub worked perfectly by only tracking single TEIs ... for probably
most uses. But a Ctrl plane tunnel may have expired despite a still active
corresponding User plane tunnel. The User plane would continue to work
indefinitely, but if any Ctrl messages followed after more than six hours of
Ctrl silence, they would have been dropped due to an expired TEI mapping.

We want to
- combine expiry of a user TEI with its ctrl TEI. (done in this patch)
- upon delete PDP context, remove both user and ctrl TEI mappings. (future)
- when a peer indicates a restart counter bump, invalidate its tunnels.
  (future)

To facilitate these, track tunnels, complete with both SGSN's and GGSN's
address, original and replaced TEIs, all for both user and ctrl plane, in a
single struct. A single expiry entry handles the entire tunnel, instead of
previously four separate expiries for each endpoint identifier.

Add the concept of a "side", being either GGSN or SGSN, to index tunnel
endpoint structs, and so on.

Track the originating side in the gtp_packet_desc.

Add header_tei_rx: set_tei() overwrites header_tei, but the originally received
header TEI is still needed to match a Create PDP Context Response up with its
Request (and for logging).

Adjust the test suite to expect tunnel listing strings instead of TEI mappings,
with a bonus of making it a lot easier to grok, and including the IP addresses.

Add regression test for refreshing tunnel expiry upon use.

Note: the current implementation is as slow as can possibly be, iterating all
the tunnels all the time. Optimizations are kept for a future commit, on
purpose.

BTW, the sequence number mapping/unmapping structures remain unchanged.

Sponsored-by: On-Waves ehi
2015-12-03 11:40:03 +01:00
Neels Hofmeyr
2c8b58139f gtphub: cosmetic/prepare: rename expiry queues.
The expiry queues are already used for resolved GGSN addresses, and will
soon enlist tunnel structs. Hence the naming should be more general.

Sponsored-by: On-Waves ehi
2015-12-03 11:39:57 +01:00
Neels Hofmeyr
1aa0e47104 gtphub: add assertion to ensure expiry ordering.
Make 100% sure the user adds expiring_items in chronological order by asserting
that a newly added expiry is >= the last expiry in the queue. Add llist_last()
to facilitate.

Sponsored-by: On-Waves ehi
2015-12-03 11:39:55 +01:00
Neels Hofmeyr
508514c7c5 gtphub: cosmetic/prepare: add nr_map_refresh().
Sponsored-by: On-Waves ehi
2015-12-03 11:39:49 +01:00
Neels Hofmeyr
29d926be12 gtphub: move timestamp into packet struct.
Instead of passing the current time around in function arguments ('now'),
rather store the current time once upon decoding a GTP packet in the
gtp_packet_desc passed around anyway ('p->timestamp').

Sponsored-by: On-Waves ehi
2015-12-03 11:39:47 +01:00
Neels Hofmeyr
231653a8d0 gtphub: cosmetic: fix an argument name.
Sponsored-by: On-Waves ehi
2015-12-03 11:39:42 +01:00
Neels Hofmeyr
4b2cbdab3e gtphub: first vty show commands.
Start adding VTY commands to show rate counters / statistics / cache dumps.

Sponsored-by: On-Waves ehi
2015-12-03 11:39:41 +01:00
Neels Hofmeyr
1ba50c6598 gtphub: add first rate counters
Sponsored-by: On-Waves ehi
2015-12-03 11:39:39 +01:00
Neels Hofmeyr
dba6d1af69 gtphub: cosmetic: clarify bind pointer naming.
Some gtphub_bind pointers point to an array of binds, some point directly at
instances. Make the distinction between the two more obvious by adding an
'_arr' suffix to the array ones.

Partly in preparation for upcoming rate counters.

Sponsored-by: On-Waves ehi
2015-12-03 11:39:38 +01:00
Neels Hofmeyr
20bd6bfef5 gtphub: add explicit cleanup handles.
Clean up functionality is added for the test suite only, to be able to clean
out all allocations and test against memory leaks.

So far, it was sufficient to expire everything to free a gtphub. In preparation
for the upcoming rate counters, which will need to be freed explicitly, add
gtphub functions to clean up everything.

As added bonus, also close the sockets explicitly -- not really needed upon
program exit, neither by the test suite, but *if* we have a cleanup function,
it should clean up everything properly.

Closing the sockets is however kept separate, for the test suite.
gtphub_start() and gtphub_stop() are for normal use (published in gtphub.h),
and gtphub_init() and gtphub_free() are for the test suite, without sockets.
(gtphub_stop() will probably never be called by anyone, but its existence
completes the picture.)

In gtphub_test.c, have a function to clean up the testing gtphub struct. First,
expire everything by timeout, assert emptiness, then call the cleanup function.
Call from each test in the end.

Sponsored-by: On-Waves ehi
2015-12-03 11:39:36 +01:00
Neels Hofmeyr
1ed9a8673d gtphub: ensure cleanup of peer addresses.
Upon calling gtphub_peer_del(), all addresses and ports should already have
expired (by force). Make sure the code heeds that with a so far missing
assertion.

Sponsored-by: On-Waves ehi
2015-12-03 11:39:34 +01:00
Neels Hofmeyr
b6c2db569f gtphub: ares vty and init
From sgsn_vty.c, copy the cfg_grx_ggsn_cmd to add an ares server to the static
sgsn_instance.

This is sort of preliminary. As described in comments, the sgsn_ares functions
should actually be separated from the static sgsn structure. gtphub keeps such
an sgsn structure just for the sgsn_ares functions.

Sponsored-by: On-Waves ehi
2015-12-03 11:39:33 +01:00
Neels Hofmeyr
d9b1d49485 gtphub: review some logging.
Sponsored-by: On-Waves ehi
2015-12-03 11:39:31 +01:00
Neels Hofmeyr
4960fab767 gtphub: cosmetic: rename a file.
gtphub_ext.c's initial purpose was to wrap a specific function. The file
then turned into everything related to DNS, which fits pretty well. Rename
to gtphub_ares.c.

Tweak the header comment to reflect the new file name.

Sponsored-by: On-Waves ehi
2015-12-03 11:39:30 +01:00
Neels Hofmeyr
e2ed8e6cc3 gtphub: nr_map: add min,max and wrap.
Implement min/max bounds for nr_pool, adjust nr_pool_init() and current tests,
and create unit tests for nr_map wrapping.

Sequence numbers range from 0 to 65535, while TEIs range from 1 to 0xffffffff.
Both cause problems when the nr_pool surpasses the range: seq exit their valid
range, causing unmappings to fail, and a TEI would be mapped as zero (invalid).

Add a comment about TEI wrapping, and lose the comment about random TEIs (not
really important).

Sponsored-by: On-Waves ehi
2015-12-03 11:39:28 +01:00
Neels Hofmeyr
334af5dd9d gtphub: fix number map range for TEIs.
Use unsigned int for nr_map, just large enough to fit the TEI space.
Adjust log output formats and casts accordingly.

Fixes: TEIs are uint32_t, but the nr_map so far used int. This would cause TEIs
from 0x80000000 on to be handled and printed as a negative value.

Sponsored-by: On-Waves ehi
2015-12-03 11:39:24 +01:00
Neels Hofmeyr
5e95a41194 gtphub: add to osmoappdesc.py
Sponsored-by: On-Waves ehi
2015-11-30 12:09:06 +01:00
Neels Hofmeyr
e5e78c21bb gtphub: add to debian build
By the example of osmo-sgsn, package osmo-gtphub for debian.

Sponsored-by: On-Waves ehi
2015-11-30 11:30:36 +01:00
Neels Hofmeyr
ff252bb801 gtphub_test: build only when c-ares and gtp are present. 2015-11-29 18:53:34 +01:00
Neels Hofmeyr
8fbfaa51bb gtphub: remove another obsolete comment. 2015-11-26 22:59:10 +01:00
Neels Hofmeyr
4ae165da61 gtphub: add enable_gtphub_test to atlocal.in.
This line was missing, I noticed only now.
2015-11-24 12:52:13 +01:00
Neels Hofmeyr
a4370dd969 gtphub: fix ares segfault: add missing initialization.
The struct gtphub_resolved_ggsn was not initialized properly, so that adding
it to a list caused a segmentation fault.
2015-11-24 12:52:13 +01:00
Neels Hofmeyr
273f875c42 gtphub: lose obsolete comment.
The del_cb is now also used for ares (GGSN resolution) timeouts, and expiry is
anyway separated from nr_map, so this comment is void.

Sponsored-by: On-Waves ehi
2015-11-24 12:52:13 +01:00
Harald Welte
6a8cbe9718 tests/smpp: Fix linking order
At least when using system-wide libtalloc, the LIBOSMOCORE_LIBS
must come last, after the static libraries under libcommon.
2015-11-21 15:43:29 +01:00
Harald Welte
97b6bfa996 Fix compilation with no libc-ares present on the system
This build failure was introduced with the OAP and gtphub changes.
2015-11-21 13:16:08 +01:00
Holger Hans Peter Freyther
1b9c815024 gtp: Fix Makefile.am so maybe distcheck is now going to work 2015-11-20 21:35:01 +00:00
Harald Welte
557c84e9f7 vty: Print NCC/BCC and not just integer value of BSIC 2015-11-20 10:50:24 +01:00
Harald Welte
a2bbc5ec0e Fix TSC/BSIC handling bug and remove bts->tsc
This fixes a bug in the following circumstances:
* BSIC is set to 0 in the config file
* No TSC is explicitly specified at the BST level in the config file

In this case, we ended up using BSIC=0 and TSC=7, as TSC=7 is our
default initialization value.

The TSC of the CCCH/BCCH must always be the BCC, which is the lower 3
bits of the BSIC.  Having configuration options for both the BSIC _and_
the TSC at the BTS level therefore makes no sense, as it only adds ways
in which users can configure non-oprational configurations.  So we
remove the bts->tsc member, and keep only the ts->tsc members that allow
us to configure a timeslot-specific TSC that's different from the BTS
TSC (= BCC).
2015-11-20 10:43:31 +01:00
Harald Welte
ae2c18c57b oap and gtphub tests must only be compiled of LIBGTP is present! 2015-11-20 10:41:02 +01:00
Harald Welte
0d21ac8f5a Depend on libgtp >= 0.92, as previous versions don't have gtpie.h installed
this fixes compilation for people having older gtp libraries installed.
2015-11-20 10:40:07 +01:00
Harald Welte
24e3c3e136 meas_db.c: fix compiler warnings
s_db.c: In function ‘_insert_ud’:
meas_db.c:65:6: warning: implicit declaration of function ‘rxlev2dbm’ [-Wimplicit-function-declaration]
      rxlev2dbm(ud->full.rx_lev)));
      ^
2015-11-20 10:28:42 +01:00
Neels Hofmeyr
6187e010a8 gtphub: fix echo reply to SGSNs: wrong fd. Add test.
The actual fix is just one character, but also add a regression test against
this, on both CTRL and USER plane.
2015-11-20 01:15:03 +01:00
Neels Hofmeyr
3c820ee532 gtphub: fix three oversights (thanks to coverity).
- an unnecessary if-not-NULL check (1339764);
- a missing nul termination safety net (1339768);
- a typo resulting in the wrong proxy being logged (1339767).

Sponsored-by: On-Waves ehi
2015-11-18 17:34:43 +01:00
Neels Hofmeyr
3d3aa8fb88 gtphub: fix fatal log msg for SGSN proxy.
While reworking the logging, a stray comma found its way into the code.

Fixes coverity 1339765.

Sponsored-by: On-Waves ehi
2015-11-18 17:34:43 +01:00
Neels Hofmeyr
4034897038 gtphub: fix gtphub_read() semantics.
gtphub always wants to know the sender, hence make the from_addr pointer
mandatory.

Fixes two coverity complaints (1339766, 1339764).

Sponsored-by: On-Waves ehi
2015-11-18 17:34:43 +01:00
Neels Hofmeyr
ad945b6aa7 fix build: remove obsolete gtphub EXTRA_DIST.
Sponsored-by: On-Waves ehi
2015-11-18 17:34:29 +01:00
Neels Hofmeyr
9cfe037559 gtphub: cosmetic: break long lines.
Fit most of the code in 80 chars width. Some instances still leak past 80
characters because of long function names, inline comments or the like, "the
exception proves the rule."

Sponsored-by: On-Waves ehi
2015-11-16 15:18:24 +01:00
Neels Hofmeyr
063a802d46 gtphub: review log levels, add level arg to LOG().
For maintenance, it is convenient to have the log level explicit at each
log statement.

Tweak some log levels / message formatting while at it.

Sponsored-by: On-Waves ehi
2015-11-16 15:17:20 +01:00
Neels Hofmeyr
390e910125 gtphub: add logging labels to bind struct.
Allow logging the plane (Ctrl/User) and side (SGSN/GGSN) in functions that only
have a gtphub_bind* to work with, by adding a constant label to each bind.

Sponsored-by: On-Waves ehi
2015-11-16 15:17:00 +01:00
Neels Hofmeyr
a208c734a2 gtphub: don't always try to do GGSN resolution.
If a GGSN is already known from unmapping, don't invoke a host resolution.
In a live working environment, it wouldn't hurt, because the lookups would
mostly return from the cache. But in a testing environment without a name
server, it barfs on every packet.

Sponsored-by: On-Waves ehi
2015-11-16 15:16:52 +01:00
Neels Hofmeyr
16c3f57ed6 gtphub: fix numerous segfaults, and other stupidities.
Initialize llist_heads to empty (2 were missing). Move those for struct gtphub
instances to gtphub_zero() (one moved, one added).

In from_[gs]gsns_read_cb(), use a return type that can actually reflect
negative return values.

resolved_addr.buf: no need to take the address of a byte array var
(cosmetic).

Pass the proper user data address to sgsn_ares_query(), not the address of
the pointer holding the user data address.

Initialize ggsn_lookup->expiry_entry (was missing). Publish the function for that
in gtphub.h so gtphub_ext.c can use it.

Sponsored-by: On-Waves ehi
2015-11-16 15:16:47 +01:00
Neels Hofmeyr
3317c84c16 gtphub: Add logging for ares queries.
Looking for a segfault, I added a lot of logging. This may be useful for
live testing ares, leaving it in there for now.

Note: I still want to clean up the logging concerning log levels etc. once
we're out of alpha.

Sponsored-by: On-Waves ehi
2015-11-16 15:16:44 +01:00
Neels Hofmeyr
c83cd898ef gtphub: fix handling of sender from nonstandard port.
Allow a peer sending from an unknown port but a known address, and just
create the port (and unmap the seq nr back to this port later to return
the response to the sender).

Only an SGSN on the Ctrl plane is allowed to make the very first contact
from an unknown address.

Sponsored-by: On-Waves ehi
2015-11-16 15:16:39 +01:00
Neels Hofmeyr
e921e32c82 gtphub: fix User plane decoding, add unit test.
Split decoding return code GTP_RC_PDU in GTP_RC_PDU_C and GTP_RC_PDU_U.
Don't do IEs in GTP_RC_PDU_U.

Add a unit test for User plane data, expected to fail (nonstandard port case).

In gtphub_test.c, tweak logging so that it is easily visible which test
produced which output. Also add the global resolved_sgsn_addr and ggsn_sender,
symmetrically to resolved_ggsn_add and sgsn_sender.

Sponsored-by: On-Waves ehi
2015-11-16 15:16:37 +01:00
Neels Hofmeyr
c227594394 gtphub: make test code reusable for future tests.
Generalize to make the PDP ctx message definitions and "sending" of messages
from SGSN->gtphub->GGSN and back reusable in future tests.

Publish gsn_addr_from_sockaddr() in gtphub.h for use in gtphub_test.c.

Use an osmo_sockaddr for resolved_ggsn_addr, because one is needed for
comparison in probably every future test.

Add LVL2_ASSERT() to print assertion message and return instead of abort,
so that functions can be called from several tests without losing the
info of which test caused it from which line.

Use globals for struct gtphub and time_t now, to reduce nr of args that need to
be passed around when writing tests. Add a default test setup function.

Sponsored-by: On-Waves ehi
2015-11-16 15:16:36 +01:00
Neels Hofmeyr
5b664f4b9b gtphub: add/fix IMSI and APN IE error handling
Sponsored-by: On-Waves ehi
2015-11-16 15:16:34 +01:00
Neels Hofmeyr
bb3d6785e1 gtphub: fix Echo behavior: respond directly.
Up to now I used the Echo as a test for sequence nr mappings. But Echos
should be handled differently: they are scoped on the link and an Echo
response should be sent right back to the requester.

Sponsored-by: On-Waves ehi
2015-11-16 15:16:32 +01:00
Neels Hofmeyr
30f7bcbd79 gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.

Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.

Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).

In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.

Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.

Minor cosmetics just to see if you're paying attention... ;)

Sponsored-by: On-Waves ehi
2015-11-16 15:16:30 +01:00
Neels Hofmeyr
c8a614d2e9 Add GTP hub initial code base.
First steps towards a new GTP hub. The aim is to mux GTP connections, so that
multiple SGSN <--> GGSN links can pass through a single point. Background:
allow having more than one SGSN, possibly in various remote locations.

The recent addition of OAP to GSUP is related to the same background idea.

(This is a collapsed patch of various changes that do not make sense to review
in chronological order anymore, since a lot of it has thorougly transmorphed
after it was first committed.)

Sponsored-by: On-Waves ehf
2015-11-16 15:16:26 +01:00
Neels Hofmeyr
65482c919f sgsn_vty.c: fix typo 2015-11-10 22:53:15 +01:00
Holger Hans Peter Freyther
98fa3dc1c6 gbproxy: Count more GSM 04.08 messages
Extend the ul/dl counting to count the usual messages on the
Gb interface. Add counters for the attach, routing area update,
pdp context activation and deactivation procedures. Update the
test result with the new counters.
2015-11-10 09:35:30 +01:00
Martin Hauke
9270dc8ca3 Fix Warning: openbsc implicit-pointer-decl meas_udp2db.c:50 2015-11-05 21:04:34 +01:00
Martin Hauke
4316cb2f25 Fix no-return-in-nonvoid-function meas_vis.c
RPM post-build-checks found some issue and marks these as error:

[   38s] I: Program returns random data in a function
[   38s] E: openbsc no-return-in-nonvoid-function meas_vis.c:118
2015-11-05 21:04:29 +01:00
Holger Hans Peter Freyther
292769e19e stats/mgcp: Initialize the statistics for MGCP as well
There are currently no reate counters but this will hopefully
change in the near future.
2015-11-02 16:20:32 +01:00
Jacob Erlbeck
46caed8fc4 stats: Set class_id in rate_ctr group descriptions
This commit adds the class_id initialiser to all rate_ctr_group_desc
definitions.

Sponsored-by: On-Waves ehf
2015-11-02 16:04:16 +01:00
Jacob Erlbeck
64630cccc7 stats: Enable stats for sgsn, gbproxy, nitb, bsc, nat
This commit initialises and enables the stats subsystem for the given
binaries.

Sponsored-by: On-Waves ehf
2015-11-02 16:01:27 +01:00
Pablo Neira Ayuso
11cb27ece6 mgcp_osmux: available circuit IDs from 0 to 255, not from 0 to 128
Holger reports that the bitmap that accounts for available Osmux circuit
IDs is limited to 128, when the maximum number of circuit IDs are
determined by the uint8_t field in the header (ie. 256 circuits).

[hfreyther: Update the testcase now that we have more ids to allocate]
2015-11-02 13:26:26 +01:00
Neels Hofmeyr
568a727550 oap: add OAP config to VTY
Sponsored-by: On-Waves ehf
2015-11-02 12:56:49 +01:00
Neels Hofmeyr
9c534fdbe8 gsup/oap: add OAP to GSUP client.
Trigger an OAP registration upon IPA connect. Feed incoming OAP messages to
oap_handle() and send replies returned by it.

Add oap_config to sgsn_config (todo: vty).

Sponsored-by: On-Waves ehf

[hfreyther: Fix coding style]
2015-11-02 12:56:47 +01:00
Neels Hofmeyr
89ef324eab oap: add OAP API test
Sponsored-by: On-Waves ehf
2015-11-02 12:56:45 +01:00
Neels Hofmeyr
f06046b6af oap: add oap testsuite skeleton
Sponsored-by: On-Waves ehf
2015-11-02 12:56:43 +01:00
Neels Hofmeyr
d739f092be oap: implement initial OAP API.
Add oap.[hc] and oap_messages.[hc].

Sponsored-by: On-Waves ehf
2015-11-02 12:56:41 +01:00
Neels Hofmeyr
d48f057328 libcommon: soak up three static functions.
Add new kitchen sink openbsc/utils.h and libcommon/utils.c to make three so far
static functions public (so I can use them in the upcoming OAP code).

A place to put them could have been the gprs_utils.h, but all general functions
in there have a gprs_ prefix, and todo markings to move them away. All other
libcommon headers are too specific, so I opened up this kitchen sink header.

Replace the implementation of encode_big_endian() with a call to
osmo_store64be_ext(). See comments.

Apply the change in Makefiles and C files.
2015-11-02 12:56:40 +01:00
Holger Hans Peter Freyther
fe60cfb1d6 sgsn: Fix up the VTY doc strings
The documentation needs to end with a \n and T3316
needs to have some text. I think it is the T3316
timer that has no action on the network side.

<command id='timer t3312 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3322 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3350 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3360 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3370 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3313 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3314 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3316 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3385 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3386 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3395 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />

Documentation error (missing docs):
<command id='timer t3397 &lt;0-65535&gt;'>
        <param name='&lt;0-65535&gt;' doc='(null)' />
2015-11-02 12:56:37 +01:00
Harald Welte
69ca8f01ec SGSN: Fix typo in VTY license statement.
It mentioned AGPLv3+ and refers to the hyperlink of v3, but still
stated "Version 2 or later".  That was a typo at the time.
2015-10-29 10:36:28 +01:00
Daniel Willmann
537d480f39 gprs/gb_proxy: Use RAND_bytes for gbproxy TLLI/TMSI allocation
This change has some implications for the test case. It manipulated
bss_ptmsi_state and sgsn_tlli_state variables to make the output of
rand_r() and thus the TLLI/TMSI used predictable.
This possibility is gone when using RAND_bytes() so instead it is
overridden by a function that returns a deterministic sequence of values
(0x00dead00, 0x00dead01, ...). The test cases are adapted to expect
these values instead of the pseudo random values before.

The gbproxy_test stdout file changes as well, but only where the
TLLI/TMSI is displayed (in the hex dumps as well as the TLLI cache
entries).  All other output is the same.
2015-10-13 10:20:26 +02:00
Daniel Willmann
d1554ecb78 gbproxy/test: Add and call cleanup_test function
This (currently empty) function is meant to contain code that cleans
up the left-overs of the test functions. This is needed by the next
commit to reset the RAND_bytes sequence.
2015-10-13 10:18:34 +02:00
Daniel Willmann
044ce5fb84 gprs: Use RAND_bytes for p-tmsi
[hfreyther: Link to libcrypto, include header, add uint8_t* cast]
2015-10-13 10:00:16 +02:00
Jacob Erlbeck
133e8624ef sgsn/test: Really parse received DL LLC messages
Currently just the number of intercepted downlink messages is counted
and eventually checked. The contents of the messages is lost. The
PTMSI contained in ATTACH/RAU Accept messages is just 'guessed' by
resetting the random number generator after reference PTMSIs have
been generated. While this works with rand_r, RAND_bytes cannot be
forced to recreate a certain number sequence this way (unless the
backend is replaced).

This commit changes that behaviour so that the last received msgb is
kept and decoded. The PTMSI that has been assigned by the SGSN is
then taken in the affected test cases and used instead of a 'guessed'
one. This is similar to how a real MS would react to the Accept
message.

Sponsored-by: On-Waves ehf
2015-10-13 09:59:34 +02:00
Jacob Erlbeck
cf15187458 sgsn/test: Add and call cleanup_test function
This (currently empty) function is meant to contain code that cleans
up the left-overs of the test functions. This will be needed by the
next commit that will store the last received msgb for later inspection.

Sponsored-by: On-Waves ehf
2015-10-13 09:58:29 +02:00
Holger Hans Peter Freyther
a777c9ee3d osmux: Allow to listen to a specific address
For a setup with multiple network interfaces be able to pick
the one that osmux should be used/visible.
2015-10-12 20:06:16 +02:00
Holger Hans Peter Freyther
9861c122dd sgsn: Fix pattern for too long msisdn
We don't care how many bytes the length has but the
destination we want to copy to.

Fixes: CID#1296813
2015-10-12 11:06:34 +02:00
Holger Hans Peter Freyther
fa07b489dc Revert "gprs: Use RAND_bytes for p-tmsi"
The commit not compiling/linking should have been a strong
indicator that it has not been tested either.

This reverts commit 6cf0249dac.
2015-10-12 09:55:59 +02:00
Holger Hans Peter Freyther
f3316e30d6 mgcp: Use the right bind addresses for NET and BTS
This API is a bit unfortunate as the caller will also
access the endpoint directly. E.g. like this:

        output = bsc_mgcp_rewrite(...,
                      mgcp_net_src_addr(endp),
                      endp->net_end.local_port, -1,

In terms of "terminology" the "net" was meant to be bad
internet and the "bts" is the local and trusted network
segment. With this terminology the "bts" would be the
call-agent/MGW and "net" where the BSCs will send data
to but that is not the case and terminology actuallys
refers to:

	* net: The addresses exposed to the entity that
	made the MGCP call
	* bts: The system where we get our data for the
	local audio flow.

Fix the method but leave the API as it is. Use the net_end
in the net_src method and the bts_end in the bts_src method.
2015-10-12 09:37:35 +02:00
Holger Hans Peter Freyther
d74cce266b Merge branch 'zecke/features/osmux-reliability'
Not verified that the audio handling is working. I saw a circuit
set-up of the call though.
2015-10-12 09:11:32 +02:00
Holger Hans Peter Freyther
6962127982 osmux: Make sure that bigger Osmux ids actually fit
We put a signed integer into this string but did not account
for the newline and for the terminating NUL of the string. Add
the newline to the string and add one for NUL. Spotted while
accidently having a CID of 255.
2015-10-12 09:11:25 +02:00
Holger Hans Peter Freyther
1afe7c7fe5 osmux: Remember the allocated CID and make sure it is released
There appears to be a leak of CIDs:
 <000b> mgcp_osmux.c:544 All Osmux circuits are in use!

There are paths that a CID had been requested and never released
of the NAT. Remember the allocated CID inside the endpoint so it
can always be released. It is using a new variable as the behavior
for the NAT and MGCP MGW is different.

The allocated_cid must be signed so that we can assign outside
of the 0-255 range of it.

Fixes: OW#1493
2015-10-12 09:11:25 +02:00
Holger Hans Peter Freyther
20626dde8f osmux: Enforce Osmux only global and per BSC configuration
Extend the osmux only setting from the MGCP MGW to the NAT. This
is applied when an endpoint is allocated and/or when the allocation
is confirmed by the remote system.

Not tested. The impact should only be when the new option is
being used.

Fixes: OW#1492
2015-10-12 09:11:25 +02:00
Holger Hans Peter Freyther
6598ded5cd osmux: Allow to enforce using Osmux for the client
Some systems only want to use Osmux. In case only Osmux
should be used fail if it has not be offered/acked.

Client:

Verified On, Off and Only with X-Osmux: 3 and without this field.
<000b> mgcp_protocol.c:823 Osmux only and no osmux offered on 0x14
<000b> mgcp_protocol.c:884 Resource error on 0x14

NAT:

Not tested and implemented

Fixes: OW#1492
2015-10-12 09:11:25 +02:00
Holger Hans Peter Freyther
15a40db606 osmux: Add introspection for osmux.
* Print number of used CIDs for the system
* Hopefully this is just the beginning
2015-10-12 09:11:25 +02:00
Holger Hans Peter Freyther
b45e4d80b6 osmux: Do not divide the number of bytes by eight.
sizeof(uint8_t) == 1 and there is no need to create an array
with 16 bytes and then only use the first two of them. This
means the CID range is from 0 to 127 and we should be able
to extend this to 256 by changing the array size to 32. Update
the testcase now that we can have more than 16 calls with Osmux.
2015-10-12 09:11:25 +02:00
Holger Hans Peter Freyther
641d387409 osmux: Test cid allocation and de-allocation
* Test that one can get an id
* That they are assigned predicatble right now
* That returning them will make the number of used ones go down
* That allocating more will fail
2015-10-12 09:11:25 +02:00
Daniel Willmann
2aedfbdfe1 libmsc: Use RAND_bytes to generate a token
[hfreyther: Add cast to uint8_t to fix compiler warning]
2015-10-12 09:07:45 +02:00
Daniel Willmann
62a63f54a6 libmsc: Use RAND_bytes to choose auth tuple
[hfreyther: Fix compiler warning about unused variable]
2015-10-12 09:06:59 +02:00
Daniel Willmann
6cf0249dac gprs: Use RAND_bytes for p-tmsi
[hfreyther: Link to libcrypto, include header, add uint8_t* cast]
2015-10-12 09:05:48 +02:00
Daniel Willmann
cdeb815c78 libmsc: Use RAND_bytes when choosing a tmsi
Require openssl version to be >= 0.9.5 because we rely on the RAND_bytes
return value.

[hfreyther: Add cast to uint8_t*]
2015-10-12 09:03:15 +02:00
Holger Hans Peter Freyther
b3cbd9aa3b mgcp: Indicate where the sending failed
The log message does not help and says where the data is
being sent to. This is because we have both a RTP and RTCP
port. Remember if we failed with RTCP or RTP and improve
the log message.

I was searching a case where the port was bound to a local
address (e.g. 127.0.0.1) and tried to send the data to a
public one (e.g. 8.8.8.8).
2015-10-08 19:15:41 +02:00
Neels Hofmeyr
0e62e595a6 Add OAP design document.
Sponsored-by: On-Waves ehf
2015-10-07 18:59:55 +02:00
Neels Hofmeyr
06cfe00c71 gsup: factor out header composition & sending.
Move IPA header composition and sending to new static gsup_client_send() (so I
can use it in the upcoming OAP code).

Sponsored-by: On-Waves ehf
2015-10-07 18:59:01 +02:00
Holger Hans Peter Freyther
8b4e584621 Merge branch 'zecke/features/amr'
Fix AMR support for the BSC, remove code duplication, make it
less prone to error.
2015-10-02 15:30:38 +02:00
Holger Hans Peter Freyther
7a77d0155f amr: Attempt to unbreak the AMR support in the BSC
The signature of mr_config and the BSC implementation didn't
match and the compiler was warning about it:

osmo_bsc_api.c:530:2: warning: initialization from incompatible pointer type
 .mr_config = bsc_mr_config,
 ^
osmo_bsc_api.c:530:2: warning: (near initialization for ‘bsc_handler.mr_config’)

Change the mr_config again and provide an implementation
that will set the ms and bts data structure. It would be
better to put the size outside of the IE but I am not going
to change it right now. It would also be nice to either move
the AMR setting into the "nitb" structure or have the msc
data be used _after_ the bts settings. This needs to be
cleaned up in the next step.

Manually verified by placing a MO call and checking that
both the channel mode modify and the mode modify request
contain the multi rate config with the rate mr config
(length two bytes, version 1, icmi==1, no start mode being
set).
2015-10-02 15:30:29 +02:00
Holger Hans Peter Freyther
a174a47811 amr: Kill more duplication and let the code work one of the modes 2015-10-02 15:30:29 +02:00
Holger Hans Peter Freyther
615ed46a6a amr: Instead of putting ms/bts into the same struct.. use it twice
This way a lot of if/else can just be killed by the caller deciding
which of the two instances to use.

I have copied both branches to new files, replace bts for ms in one
of them and ran diff on it. There is no difference.
2015-10-02 15:30:29 +02:00
Holger Hans Peter Freyther
11cb7a9fd9 amr: Remove some code duplication in preparation
Merge two copies into a local static helper function. The format
of the message will change and then it is easier to modify it in
one place than in two.

Sadly the original patch was merged before this clean-up so do
the clean-up as second step.

Conflicts:
	openbsc/src/libbsc/abis_rsl.c
	openbsc/src/libbsc/gsm_04_08_utils.c
2015-10-02 15:30:28 +02:00
Neels Hofmeyr
130be40c3e sgsn_main: in -h, print default config file 2015-09-24 17:29:08 +02:00
Holger Hans Peter Freyther
d3496aed69 debian: Attempt to fix packaging and point to a meaningful readme
The empty README file has been removed but the package still tries
to install it.
2015-09-24 16:45:21 +02:00
Holger Hans Peter Freyther
3e4e8cfb74 vty: Change the return type from enum to int
clang complained that different enums are mixed with the
return type and we actually want this to be an int now.
2015-09-24 15:39:30 +02:00
Holger Hans Peter Freyther
925504bfe0 gbproxy: Add quirk commands to allow upgrade from pre-release
The pre-release didn't add a newline after the apn and the patching
pattern command. Create a quirk command that combines both. The
pre-release didn't include a differentation between routing and
patching.

The TLLI handling has a different and more generic name now. Make
it handle the old one that is actively used.

Add a file with the broken format and the standard config file
test should pick it up.
2015-09-24 10:28:43 +02:00
Neels Hofmeyr
e57e0fa701 bsc_nat: Fix 1 log error output of wrong variable. 2015-09-23 19:02:36 +02:00
Andreas Eversberg
732665269e Add full AMR multirate IE support with VTY config for MS and BTS side 2015-09-22 16:46:27 +02:00
Neels Hofmeyr
354d1f3084 osmo-nitb: obsess about --help formatting.
Make every line use same punctuation style ('.' at the end and start in caps).
Insert spaces to have all help texts in a column.
2015-09-15 19:36:19 +02:00
Neels Hofmeyr
c6a8d09b78 Remove empty README.
This README's content has moved to openbsc/README. This is just an empty
file now.
2015-09-15 19:36:19 +02:00
Neels Hofmeyr
51cf69cdb4 openbsc/configure.ac: check for pcap/pcap.h.
The build process requires pcap/pcap.h in openbsc/src/utils/meas_pcap2db.c, but
the configure script did not check for that file.
2015-09-15 19:36:19 +02:00
Holger Hans Peter Freyther
4b4a187b4f Merge branch 'zecke/features/rtp-bridge'
* Implement the rtp-bridge mode for MNCC
* Audio doesn't flow through the NITB at all
* It only works with IPv4 BTSes right now
* We need to select an audio codec way too early
* No tandem free operation
* Early assignment always equals TCH/F
2015-09-14 10:53:35 +02:00
Holger Hans Peter Freyther
53122b09d0 mncc: Use the default codec from the built-in mncc mode
In case of the RTP bridge mode we need to select the codec
ourselves. Rely on the same (incomplete) codec selection that
can be done using the mncc-int configuration node. This might
gain bearer capabilities support.

In case of a SDCCH a TCH/F will be attempted to be assigned.
This is an open issue for both modes and there should be a
preference for full or half-rate channels somewhere.
2015-09-14 10:12:29 +02:00
Holger Hans Peter Freyther
c21dcb20e5 mncc: Implement CRCX->MDCX for handover for direct rtp mode
Implement sending MDCX on the newly allocated channel and send
the data to the same destination as the currently connected one.
This way the receiver can implement RTP RFC Appendix A.1 and
deal with the new source.
2015-09-14 10:12:29 +02:00
Holger Hans Peter Freyther
c8a6c13e4e mncc: Implement the direct RTP mode for ip based systems
For the LCR rtp-bridge audio should directly flow to the
remote system. In contrast to the original patch audio
will now flow directly from the BTS to the remote system.
This assumes that BTS and the remote system are in the
same network segment and can directly communicate.

There are various limitations in the first iteration of
the implementation:

We could (and in the future) should delay the assignment
but currently we are forced to pick the channel and move
it to the audio state. In case we are located on a SDCCH
we always need to change but if we are on a TCH we could
send the ipa.CRCX and change the audio state a lot later.
The net effect is that the audio codec selection needs to
be done in the NITB code and not in the system connected
to it.

This only works with ip based systems. For E1 systems one
could still use the RTP socket or even try to move this
out of the process.

There is no code for handover handling and it relies on
the remote system dealing with the SSRC change of the
system.
2015-09-14 10:12:29 +02:00
Holger Hans Peter Freyther
ffbf45e09e mncc: Update the protocol to match LCR
This adds the protocol definition for the RTP bridge extension
of Andreas Eversberg and bumps the protocol version.

I added the missing mncc mappings from value to string.

[ 5cf8fb10ea3addcae74d37f4dbf1c1be664df53e protocol extension
  5dac90de38990b188f499c602bf18a4f232070e8 payload extension]
2015-09-14 10:12:29 +02:00
Alexander Chemeris
08c508f84a msc: Add channel information to the meas_feed, bump version to v1. 2015-09-14 10:08:41 +02:00
Pablo Neira Ayuso
d721579a6a osmux: fix show online-help
Before:

    <command id='osmux dummy (on|off)'>
      <params>
        <param name='osmux' doc='RTP multiplexing' />
        <param name='dummy' doc='Enable dummy padding' />
        <param name='on' doc='Disable dummy padding' />
        <param name='off' doc='(null)' />
      </params>

After:

    <command id='osmux dummy (on|off)'>
      <params>
        <param name='osmux' doc='RTP multiplexing' />
        <param name='dummy' doc='Dummy padding' />
        <param name='on' doc='Enable dummy padding' />
        <param name='off' doc='Disable dummy padding' />
      </params>
    </command>

Note the 'null' string in 'off'. Reported by Holger.
2015-09-07 11:31:17 +02:00
Ciaby
92360b15e3 Add SMPP support in the debian build, include libsmpp34-dev as a dependency. 2015-09-04 16:28:34 +02:00
Holger Hans Peter Freyther
614aba391d mgcp: Fix grammar, clean-up return codes
Mike's patch included clean-ups I want to apply separately and
change them a bit. If we return from an else we don't need to
put the else.

* Try the E1 trunk first
* Then try a local virtual trunk
* Fail if none of the above returned
2015-09-04 16:05:30 +02:00
Michael McTernan
79135acbb8 mgcp: Remove use of hardwired @mgw from endpoint IDs.
Remove the host portion of the endpoint Id.  This requires less
configuration and we are probably fine to trust that MGCP only
received messages designated for it.
2015-09-04 16:05:30 +02:00
Harald Welte
e5ba92e7be system_information.c: Distinguish two previously identical log msgs 2015-09-04 06:25:48 +02:00
Harald Welte
e18f78e81d Fix neighbor channel list generation for 1900 MHz PCS band
In the 1900 MHz PCS band, we always generated neighbor cell lists
consisting of only a single neighbor cell, rather than al the
configured BTSs.
2015-09-04 06:25:48 +02:00
Holger Hans Peter Freyther
8fc568466c debian: Require ares for the SGSN and GGSN resolving 2015-08-23 18:06:09 +02:00
Holger Hans Peter Freyther
0190d790b6 debian: Add libssl-dev for the NAT 2015-08-23 18:05:14 +02:00
Holger Hans Peter Freyther
c390ae8eaf mgcp: Allow to bind to different ports for net/bts ports
When using multiple interfaces on a system one can now configure
which will be served for the BTS ports and which will be served
for the network. The direct usage of source_addr is now only to
initialize the MGCP receiving port itself.
2015-08-20 17:24:03 +02:00
Holger Hans Peter Freyther
e6ed009a36 mgcp: Begin to separate network and bts endpoints
Make it possible to bind the call-agent to a specific IP address
and the network and bts end to different ip addresses. Begin by
clarifying which source ip address we want to have.
2015-08-20 14:58:19 +02:00
Holger Hans Peter Freyther
ceef936ea8 mgcp: Add transcoding from PCMU as well
Use the existing ulaw encode/decode to support PCMU as well.
The MERA VoIP switch has some severe issues with the GSM codec
and it appears easier to enable transcoding for it.

The mera switch doesn't appear to cope with codec change
between a SIP 180 trying and the 200 ok connection result.

Inserting the codec is touching too many places. Ideally we
should have the transcoding function as pointer in the struct
as well but the arguments differ.. so it is not a direct way
forward.
2015-08-19 15:44:44 +02:00
Pablo Neira Ayuso
57e95a22f0 osmux: add option to pad the circuit with dummy messages
Iridium is a satellite network which operates a GPRS-like that allows you to
get speeds up to 128kbit/s. However, it takes from 5 to 6 secs to get the
bandwidth allocated, so the conversation is garbled during the time.

This patch uses the new dummy padding support in libosmo-netif that is
controlled through the osmux osmux_xfrm_input_open_circuit().

This includes a new VTY option for osmux.
2015-08-19 00:17:31 +02:00
Harald Welte
ecff2424e5 Use 'ROUTING AREA' consistently, not 'ROUTEING AREA'
The spec unfortuantely uses both terms and has no consistent spelling,
but in our logging output we can at least try to be consistent.
2015-08-18 19:35:02 +02:00
Harald Welte
b9845f937e GSM/GPRS 04.08: Don't print numeric mobile identity types
I guess none of our users knows what a mi_type=0x02 is, but most would
know what an IMSI or a TMSI is.  So let's use the newly introduced
gsm48_mi_type_name() function to fix this.
2015-08-18 19:35:02 +02:00
Harald Welte
6b39feedc7 GMM: fix format string compiler warning 2015-08-18 19:35:02 +02:00
Harald Welte
601cf12f81 GMM: Don't use DGPRS logging category from GMM 2015-08-18 19:35:02 +02:00
Harald Welte
eb98c74fb1 GMM: use MMCTXP whenever possible to include MS identity in log output 2015-08-18 19:35:01 +02:00
Harald Welte
22df4ac848 LLC: Don't dispatch XID frames into GMM
For some odd reasons the XID is not a separate SAPI but has been kludged into
the GMM SAPI.  This means we ahve to be careful not to dispatch XID frames into
GMM.  We do this by introducing an explicit check for UI frames before the
dispatch to GMM.

The previous code already was doing "the right thing" but printed occasional
messages like "gprs_gmm.c:2082 Unknown GSM 04.08 discriminator 0x01: 01 00 0e
00 32 11 03 16 01 90 63 28 0b".  Those should be gone after this patch.
2015-08-18 19:35:01 +02:00
Harald Welte
78fa99103d LLC: Don't feed length=0 frames to SNDCP / GMM 2015-08-18 19:35:01 +02:00
Harald Welte
6a19dd0d31 GMM: add hexdump in case of unknown pdisc/msgtype 2015-08-18 19:35:01 +02:00
Harald Welte
9450882901 sgsn: make all SGSN timers configurable via the VTY 2015-08-18 19:35:01 +02:00
Andreas Eversberg
39ba248608 Send RADIO LINK TIMEOUT value via OML attribute to BTS
The same radio link timeout value is used for BTS and MS side.
2015-08-17 16:43:14 +02:00
Andreas Eversberg
4d4944a07d Add option to set RADIO LINK TIMEOUT value via VTY 2015-08-17 16:31:35 +02:00
Andreas Eversberg
93e795c1fd Add check for non existing lchan at tch_frame_down()
Traffic cannot sent to BTS, if there is (currently) no logical channel
associated with the transaction.

This happens, if TCH traffic is received from upper layer, but there is
no lchan available before completing immediate assignment, handover or
assignment process.

[hfreyther: The code has not been moved to tch_frame_down
but the issue looks similiar]
2015-08-17 16:21:24 +02:00
Holger Hans Peter Freyther
4c97435b35 mgcp: Test we don't crash on the NAT dummy MGCP message
We want the port and IPv4 address to be extracted but don't
expect any change in audio codecs.
2015-08-17 15:50:01 +02:00
Holger Hans Peter Freyther
d17bc7b3a8 mgcp: Avoid crashing when rtpmap is not complete
The NAT sends an incomplete SDP file for the purpose of informing
the BSC about the remote IP/PORT early. The case of an incomplete
SDP file was not considered. Check if there is a codec and if not
skip it.

TODO: We need to have a better end-point life cycle test.
2015-08-17 15:22:30 +02:00
Holger Hans Peter Freyther
a334e90ddf Merge branch 'zecke/features/sdp-codec-handling'
Move forward while preserving the legacy handling. Beging to
extract SDP rtpmap information and select codecs atfer this.
It is a foundation we can now build further and better check
ons.
2015-08-14 15:48:54 +02:00
Holger Hans Peter Freyther
aeadf261e5 mgcp: Allow to enforce that the codecs need to match
We have a lot of legacy that I am afraid to break. We have
everything in place to make a good codec selection (e.g. if
we can avoid transcoding, pick the one with best quality or
the lowest speed). Right now I have a specific case where
from all options I want to pick GSM. Guard the codec compat
check behind the disallow transcoding option to make sure
to not break legacy application.
2015-08-14 15:43:06 +02:00
Holger Hans Peter Freyther
ca7d05bdb9 mgcp: Turn SDP file parsing in a two stage process
First collect everything we know and the mapping. E.g. a genuis
could remap "3" to "AMR" so we only know the codecs once we are
at the end of the SDP file. Once we have collected everything we
can select the audio codecs. The current code is compatible in
that two codecs will be selected regardless of if they make any
sense or not.

mgcp_set_audio_info could re-use some of our codec information
but then the caller in the MGCP protocol needs to be updated as
well as we use the "I: GSM" information to derive the codec from
there.
2015-08-14 11:13:48 +02:00
Holger Hans Peter Freyther
a611da8407 mgcp: Move the SDP handling into a separate file/module
The SDP file handling will get more complicated in terms of
codec selection so let's remove it from the protocol handling
before we start blowing it up in size.
2015-08-14 09:24:11 +02:00
Holger Hans Peter Freyther
0eaad4f216 mgcp: Remove unused parsing data struct
This struct was removed when we switched to strtok_r for
parsing the data. Remove the left-over.
2015-08-14 08:54:58 +02:00
Holger Hans Peter Freyther
e9f7c9925c nat: Forward SDP files with multiple payload types in it
The parsing code assumed that there will be a single payload
type and this assumption is clearly wrong. Forward all of the
payload types. The code is still only extracting the first
type from the list. The variable name has been renamed to
reflect this.
2015-08-13 18:53:10 +02:00
Holger Hans Peter Freyther
29d58b734d sms: Attempt to plug memory leaks seen at Rhizomatica
Using the talloc leak report we see that there are some msgb's
that are allocated for SMS but we don't have transactions or
SMS around. We need to improve the name of the messages to
uniquely dscribe where they are from but the obvious leak does
occur in this routine.

The no available transaction id is most likely the case where
we leak memory. This should not occur and shows another issue
with the smsqueue/smpp handling. It doesn't explain the subscr
reference count issue either.

Extract of the leak report:

  GSM 04.11                      contains   1160 bytes in   1 blocks (ref 0) 0x2517dc0
  GSM 04.11                      contains   1160 bytes in   1 blocks (ref 0) 0x24b56e0
  GSM 04.11                      contains   1160 bytes in   1 blocks (ref 0) 0x23e7930
2015-08-12 13:38:22 +02:00
Holger Hans Peter Freyther
c9dbe3c7b1 paging: Provide information about pending requests
For debugging it is nice to know how many requests are
pending. Simply count it and print it besides the paging
part.
2015-08-08 20:49:04 +02:00
Holger Hans Peter Freyther
2f25764e51 Merge branch 'zecke/fixes/subscr-leak'
At the rhizomatica sites some unauthorized subscribers have a
last used from long time ago but a bigger reference count. This
means that we have an unbalanced subscr_get/subscr_put that we
need to investigate. These two fixes are genuine fixes but are
unlikely to fix the issue I am not understanding yet.
2015-08-08 20:47:02 +02:00
Holger Hans Peter Freyther
5425e5ea27 subscr: Fix subscr refcount issue in case of message error
In case the SMPP payload didn't include the right fields we
would leak the subscr reference count.
2015-08-08 20:46:50 +02:00
Holger Hans Peter Freyther
8159455506 subscr: Fix potential subscr ref count issue
In case the subscriber is currently busy we would omit the
subscr_put. This seems to be very hard to hit as the subscr
need to be active and at the same time be selected for the
purge operation.
2015-08-08 20:46:49 +02:00
Holger Hans Peter Freyther
e019b564ec Merge branch 'zecke/changes/paging-order'
Various paging clean-ups. I couldn't re-produce the assert that
was hit by Rhizomatica in the subscriber code. Let's clean things
up a bit to avoid some of the potential issues this code had.

Always stop paging regardless of where the subscriber is at the
time of the cancellation.
2015-08-08 20:44:42 +02:00
Holger Hans Peter Freyther
eb48cafac9 paging: Forget we were paging after the dispatch
So in case somebody is starting paging from within a paging
expired callback we would dispatch the paging request right
away with the same failure.
2015-08-03 12:02:14 +02:00
Holger Hans Peter Freyther
778c7d1544 paging: Stop paging everywhere before dispatching any signal 2015-08-03 12:02:14 +02:00
Holger Hans Peter Freyther
ba43365e96 paging: Go through all BTS to stop paging
As the comment says we should not rely that the paging
occurs on the current LAC. We might page at more BTS.
Walk all the BTS to stop paging. No callbacks will be
issued by this stop operation.
2015-08-03 12:02:14 +02:00
Holger Hans Peter Freyther
469f992b2b paging: In case paging failed stop it everywhere
In case we can't page on a BTS then stop it everywhere. The
callers of paging_request assume that this is kind of an
atomic operation and we should help with that.
2015-08-03 12:02:14 +02:00
Holger Hans Peter Freyther
b618c7ec9b paging: Move the silent_call code to use the subscriber request
Coordinate with the normal subscriber channel requests instead
of going to page ourselves. This might lead to getting a channel
that is of a different type though.
2015-08-03 12:02:14 +02:00
Holger Hans Peter Freyther
daaea0c84f 64bit: Fix compiler warnings in regard to 64bit
vty_interface_layer3.c:584:4: warning: format '%d' expects argument of type 'int', but argument 3 has type 'long unsigned int' [-Wformat=]
    sizeof(subscr->extension)-1, VTY_NEWLINE);
2015-08-03 12:01:44 +02:00
Max
5c06e4045a use non-vararg functions if possible
Signed-off-by: Max <max.suraev@fairwaves.co>
2015-08-01 23:51:52 +00:00
Holger Hans Peter Freyther
145e2532f4 Merge branch 'zecke/features/no-tmsi'
When two phones use the same TMSI and no A3A8 is possible
we could end in a hard to detect issue. Assume that the IMSI
will not clash and we have issues for foreign simcards.
2015-08-01 23:49:34 +00:00
Holger Hans Peter Freyther
666e36aea9 nitb: Add a mode to not use TMSI for normal operation
In case foreign simcards are used we can not do authentication
and ciphering. In case a TMSI is re-used too early and we do
page using TMSI we can't know which of the two MS is responding
to us. We could change the "secure channel" routine to ask for
the IMSI and only then stop the paging.

As we don't have ciphering there is not much use in using the
TMSI. Add a mode "no assign-tmsi" that will not assign the TMSI
during LU. Now CM Service Request and Paging Response  will
work using the IMSI. There can't be a clash with that.

[ciaby fixed the vty write to use the right name]
2015-08-01 23:49:16 +00:00
Holger Hans Peter Freyther
5f8a0c5c70 nitb: Be less strict about the reject cause
When we can't find the TMSI then the subscriber is not in our
VLR. We have not consulted with the HLR and it is better to not
use such a severe error code.
2015-08-01 23:49:16 +00:00
Holger Hans Peter Freyther
d15409876c build: Include sys/socket.h for AF_UNSPEC 2015-08-01 23:46:56 +00:00
Holger Hans Peter Freyther
4672059d94 mgcp: Include enough socket data structures to build on freebsd
in_address is not 'accidently' included by FreeBSD when we include
the osmocom/core/select.h header file. We need to include a bit
more.

In file included from mgcp_protocol.c:38:
../../include/openbsc/mgcp_internal.h:134:21: error: field has incomplete type 'struct sockaddr_in'
        struct sockaddr_in forward;
2015-08-01 23:36:39 +00:00
Holger Hans Peter Freyther
a2c41c42b1 sms: Fix the non-SMPP mode of the test
List needs to be executed from within the right configuration
node to see if it is available or not. list on the toplevel
will uncoditionally show "smpp" as part of the logging config.
2015-07-13 11:30:13 +02:00
Holger Hans Peter Freyther
1e365477ee bsc: Rename core_ncc to core_mnc
Struct osmo_msc_data contains int core_ncc, which is actually the
MNC part of the PLMN, not to be confused with the Network Colour
Code.

The following patch renames this field for clarity and consistency
with the standards.
2015-07-13 11:06:10 +02:00
Holger Hans Peter Freyther
14a434b9d6 Merge branch 'zecke/features/smpp-route' 2015-07-13 10:42:17 +02:00
Holger Hans Peter Freyther
7c19c6b406 sms: Do not go through the routing a second time
If we have tried SMPP first and it was not routable, and then
tried the local delivery there is no point in trying SMPP with
the same parameters again. Leave early and return unknown sub
to the caller.
2015-07-13 10:39:51 +02:00
Holger Hans Peter Freyther
42cf2e03c9 sms: Add a way to always route SMS through SMPP systems
default-route would only be looked at after there has been
no subscriber in the local database. Depending on the setup
this is not what one wants. This has been discussed at the
OsmoDevCon and there have been hacks in some branches. Let's
introduce a VTY command to select if SMPP should be consulted
first and then fallback to the current behavior.
2015-07-06 16:50:19 +02:00
Holger Hans Peter Freyther
dcbc83355e sms: Simplify the return handling for SMPP routes/unroutable 2015-07-06 16:40:51 +02:00
Holger Hans Peter Freyther
e3c391e8d0 sms: Put the try_deliver into the header file
Even if it is using BSC/NITB types let's put it in the header
file than just declaring it at a place that could bitrot in a
way that doesn't lead a warning.
2015-07-06 16:40:01 +02:00
Holger Hans Peter Freyther
af1b968b22 sms: Move the routing of the sms to a separate function
The "default-route" for SMPP will be used after a local
subscriber look-up. Sometimes we want to route everything
to SMPP. Make this possible by changing this routine.
2015-07-06 16:04:41 +02:00
Holger Hans Peter Freyther
b69518f383 configure: Do not link all applications against libgsm
Use the same trick as done by the dlopen check to not
have everyone link against the library.
2015-07-02 09:51:31 +02:00
Holger Hans Peter Freyther
58ec15c4ed configure: No need to check for crypt here
We just link to libosmovty and if it requires crypt internally it
needs to link to that (and not us). This looks like a left-over
from when we moved the VTY code out of OpenBSC
2015-07-02 09:40:03 +02:00
Holger Hans Peter Freyther
9f95ae8885 nat: Use RAND_bytes instead of /dev/urandom
We don't need to consume all the entropy of the kernel but can
use libcrypto (OpenSSL) to generate random data. It is not clear
if we need to call RAND_load_file but I think we can assume that
our Unices have a /dev/urandom.

This takes less CPU time, provides good enough entropy (in theory)
and leaves some in the kernel entropy pool.
2015-07-01 08:34:16 +02:00
Holger Hans Peter Freyther
8ee53ed9ec Merge branch 'zecke/features/auth'
Introduce another authentication scheme using MILENAGE. In the
future reading from /dev/urandom will be replaced with libcrypto.
2015-07-01 08:19:51 +02:00
Holger Hans Peter Freyther
694d98042f nat: After we identified the bsc check the key
We are using the token to find the right bsc_config and
then we can use the last_rand of the bsc_connection to
calculate the expected result and try to compare it with
a time constant(???) memcmp.
2015-07-01 08:16:41 +02:00
Holger Hans Peter Freyther
e2ac6b77fe bsc: Check for the rand and then generate a res
Check if the NAT has sent 16 bytes of RAND and if a key
has been configured in the system and then generate a
result using milenage. The milenage res will be sent and
noth the four byte GSM SRES derivation.
2015-07-01 08:16:41 +02:00
Holger Hans Peter Freyther
9705671025 nat: Send 16 bytes of rand to the BSC and remember it
Generate 16 byte of random data to be used for A3A8 by
the BSC in the response. We can't know which BSC it is
at this point and I don't want to send another message
once the token has been received so always send the data
with an undefined code. The old BSCs don't parse the
message and will happily ignore the RAND.

/dev/urandom can give short reads on Linux so loop
around it until the bytes have been read from the kernel.
2015-07-01 08:16:40 +02:00
Holger Hans Peter Freyther
fce6971fe3 nat: Provide access to /dev/urandom for the code
Instead of doing open/read/close all the time, open the
FD in the beginning and keep it open. To scare me even
more I have seen /dev/urandom actually providing a short
read and then blocking but it seems to be the best way
to get the random byes we need for authentication.

So one should/could run the cheap random generator on
the system (e.g. haveged) or deal with the NAT process
to block.
2015-07-01 08:16:40 +02:00
Holger Hans Peter Freyther
8a8df80772 bsc/nat: Fix the structure of the identity request message
Unfortunately the basic structure of the response is broken.
There is a two byte length followed by data. The concept of
a 'tag' happens to be the first byte of the data.

This means we want to write strlen of the token, then we
want to write the NUL and then we need to account for the
tag in front.

Introduce a flag if the new or old format should be used.
This will allow to have new BSCs talk to old NATs without
an additional change. In the long run we can clean that up.
2015-07-01 08:16:40 +02:00
Holger Hans Peter Freyther
0363d1bb97 nat: Close the connection after we couldn't find the user
In case the token was not correct, just close the connection.
It is not clear that forcing a new TCP connection is going to
give us any extra security here. But with the upcoming auth
handling it does make sense to have both case look similar.
2015-07-01 08:16:40 +02:00
Holger Hans Peter Freyther
aa0cecd9b7 nat: Factor out the config by token search
In the upcoming authentication improvements it is nice to
separate the finding of the config from the post-allow
handling of it.
2015-07-01 08:16:40 +02:00
Holger Hans Peter Freyther
2dd18bdd87 nat: Add size check for the payload
The msgb will always have these bytes but it is better practice
to verify that the message really has space for the two bytes.
2015-07-01 08:16:40 +02:00
Holger Hans Peter Freyther
57ee780789 bts: Arfcn can never be smaller than 0
Remove the condition because it can never be true.

Fixes: Coverity CID#1307793
2015-06-20 18:45:35 +02:00
Andreas Rottmann
797eb7b592 build: avoid spurious hard dependency on libosmo-sccp
In the libfilter source code, which is built regardless of --enable-nat,
headers from libosmo-sccp were used, thus causing a build failure (see
below) when building without --enable-nat, and libosmo-sccp not being
installed (or being installed in a prefix not otherwise included in the
build).

The build fails like this:

In file included from ../../../src/libfilter/bsc_msg_filter.c:27:0:
../../../include/openbsc/bsc_nat_sccp.h:27:37: fatal error: osmocom/sccp/sccp_types.h: No such file or directory

As the includes seem not to be actually needed, this change fixes the
issue by just omitting them.
2015-06-19 20:58:35 +02:00
Andreas Rottmann
4bb3fccb75 Fix "make distcheck"
Running "make distcheck" failed trying to generate ".version" into the
read-only unpacked source directory. Actually shipping ".version" in the
tarball fixes that.
2015-06-19 20:57:48 +02:00
Andreas Rottmann
b25c8342cc Fix build wrt. missing CFLAGS constituents
When libosmo-netif and/or libosmo-abis are installed in distinct
prefixes, the build failed with non-found headers.
2015-06-19 20:56:53 +02:00
Michael McTernan
c58a1e573b Fix GSM900 ARFCN range check
Allow ARFCN 0 to be used in GSM900 band.
2015-06-19 20:51:43 +02:00
Holger Hans Peter Freyther
ce97a06fa3 bsc: Attempt to fix crash when sending a SCCP CREF message
There was no context for the SCCP CREF message and this means
that the msc_con was a plain NULL pointer that was dereferenced
and the application would crash.

Use the new API to pass the incoming MSC Connection which sould
be used for the SCCP CREF message as context. The code has not
been fed with an actual SCCP CR message.
2015-06-15 09:47:45 +02:00
Holger Hans Peter Freyther
0958938d4e sgsn: Simplify finding/using the first address of the result
The loop was used to print all returned addresses but we can
simply pick the first one. This is fixing a coverity issue that
the loop will be executed eaxactly once (and that was on
purpose).

Simplify the code and just take the first element (which might
be NULL).

Fixes: Coverity CID#1302852
2015-06-02 09:51:32 +02:00
Holger Hans Peter Freyther
f2e114ac85 sgsn: seleted_apn_str might be NULL do not strcpy
The subscriber might simply not be allowed to use the APN
that was specified. So selected_apn_str might very well be
NULL.

Fixes: Coverity CID#1302853
2015-06-02 09:46:32 +02:00
Holger Hans Peter Freyther
65b0efe56e sgsn: Check the return value of osmo_fd_register
We can't do much in case the fd is failing to be registered.
There should be a timeout that is catching this and it might
be able to repair it self.

Fixes: Coverity CID#1302854
2015-06-02 09:46:11 +02:00
Alexander Chemeris
c36a13b073 libbsc: Move SIs update/generation for a BTS into a separate function.
The code to do that doesn't belong to the control interface, so
abstract it out to a separate function gsm_bts_set_system_infos().

[hfreyther: Fix the coding style...]
2015-06-02 08:43:29 +02:00
Holger Hans Peter Freyther
9cb249bf84 sgsn: Do not search the name with the "domain" name attached to it
In case the query for "hostname" will fail c-ares will append the
domain name of /etc/resolv.conf and query again. We don't want that
so claim we provide a list of domain names and then don't provide
any.

I didn't intend to have pushed the c-ares code to master yet.
2015-06-01 18:46:12 +02:00
Ivan Kluchnikov
5fd0c64e0a gsm_04_08: Use osmo_assert for transt->conn and conn only in case of paging succeeded
setup_trig_pag_evt function can receive parameter conn = NULL, if T3113 expires.
2015-05-29 15:14:23 +02:00
Holger Hans Peter Freyther
b7ae0b34f9 ggsn: The id is a uint32_t don't print it as signed
This was noticed as I started to use UINT32_MAX for
dynamically created GGSNs.
2015-05-29 15:11:55 +02:00
Holger Hans Peter Freyther
a5a6da46a0 sgsn: Allow to specify the DNS servers that should be used
If no server is specified the default list will be used. This
allows to separate the servers for the local network and GRX
from each other.
2015-05-25 15:58:02 +08:00
Holger Hans Peter Freyther
39c430ee29 sgsn: Allow to resolve the IPv4 address of a GGSN through DNS
For real networks we need to check if the requested APN string
is allowed and then resolve the GGSN address through DNS. There
are countries with two or three digit MNCs and one could either
try to keep a list of countries that have two/three digits or
just try both of them. I have opted for the later for the ease
of the implementation.

C-Ares doesn't allow to cancel a request so we will need to
have the MMCTX and the Lookup have different lifetimes. We simply
set ->mmctx to NULL in case the MMCTX dies more early.

The selected and verified apn_str will be copied into the out
parameter. In case no static APN/GGSN config is present and the
dynamic mode is enabled a request will be made.
2015-05-25 15:57:57 +08:00
Holger Hans Peter Freyther
66e7106d39 sgsn: Integrate c-ares with the osmocom event loop
c-ares is an asynchronous DNS resolver and we need it to
resolve the GGSN address. This is integrating the library
into our infrastructure. We will create and maintain a list
of registered FDs (c-ares is currently only using one of
them) and (re-)schedule the timer after events occurred.
2015-05-25 15:39:59 +08:00
Holger Hans Peter Freyther
ccd2312d10 sgsn: Create a copy of the msgb for later usage
When needing to do an asynchronous DNS query we need
to keep the TLV data around. So create a wrapper that
takes a copy of it and frees it after the call. I can
change the code to add an out parameter to decide if
the msgb should be freed or not.

Pick network failure in case the msgb could not be
cloned in the hope the MS will retry then.
2015-05-25 15:39:59 +08:00
Holger Hans Peter Freyther
7605bdc02c sgsn: Re-factor the activate PDP code for future changes
A real SGSN will dynamically resolve the APN name into the
GGSN IP Address. This means that after we have collected all
information we need to start to resolve the GGSN and then
can continue.
2015-05-25 14:38:02 +08:00
Holger Hans Peter Freyther
08bb84b04e sgsn: Deal with no static ggsn being configured at all
In case no static ggsn is configured the code would crash
with the assumption that there is always such a GGSN.
2015-05-25 14:38:01 +08:00
Holger Hans Peter Freyther
9270d99f3d sgsn: If there is a subscr don't allow an empty list
This is a left-over from the initial system where no PDP
was provided by the system. For now if there is a subscr
attached and no PDP context provisioned. He is not allowed
to have a data connection.

Update the testcase to create the pdp list entry more
early with a wildcard and then change it to a specific
match.
2015-05-25 14:38:01 +08:00
Holger Hans Peter Freyther
5e4b88cbb2 Merge branch 'zecke/features/sgsn-hlr-number'
Store the hlr-Number for purgeMS and CDR handling
2015-05-24 12:32:36 +08:00
Holger Hans Peter Freyther
8ee13e2937 sgsn: Extract the hlr Number into the mm context
Include the hlr-Number of the subscriber in the CDR. This is useful
for debugging and understanding which equipment was used during the
test. In contrast to the MSISDN the '+' is emitted as the number
must be in international format already.
2015-05-24 12:32:23 +08:00
Holger Hans Peter Freyther
10c0f56a0e gsup: Copy the hlr-Number and use it during purge
Copy the hlr-Number into the sgsn_data and use it during
the purgeMS. There is no unit test that looks at the data
we send so I manually verified this by looking at the output.
Below is the output of the test that purges the subscriber.

<000f> gprs_subscriber.c:170 SUBSCR(123456789012345) Sending GSUP, will send: 0c 01 08 21 43 65 87 09 21 43 f5 09 07 91 83 61 26 31 23 f3
2015-05-24 12:32:23 +08:00
Holger Hans Peter Freyther
0bb5674cde gsup: Decode/Encode the hlr-Number in the GSUP message
Implement it similar to the msisdn_enc/msisdn_enc_len and
extend the testcase to include it as well.
2015-05-24 12:32:23 +08:00
Holger Hans Peter Freyther
e54a24d4e6 gsup: Add the HLR-Number as type and use it for UpdateLocation Res
The HLR-Number can be passed from the MAP Proxy to the SGSN and
can then be used for the CDR module or passed during the purgeMS
operation.
2015-05-24 12:32:22 +08:00
Holger Hans Peter Freyther
0f7a279a06 sgsn: Change the selection mode to verified
We have verified/selected the APN. Either based on the subscriber
data, a global APN match. But at least this SGSN has looked at
what the MS has asked for and then selected a matching GGSN.
2015-05-22 10:05:56 +08:00
Holger Hans Peter Freyther
c1c6a28c8d sgsn: Reserved bits should be set to 1
Bits 3 to 8 are spare bits and should be set to 1 in etsi
specifications. Do that.
2015-05-22 10:05:49 +08:00
Max
4c6e667968 Replace ad-hoc function with generic one from libosmocore
Signed-off-by: Max <max.suraev@fairwaves.co>
2015-05-17 19:09:32 +02:00
Holger Hans Peter Freyther
072bee5c85 sgsn: Clear LAC/RAC value for the routing area identity
Clear LAC/RAC with pre-defined value in the RAI.

3GPP 29.060 v7.17.0 section 7.3.1 page 23:

"The SGSN may include the Routeing Area Identity (RAI) of the
SGSN where the MS is registered. The MCC and MNC components shall
be populated with the MCC and MNC, respectively, of the SGSN
where the MS is registered. The LAC and RAC components shall be
populated by the SGSN with the value of 'FFFE' and 'FF',
respectively.”
2015-05-17 17:36:23 +02:00
Holger Hans Peter Freyther
267fd0c7f7 Merge branch 'zecke/features/sgsn-gtp-cdr'
Extend GTP and CDR support in the SGSN.
2015-05-17 17:24:09 +02:00
Holger Hans Peter Freyther
d6900dfba4 sgsn: Give the IMEI to the GGSN for analysis
Most SGSNs pass the IMEI(SV). We currently only enquire about
the IMEI and then pad the 'SV' with 1111b (thanks to the encoding
routine). Sadly it insists on always writing the length which
means we have to memmove the data around by a single octet.

Manually verified using the pcu-emu and looking at the trace
using wireshark.
2015-05-17 17:23:57 +02:00
Holger Hans Peter Freyther
6ddb6ac028 sgsn: Encode the ULI for the PDP context creation ack
Give the GGSN another opportunity to determine which tarif
to apply for the SGSN/subscriber. This code assumes tha the
RAN is a GERAN system but the assumption has been made in
other places as well.
2015-05-17 17:23:57 +02:00
Holger Hans Peter Freyther
22093ef964 sgsn: Always include the routing area identity
For PDP context creation we always want to include the RAI
for the current mmctx. This might help commercial GGSNs to
determine which charging to apply.
2015-05-17 17:23:57 +02:00
Holger Hans Peter Freyther
77ff1c40e2 cdr: Remember the charging id supplied by the GGSN
The charging_id is provided by the GGSN. Copy it into the CDR
part of the data structure so it will remain present until after
the pdp context has been deleted.
2015-05-17 17:23:57 +02:00
Holger Hans Peter Freyther
446f8403d1 debian: Fix dependencies pointed out by lintian
E: openbsc source: missing-separator-between-items in osmocom-nitb depends field between '${misc:Depends}' and 'libdbd-sqlite3'
2015-05-17 17:23:36 +02:00
Holger Hans Peter Freyther
7882d2751f Merge branch 'zecke/features/cdr'
Add an optional CDR module. This will create a rotatable log
file, detect rotation and try to write as many information as
possible.
2015-05-12 20:06:47 +02:00
Holger Hans Peter Freyther
c15c61c401 sgsn: Add VTY configuration for the CDR module
Make it possible to set a filename to use for the CDR. By
default no CDR will be generated. Forbid to set the interval
of 0 seconds as this will cause a lot of work. Add a very
basic VTY test.
2015-05-06 17:46:08 +02:00
Holger Hans Peter Freyther
4f5b8237ec sgsn: Create an initial and limited CDR module
This is consuming the new signals and allows to install several
different CDR/observing/event/audit modules in the future. For
getting the bytes in/out the code would have had to undo what the
rate counter is doing and at the same time adding a "total" to
the ratecounter didn't look like a good idea, the same went for
making it a plain counter.

Begin writing the values one by one and open/closing a new FILE
for every log messages. This is not efficient but easily deals
with external truncation/rotation of the file (no fstat for and
checking the links and size). As usual we will wait and see if
this is an issue.

Add some new members to our PDP context structure to see what it
is about.
2015-05-06 17:43:15 +02:00
Holger Hans Peter Freyther
b100895557 sgsn: Add various signals consumed by CDR or other client code 2015-05-06 17:14:51 +02:00
Holger Hans Peter Freyther
20de3ae17c sgsn: Extract the MSISDN from the subscr data structure
In case there is a subscr attached to the MM context and there
is an encoded MSISDN we will attempt to decode it and in case
of an international number prepend a '+'. Assume that the array
size of gsm_mmcc_called->number is as big as ctx->msisdn for the
strncpy.
2015-05-06 17:14:51 +02:00
Holger Hans Peter Freyther
b448dd849a sgsn: Make the free function internal
All calls should and do go through the
sgsn_mm_ctx_cleanup_free function.
2015-05-06 17:14:51 +02:00
276 changed files with 22077 additions and 12145 deletions

0
README
View File

57
contrib/jenkins.sh Executable file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/env bash
set -ex
rm -rf deps/install
mkdir deps || true
export LD_LIBRARY_PATH=$PWD/deps/install/lib
cd deps
osmo-deps.sh libosmocore
cd libosmocore
autoreconf --install --force
./configure --prefix=$PWD/../install
$MAKE $PARALLEL_MAKE install
cd ../
osmo-deps.sh libosmo-abis
cd libosmo-abis
autoreconf --install --force
PKG_CONFIG_PATH=$PWD/../install/lib/pkgconfig ./configure --prefix=$PWD/../install
PKG_CONFIG_PATH=$PWD/..//install/lib/pkgconfig $MAKE $PARALLEL_MAKE install
cd ../
osmo-deps.sh libosmo-netif
cd libosmo-netif
autoreconf --install --force
PKG_CONFIG_PATH=$PWD/../install/lib/pkgconfig ./configure --prefix=$PWD/../install
PKG_CONFIG_PATH=$PWD/..//install/lib/pkgconfig $MAKE $PARALLEL_MAKE install
cd ../
osmo-deps.sh libosmo-sccp
cd libosmo-sccp
autoreconf --install --force
PKG_CONFIG_PATH=$PWD/../install/lib/pkgconfig ./configure --prefix=$PWD/../install
PKG_CONFIG_PATH=$PWD/..//install/lib/pkgconfig $MAKE $PARALLEL_MAKE install
cd ../
osmo-deps.sh libsmpp34
cd libsmpp34
autoreconf --install --force
./configure --prefix=$PWD/../install
$MAKE install
cd ../
osmo-deps.sh openggsn
cd openggsn
autoreconf --install --force
PKG_CONFIG_PATH=$PWD/../install/lib/pkgconfig ./configure --prefix=$PWD/../install
PKG_CONFIG_PATH=$PWD/..//install/lib/pkgconfig $MAKE $PARALLEL_MAKE install
cd ../../openbsc
autoreconf --install --force
PKG_CONFIG_PATH=$PWD/../deps/install/lib/pkgconfig ./configure --enable-osmo-bsc --enable-nat $SMPP $MGCP --enable-vty-tests --enable-external-tests
PKG_CONFIG_PATH=$PWD/../deps/install/lib/pkgconfig $MAKE $PARALLEL_MAKE
PKG_CONFIG_PATH=$PWD/../deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/../deps/install/lib $MAKE check
PKG_CONFIG_PATH=$PWD/../deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/../deps/install/lib $MAKE distcheck

18
debian/control vendored
View File

@@ -2,7 +2,7 @@ Source: openbsc
Section: net
Priority: optional
Maintainer: Harald Welte <laforge@gnumonks.org>
Build-Depends: debhelper (>= 7.0.0~), autotools-dev, pkg-config, libgtp0-dev, libosmocore-dev, libosmo-sccp-dev, libdbi0-dev, dh-autoreconf, libosmo-abis-dev, libosmo-netif-dev, libdbd-sqlite3, libpcap-dev
Build-Depends: debhelper (>= 7.0.0~), autotools-dev, pkg-config, libgtp0-dev, libosmocore-dev, libosmo-sccp-dev, libdbi0-dev, dh-autoreconf, libosmo-abis-dev, libosmo-netif-dev, libdbd-sqlite3, libpcap-dev, libssl-dev, libc-ares-dev, libsmpp34-dev
Standards-Version: 3.8.4
Homepage: http://openbsc.osmocom.org/
Vcs-Git: git://bs11-abis.gnumonks.org/openbsc.git
@@ -16,7 +16,7 @@ Description: GSM Base Station Controller; BSC-only version of OpenBSC. Needs a
Package: osmocom-nitb
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends} libdbd-sqlite3
Depends: ${shlibs:Depends}, ${misc:Depends}, libdbd-sqlite3
Description: GSM Network-in-a-Box, implements BSC, MSC, SMSC, HLR, VLR
All the GSM network components bundled together.
@@ -50,6 +50,12 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Osmocom Base Station Controller Network Address Translation
Network address translation for BSC.
Package: osmo-gtphub
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Osmocom GTP Hub
Proxy for comms between multiple SGSNs and GGSNs.
Package: osmocom-bsc-dbg
Architecture: any
Section: debug
@@ -105,3 +111,11 @@ Priority: extra
Depends: osmocom-bsc-nat (= ${binary:Version}), ${misc:Depends}
Description: Debug symbols for the OpenBSC Network Address Translation
Make debugging possible
Package: osmo-gtphub-dbg
Architecture: any
Section: debug
Priority: extra
Depends: osmo-gtphub (= ${binary:Version}), ${misc:Depends}
Description: Debug symbols for Osmocom GTP Hub
Make debugging possible

2
debian/docs vendored
View File

@@ -1 +1 @@
README
openbsc/README

2
debian/osmo-gtphub.default vendored Normal file
View File

@@ -0,0 +1,2 @@
CONFIG_FILE="/etc/osmocom/osmo-gtphub.cfg"

1
debian/osmo-gtphub.examples vendored Normal file
View File

@@ -0,0 +1 @@
openbsc/doc/examples/osmo-gtphub

150
debian/osmo-gtphub.init vendored Executable file
View File

@@ -0,0 +1,150 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: osmo-gtphub
# Required-Start: $network $local_fs
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Osmocom GTP hub
# Description: Osmocom GTP hub
### END INIT INFO
# Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
NAME=osmo-gtphub # Introduce the short server's name here
DESC="Osmocom GTP hub" # Introduce a short description here
DAEMON=/usr/bin/osmo-gtphub # Introduce the server's location here
SCRIPTNAME=/etc/init.d/osmo-gtphub
# Exit if the package is not installed
[ -x $DAEMON ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/osmo-gtphub ] && . /etc/default/osmo-gtphub
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
DAEMON_ARGS="$DAEMON_ARGS -D -c $CONFIG_FILE"
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
# Add code here, if necessary, that waits for the process to be ready
# to handle requests from services started subsequently which depend
# on this one. As a last resort, sleep for some time.
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
return "$RETVAL"
}
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon --stop --signal 1 --quiet $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:

1
debian/osmo-gtphub.install vendored Normal file
View File

@@ -0,0 +1 @@
/usr/bin/osmo-gtphub

View File

@@ -1,3 +1,3 @@
/usr/bin/ipaccess-config
/usr/bin/ipaccess-find
/usr/bin/abisip-find
/usr/bin/ipaccess-proxy

3
debian/rules vendored
View File

@@ -34,8 +34,9 @@ override_dh_strip:
dh_strip -posmocom-sgsn --dbg-package=osmocom-sgsn-dbg
dh_strip -posmocom-gbproxy --dbg-package=osmocom-gbproxy-dbg
dh_strip -posmocom-bsc-nat --dbg-package=osmocom-bsc-nat-dbg
dh_strip -posmo-gtphub --dbg-package=osmo-gtphub-dbg
override_dh_auto_configure:
echo $(VERSION) > openbsc/.tarball-version
dh_auto_configure --sourcedirectory=openbsc -- --enable-nat --enable-osmo-bsc
dh_auto_configure --sourcedirectory=openbsc -- --enable-nat --enable-osmo-bsc --enable-smpp

View File

@@ -1,144 +0,0 @@
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c linux-2.6.27.4/drivers/isdn/mISDN/layer2.c
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c 2008-10-26 00:05:07.000000000 +0200
+++ linux-2.6.27.4/drivers/isdn/mISDN/layer2.c 2008-12-23 16:16:29.000000000 +0100
@@ -94,8 +94,10 @@
struct layer2 *l2 = fi->userdata;
va_list va;
+#if 0
if (!(*debug & DEBUG_L2_FSM))
return;
+#endif
va_start(va, fmt);
printk(KERN_DEBUG "l2 (tei %d): ", l2->tei);
vprintk(fmt, va);
@@ -882,6 +884,8 @@
l2->va = 0;
l2->vr = 0;
l2->sow = 0;
+ l2->sapi = skb->data[0] >> 2;
+ set_channel_address(&l2->ch, l2->sapi, l2->tei);
clear_exception(l2);
send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
mISDN_FsmChangeState(fi, ST_L2_7);
@@ -898,6 +902,7 @@
struct layer2 *l2 = fi->userdata;
struct sk_buff *skb = arg;
+ printk(KERN_DEBUG "l2_send_UA()\n");
send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
}
@@ -931,6 +936,8 @@
l2->va = 0;
l2->vr = 0;
l2->sow = 0;
+ l2->sapi = skb->data[0] >> 2;
+ set_channel_address(&l2->ch, l2->sapi, l2->tei);
mISDN_FsmChangeState(fi, ST_L2_7);
stop_t200(l2, 3);
mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
@@ -982,6 +989,8 @@
} else if (l2->vs != l2->va) {
skb_queue_purge(&l2->i_queue);
pr = DL_ESTABLISH_IND;
+ //l2->sapi = skb->data[0] >> 2;
+ //set_channel_address(&l2->ch, l2->sapi, l2->tei);
}
stop_t200(l2, 5);
l2->vr = 0;
@@ -1841,11 +1850,14 @@
u_int l;
int c = 0;
+ printk(KERN_DEBUG "ph_data_indication 0x%x 0x%x 0x%x\n", datap[0], datap[1], datap[2]);
+
l = l2addrsize(l2);
if (skb->len <= l) {
mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
return ret;
}
+#if 0
if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
psapi = *datap++;
ptei = *datap++;
@@ -1875,6 +1887,7 @@
return 0;
}
} else
+#endif
datap += l;
if (!(*datap & 1)) { /* I-Frame */
c = iframe_error(l2, skb);
@@ -1890,6 +1903,7 @@
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
} else if (IsSABME(datap, l2)) {
c = unnum_error(l2, skb, CMD);
+ printk(KERN_DEBUG "IsSABME() returned true, unnum_error=%d\n", c);
if (!c)
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
} else if (IsUA(datap)) {
@@ -2087,7 +2101,7 @@
test_and_set_bit(FLG_LAPD, &l2->flag);
test_and_set_bit(FLG_LAPD_NET, &l2->flag);
test_and_set_bit(FLG_MOD128, &l2->flag);
- l2->sapi = 0;
+ l2->sapi = 62;
l2->maxlen = MAX_DFRAME_LEN;
if (test_bit(OPTION_L2_PMX, &options))
l2->window = 7;
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c linux-2.6.27.4/drivers/isdn/mISDN/tei.c
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c 2008-10-26 00:05:07.000000000 +0200
+++ linux-2.6.27.4/drivers/isdn/mISDN/tei.c 2008-12-23 16:32:59.000000000 +0100
@@ -830,18 +830,29 @@
int tei, ri;
struct layer2 *l2;
+ printk(KERN_DEBUG "new tei request: tei=%d\n", dp[3] >> 1);
+
ri = dp[0] << 8;
ri += dp[1];
- if (!mgr->up)
- goto denied;
- tei = get_free_tei(mgr);
- if (tei < 0) {
- printk(KERN_WARNING "%s:No free tei\n", __func__);
+ if (!mgr->up) {
+ printk(KERN_DEBUG "mgr->up == NULL\n");
goto denied;
}
+ if (dp[3] != 0xff) {
+ /* This is a TEI request according to 3GPP TS 08.56 6.1.11.2 */
+ tei = dp[3] >> 1;
+ } else {
+ tei = get_free_tei(mgr);
+ if (tei < 0) {
+ printk(KERN_WARNING "%s:No free tei\n", __func__);
+ goto denied;
+ }
+ }
l2 = create_new_tei(mgr, tei);
- if (!l2)
+ if (!l2) {
+ printk(KERN_DEBUG "create_new_tei == NULL\n");
goto denied;
+ }
else
mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp);
return;
@@ -1159,12 +1170,14 @@
return -ENOTCONN;
if (skb->len != 3)
return -ENOTCONN;
+#if 0
if (skb->data[0] != 0)
/* only SAPI 0 command */
return -ENOTCONN;
+#endif
if (!(skb->data[1] & 1)) /* invalid EA1 */
return -EINVAL;
- tei = skb->data[1] >> 0;
+ tei = skb->data[1] >> 1;
if (tei > 63) /* not a fixed tei */
return -ENOTCONN;
if ((skb->data[2] & ~0x10) != SABME)

View File

@@ -1,486 +0,0 @@
This experimental patch splits one E1 card into three virtual cards,
TS 1,2,3,4,5 is card 0
TS 6,7,8,9,10 is card 1
TS 11,12,13,14 is card 2
This allows you to run one L2 TEI handler on each of the virtual cards,
which is required if you want to run multiple BTS on a single E1 link.
Thanks to Andreas Eversberg for this patch.
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
index 0c77386..02dd4a1 100644
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
@@ -209,14 +209,17 @@ struct hfc_multi {
u_long ledstate; /* save last state of leds */
int opticalsupport; /* has the e1 board */
/* an optical Interface */
- int dslot; /* channel # of d-channel (E1) default 16 */
+
+ u_int bmask[32]; /* bitmask of bchannels for port */
+ u_char dnum[32]; /* array of used dchannel numbers for port */
+ u_char created[32]; /* what port is created */
+ u_int activity[32]; /* if there is any action on this */
+ /* port (will be cleared after */
+ /* showing led-states) */
u_long wdcount; /* every 500 ms we need to */
/* send the watchdog a signal */
u_char wdbyte; /* watchdog toggle byte */
- u_int activity[8]; /* if there is any action on this */
- /* port (will be cleared after */
- /* showing led-states) */
int e1_state; /* keep track of last state */
int e1_getclock; /* if sync is retrieved from interface */
int syncronized; /* keep track of existing sync interface */
@@ -233,7 +236,6 @@ struct hfc_multi {
* the bch->channel is equvalent to the hfc-channel
*/
struct hfc_chan chan[32];
- u_char created[8]; /* what port is created */
signed char slot_owner[256]; /* owner channel of slot */
};
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index e1dab30..4fe2d27 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -1619,8 +1619,8 @@ hfcmulti_leds(struct hfc_multi *hc)
* left red: frame sync, but no L1
* right green: L2 active
*/
- if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */
- if (hc->chan[hc->dslot].dch->dev.D.protocol
+ if (hc->chan[hc->dnum[0]].sync != 2) { /* no frame sync */
+ if (hc->chan[hc->dnum[0]].dch->dev.D.protocol
!= ISDN_P_NT_E1) {
led[0] = 1;
led[1] = 1;
@@ -2428,55 +2428,56 @@ handle_timer_irq(struct hfc_multi *hc)
}
}
if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
- dch = hc->chan[hc->dslot].dch;
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
+#warning todo: put interface parameters to hc
+ dch = hc->chan[hc->dnum[0]].dch;
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
/* LOS */
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
- if (!temp && hc->chan[hc->dslot].los)
+ if (!temp && hc->chan[hc->dnum[0]].los)
signal_state_up(dch, L1_SIGNAL_LOS_ON,
"LOS detected");
- if (temp && !hc->chan[hc->dslot].los)
+ if (temp && !hc->chan[hc->dnum[0]].los)
signal_state_up(dch, L1_SIGNAL_LOS_OFF,
"LOS gone");
- hc->chan[hc->dslot].los = temp;
+ hc->chan[hc->dnum[0]].los = temp;
}
- if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
/* AIS */
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
- if (!temp && hc->chan[hc->dslot].ais)
+ if (!temp && hc->chan[hc->dnum[0]].ais)
signal_state_up(dch, L1_SIGNAL_AIS_ON,
"AIS detected");
- if (temp && !hc->chan[hc->dslot].ais)
+ if (temp && !hc->chan[hc->dnum[0]].ais)
signal_state_up(dch, L1_SIGNAL_AIS_OFF,
"AIS gone");
- hc->chan[hc->dslot].ais = temp;
+ hc->chan[hc->dnum[0]].ais = temp;
}
- if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
/* SLIP */
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
- if (!temp && hc->chan[hc->dslot].slip_rx)
+ if (!temp && hc->chan[hc->dnum[0]].slip_rx)
signal_state_up(dch, L1_SIGNAL_SLIP_RX,
" bit SLIP detected RX");
- hc->chan[hc->dslot].slip_rx = temp;
+ hc->chan[hc->dnum[0]].slip_rx = temp;
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
- if (!temp && hc->chan[hc->dslot].slip_tx)
+ if (!temp && hc->chan[hc->dnum[0]].slip_tx)
signal_state_up(dch, L1_SIGNAL_SLIP_TX,
" bit SLIP detected TX");
- hc->chan[hc->dslot].slip_tx = temp;
+ hc->chan[hc->dnum[0]].slip_tx = temp;
}
- if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
/* RDI */
temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
- if (!temp && hc->chan[hc->dslot].rdi)
+ if (!temp && hc->chan[hc->dnum[0]].rdi)
signal_state_up(dch, L1_SIGNAL_RDI_ON,
"RDI detected");
- if (temp && !hc->chan[hc->dslot].rdi)
+ if (temp && !hc->chan[hc->dnum[0]].rdi)
signal_state_up(dch, L1_SIGNAL_RDI_OFF,
"RDI gone");
- hc->chan[hc->dslot].rdi = temp;
+ hc->chan[hc->dnum[0]].rdi = temp;
}
temp = HFC_inb_nodebug(hc, R_JATT_DIR);
- switch (hc->chan[hc->dslot].sync) {
+ switch (hc->chan[hc->dnum[0]].sync) {
case 0:
if ((temp & 0x60) == 0x60) {
if (debug & DEBUG_HFCMULTI_SYNC)
@@ -2485,10 +2486,10 @@ handle_timer_irq(struct hfc_multi *hc)
"in clock sync\n",
__func__, hc->id);
HFC_outb(hc, R_RX_OFF,
- hc->chan[hc->dslot].jitter | V_RX_INIT);
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
HFC_outb(hc, R_TX_OFF,
- hc->chan[hc->dslot].jitter | V_RX_INIT);
- hc->chan[hc->dslot].sync = 1;
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
+ hc->chan[hc->dnum[0]].sync = 1;
goto check_framesync;
}
break;
@@ -2499,7 +2500,7 @@ handle_timer_irq(struct hfc_multi *hc)
"%s: (id=%d) E1 "
"lost clock sync\n",
__func__, hc->id);
- hc->chan[hc->dslot].sync = 0;
+ hc->chan[hc->dnum[0]].sync = 0;
break;
}
check_framesync:
@@ -2510,7 +2511,7 @@ check_framesync:
"%s: (id=%d) E1 "
"now in frame sync\n",
__func__, hc->id);
- hc->chan[hc->dslot].sync = 2;
+ hc->chan[hc->dnum[0]].sync = 2;
}
break;
case 2:
@@ -2520,7 +2521,7 @@ check_framesync:
"%s: (id=%d) E1 lost "
"clock & frame sync\n",
__func__, hc->id);
- hc->chan[hc->dslot].sync = 0;
+ hc->chan[hc->dnum[0]].sync = 0;
break;
}
temp = HFC_inb_nodebug(hc, R_SYNC_STA);
@@ -2530,7 +2531,7 @@ check_framesync:
"%s: (id=%d) E1 "
"lost frame sync\n",
__func__, hc->id);
- hc->chan[hc->dslot].sync = 1;
+ hc->chan[hc->dnum[0]].sync = 1;
}
break;
}
@@ -2746,7 +2747,8 @@ hfcmulti_interrupt(int intno, void *dev_id)
if (r_irq_misc & V_STA_IRQ) {
if (hc->ctype == HFC_TYPE_E1) {
/* state machine */
- dch = hc->chan[hc->dslot].dch;
+#warning todo
+ dch = hc->chan[hc->dnum[0]].dch;
e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
&& hc->e1_getclock) {
@@ -2768,7 +2770,15 @@ hfcmulti_interrupt(int intno, void *dev_id)
}
dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
& 0x7;
+#warning todo hack!!! broadcast state change!!!
+ dch = hc->chan[hc->dnum[0]].dch;
schedule_event(dch, FLG_PHCHANGE);
+ dch = hc->chan[hc->dnum[1]].dch;
+ dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
+ & 0x7;
+ schedule_event(dch, FLG_PHCHANGE);
+
+
if (debug & DEBUG_HFCMULTI_STATE)
printk(KERN_DEBUG
"%s: E1 (id=%d) newstate %x\n",
@@ -3851,31 +3861,35 @@ hfcmulti_initmode(struct dchannel *dch)
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: entered\n", __func__);
+ i = dch->slot;
+ pt = hc->chan[i].port;
if (hc->ctype == HFC_TYPE_E1) {
- hc->chan[hc->dslot].slot_tx = -1;
- hc->chan[hc->dslot].slot_rx = -1;
- hc->chan[hc->dslot].conf = -1;
- if (hc->dslot) {
- mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,
+ /* E1 */
+#warning todo: don''t do it if dnum == 0
+ hc->chan[hc->dnum[pt]].slot_tx = -1;
+ hc->chan[hc->dnum[pt]].slot_rx = -1;
+ hc->chan[hc->dnum[pt]].conf = -1;
+ if (hc->dnum[pt]) {
+ mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
-1, 0, -1, 0);
dch->timer.function = (void *) hfcmulti_dbusy_timer;
dch->timer.data = (long) dch;
init_timer(&dch->timer);
}
for (i = 1; i <= 31; i++) {
- if (i == hc->dslot)
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
continue;
hc->chan[i].slot_tx = -1;
hc->chan[i].slot_rx = -1;
hc->chan[i].conf = -1;
mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
}
- /* E1 */
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
+#warning todo (global)
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[pt]].cfg)) {
HFC_outb(hc, R_LOS0, 255); /* 2 ms */
HFC_outb(hc, R_LOS1, 255); /* 512 ms */
}
- if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) {
+ if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[pt]].cfg)) {
HFC_outb(hc, R_RX0, 0);
hc->hw.r_tx0 = 0 | V_OUT_EN;
} else {
@@ -3888,12 +3902,12 @@ hfcmulti_initmode(struct dchannel *dch)
HFC_outb(hc, R_TX_FR0, 0x00);
HFC_outb(hc, R_TX_FR1, 0xf8);
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
if (dch->dev.D.protocol == ISDN_P_NT_E1) {
@@ -3957,7 +3971,7 @@ hfcmulti_initmode(struct dchannel *dch)
plxsd_checksync(hc, 0);
}
} else {
- i = dch->slot;
+ /* ST */
hc->chan[i].slot_tx = -1;
hc->chan[i].slot_rx = -1;
hc->chan[i].conf = -1;
@@ -3973,8 +3987,6 @@ hfcmulti_initmode(struct dchannel *dch)
hc->chan[i - 1].slot_rx = -1;
hc->chan[i - 1].conf = -1;
mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
- /* ST */
- pt = hc->chan[i].port;
/* select interface */
HFC_outb(hc, R_ST_SEL, pt);
/* undocumented: delay after R_ST_SEL */
@@ -4557,6 +4569,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
}
/* free channels */
for (i = 0; i <= 31; i++) {
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
+ continue;
if (hc->chan[i].bch) {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
@@ -4680,12 +4694,13 @@ release_card(struct hfc_multi *hc)
}
static int
-init_e1_port(struct hfc_multi *hc, struct hm_map *m)
+init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
{
struct dchannel *dch;
struct bchannel *bch;
int ch, ret = 0;
char name[MISDN_MAX_IDLEN];
+ int bcount = 0;
dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
if (!dch)
@@ -4698,13 +4713,12 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
dch->dev.D.send = handle_dmsg;
dch->dev.D.ctrl = hfcm_dctrl;
- dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
- dch->slot = hc->dslot;
- hc->chan[hc->dslot].dch = dch;
- hc->chan[hc->dslot].port = 0;
- hc->chan[hc->dslot].nt_timer = -1;
+ dch->slot = hc->dnum[pt];
+ hc->chan[hc->dnum[pt]].dch = dch;
+ hc->chan[hc->dnum[pt]].port = pt;
+ hc->chan[hc->dnum[pt]].nt_timer = -1;
for (ch = 1; ch <= 31; ch++) {
- if (ch == hc->dslot) /* skip dchannel */
+ if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
continue;
bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
if (!bch) {
@@ -4733,7 +4747,10 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
hc->chan[ch].bch = bch;
hc->chan[ch].port = 0;
set_channelmap(bch->nr, dch->dev.channelmap);
+ bcount++;
}
+ dch->dev.nrbchan = bcount;
+#warning todo: must be set globally, and must be a seperate function
/* set optical line type */
if (port[Port_cnt] & 0x001) {
if (!m->opticalsupport) {
@@ -4749,7 +4766,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
__func__,
HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_OPTICAL,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[pt]].cfg);
}
}
/* set LOS report */
@@ -4759,7 +4776,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
"LOS report: card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_LOS,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[pt]].cfg);
}
/* set AIS report */
if (port[Port_cnt] & 0x008) {
@@ -4768,7 +4785,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
"AIS report: card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_AIS,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[pt]].cfg);
}
/* set SLIP report */
if (port[Port_cnt] & 0x010) {
@@ -4778,7 +4795,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
"card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_SLIP,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[pt]].cfg);
}
/* set RDI report */
if (port[Port_cnt] & 0x020) {
@@ -4788,7 +4805,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
"card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_REPORT_RDI,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[pt]].cfg);
}
/* set CRC-4 Mode */
if (!(port[Port_cnt] & 0x100)) {
@@ -4797,7 +4814,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
" card(%d) port(%d)\n",
__func__, HFC_cnt + 1, 1);
test_and_set_bit(HFC_CFG_CRC4,
- &hc->chan[hc->dslot].cfg);
+ &hc->chan[hc->dnum[pt]].cfg);
} else {
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG "%s: PORT turn off CRC4"
@@ -4829,20 +4846,23 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
}
/* set elastic jitter buffer */
if (port[Port_cnt] & 0x3000) {
- hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;
+ hc->chan[hc->dnum[pt]].jitter = (port[Port_cnt]>>12) & 0x3;
if (debug & DEBUG_HFCMULTI_INIT)
printk(KERN_DEBUG
"%s: PORT set elastic "
"buffer to %d: card(%d) port(%d)\n",
- __func__, hc->chan[hc->dslot].jitter,
+ __func__, hc->chan[hc->dnum[pt]].jitter,
HFC_cnt + 1, 1);
} else
- hc->chan[hc->dslot].jitter = 2; /* default */
- snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
+ hc->chan[hc->dnum[pt]].jitter = 2; /* default */
+ if (hc->ports > 1)
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d", HFC_cnt + 1, pt+1);
+ else
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
if (ret)
goto free_chan;
- hc->created[0] = 1;
+ hc->created[pt] = 1;
return ret;
free_chan:
release_port(hc, dch);
@@ -5009,18 +5029,30 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
hc->id = HFC_cnt;
hc->pcm = pcm[HFC_cnt];
hc->io_mode = iomode[HFC_cnt];
+#warning todo: rework module parameters for customizing e1 fragments.... yea, let''s call it: fragments
if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {
- hc->dslot = 0;
+ hc->dnum[0] = 0;
printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
"31 B-channels\n");
}
if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32
&& hc->ctype == HFC_TYPE_E1) {
- hc->dslot = dslot[HFC_cnt];
+ hc->dnum[0] = dslot[HFC_cnt];
printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
"time slot %d\n", dslot[HFC_cnt]);
} else
- hc->dslot = 16;
+ hc->dnum[0] = 16;
+
+#warning todo HACK!!! just a small map of two "fragments"
+ if (hc->ctype == HFC_TYPE_E1) {
+ hc->dnum[0] = 1;
+ hc->bmask[0] = 0x0000003c;
+ hc->dnum[1] = 6;
+ hc->bmask[1] = 0x00000780;
+ hc->dnum[2] = 11;
+ hc->bmask[2] = 0x00007800;
+ hc->ports = 3;
+ }
/* set chip specific features */
hc->masterclk = -1;
@@ -5103,7 +5135,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
goto free_card;
}
if (hc->ctype == HFC_TYPE_E1)
- ret_err = init_e1_port(hc, m);
+ ret_err = init_e1_port(hc, m, pt);
else
ret_err = init_multi_port(hc, pt);
if (debug & DEBUG_HFCMULTI_INIT)
@@ -5115,10 +5147,14 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
if (ret_err) {
while (pt) { /* release already registered ports */
pt--;
- release_port(hc, hc->chan[(pt << 2) + 2].dch);
+ if (hc->ctype == HFC_TYPE_E1)
+ release_port(hc, hc->chan[hc->dnum[pt]].dch);
+ else
+ release_port(hc, hc->chan[(pt << 2) + 2].dch);
}
goto free_card;
}
+#warning todo: count it right, add additional "fragment" counter...
Port_cnt++;
}

10
openbsc/.gitignore vendored
View File

@@ -46,14 +46,16 @@ ltmain.sh
hlr.sqlite3
src/utils/bs11_config
src/ipaccess/ipaccess-config
src/ipaccess/ipaccess-find
src/ipaccess/abisip-find
src/ipaccess/ipaccess-firmware
src/ipaccess/ipaccess-proxy
src/utils/isdnsync
src/nat/bsc_nat
src/gprs/osmo-sgsn
src/gprs/osmo-gbproxy
src/gprs/osmo-gtphub
src/osmo-bsc_nat/osmo-bsc_nat
src/osmo-cscn/osmo-cscn
#tests
tests/testsuite.dir
@@ -77,6 +79,9 @@ tests/trau/trau_test
tests/mgcp/mgcp_transcoding_test
tests/sgsn/sgsn_test
tests/subscr/subscr_test
tests/oap/oap_test
tests/gtphub/gtphub_test
tests/mm_auth/mm_auth_test
tests/atconfig
tests/atlocal
@@ -84,5 +89,6 @@ tests/package.m4
tests/testsuite
tests/testsuite.log
src/openbsc.cfg*
writtenconfig/
gtphub_restart_count

View File

@@ -5,3 +5,5 @@ Stefan Schmidt <stefan@datenfreihafen.org>
Daniel Willmann <daniel@totalueberwachung.de>
Andreas Eversberg <Andreas.Eversberg@versatel.de>
Sylvain Munaut <246tnt@gmail.com>
Jacob Erlbeck <jerlbeck@sysmocom.de>
Neels Hofmeyr <nhofmeyr@sysmocom.de>

View File

@@ -7,7 +7,7 @@ pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = openbsc.pc
BUILT_SOURCES = $(top_srcdir)/.version
EXTRA_DIST = git-version-gen osmoappdesc.py
EXTRA_DIST = git-version-gen osmoappdesc.py .version
$(top_srcdir)/.version:
echo $(VERSION) > $@-t && mv $@-t $@
dist-hook:

View File

@@ -1,32 +1,39 @@
About OpenBSC
=============
OpenBSC is a minimalistic implementation of the GSM Network, with
particular emphasis on the functionality typically provided by the BSC,
MSC, HLR, VLR and SMSC.
OpenBSC started as a minimalistic all-in-one implementation of the GSM Network,
with particular emphasis on the functionality typically provided by the BSC,
MSC, HLR, VLR and SMSC. Today it is a growing suite of libraries and programs,
implementing protocol stacks and functional elements, including
Its currently supported interfaces towards the BTS are:
* OsmoBSC - a pure GSM BSC, speaking Abis/IP to the BTS and A/IP to the MSC
* OsmoBSC-MGCP - MGCP helper to the OsmoBSC software
* OsmoNITB - a BSC+MSC+VLR+HLR+SMSC "Network in the box".
* OsmoCSCN - a voice CN with A/IP and IuCS/IP towards the BSC and/or HNB-GW
* OsmoSGSN - a GPRS SGSN with Gb/IP and IuPS/IP towards the PCU and/or HNB-GW
* Osmo-GbProxy - a Proxy to aggregate many Gb links as one Gb link to the SGSN
* OsmoBSCNAT - a gateway aggregating many A links as one A link to the MSC
* OsmoGTPHUB - a hub aggregating many GTP links (between SGSN and GGSN)
* ipaccess-utils - some tools to discover + configure ip.access nanoBTS
* bs11_config - a tool to configure the Siemens BS-11 microBTS
Various interfaces towards the BTS are supported, among which are:
* Classic A-bis over E1 using a mISDN based E1 interface. In other
words, you can connect existing GSM Base Transceiver Station (BTS)
through E1 to OpenBSC. So far, we have only tested the Siemens BS-11
Test reports with other BTS are much appreciated!
through E1 to OpenBSC. So far, we have made it work with the Siemens BS-11,
various Ericsson RBS2xxx BTS models and the Nokia MetroSite.
* A-bis over IP as used by the ip.access nanoBTS product family
* A-bis over IP as used by the ip.access nanoBTS product family as well as
the Open Source OsmoBTS software (by the same authors as OpenBSC). OsmoBTS
in turn supports various transceiver hardware, including the sysmoBTS
product family, as well as SDR transceivers supported by OsmoTRX, such as
the UmTRX or USRP boardss.
You can find the project documentation at http://openbsc.gnumonks.org/
* IuCS and IuPS over IP towards an HNB-GW (see osmo-iuh) for UMTS (3G)
voice and data links.
This project is still in its early days, and there are lots of areas where it
doesn't behave as per GSM spec.
Find OpenBSC online at
http://openbsc.osmocom.org/
Harald Welte <laforge@gnumonks.org>
libosmocore
===========
Please note that as of March 2010, OpenBSC has a dependency to a library
called "libosmocore". You can obtain that library from
git://git.osmocom.org/libosmocore.git

11
openbsc/README.vty-tests Normal file
View File

@@ -0,0 +1,11 @@
To run the configuration parsing and output (VTY) test suite, first install
git://git.osmocom.org/python/osmo-python-tests
and pass the following configure options here:
./configure --enable-vty-tests --enable-external-tests
The VTY tests are then included in the standard check target:
make check

View File

@@ -16,8 +16,6 @@ AC_PROG_INSTALL
AC_PROG_RANLIB
dnl checks for libraries
AC_SEARCH_LIBS(crypt, crypt,
[LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""])
AC_SUBST(LIBRARY_DL)
@@ -29,6 +27,10 @@ PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.7.0)
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.2.0)
PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 0.6.4)
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.1)
PKG_CHECK_MODULES(LIBCRYPTO, libcrypto >= 0.9.5)
PKG_CHECK_MODULES(LIBASN1C, libasn1c)
PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap)
PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran)
# Enabke/disable the NAT?
AC_ARG_ENABLE([nat], [AS_HELP_STRING([--enable-nat], [Build the BSC NAT. Requires SCCP])],
@@ -48,7 +50,7 @@ fi
AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
AC_SUBST(osmo_ac_build_bsc)
# Enable/disable smpp support in the nitb?
# Enable/disable smpp support in the cscn?
AC_ARG_ENABLE([smpp], [AS_HELP_STRING([--enable-smpp], [Build the SMPP interface])],
[osmo_ac_build_smpp="$enableval"],[osmo_ac_build_smpp="no"])
if test "$osmo_ac_build_smpp" = "yes" ; then
@@ -64,7 +66,8 @@ AC_ARG_ENABLE([mgcp-transcoding], [AS_HELP_STRING([--enable-mgcp-transcoding], [
AC_ARG_WITH([g729], [AS_HELP_STRING([--with-g729], [Enable G.729 encoding/decoding.])], [osmo_ac_with_g729="$withval"],[osmo_ac_with_g729="no"])
if test "$osmo_ac_mgcp_transcoding" = "yes" ; then
AC_SEARCH_LIBS(gsm_create, gsm)
AC_SEARCH_LIBS([gsm_create], [gsm], [LIBRARY_GSM="$LIBS";LIBS=""])
AC_SUBST(LIBRARY_GSM)
if test "$osmo_ac_with_g729" = "yes" ; then
PKG_CHECK_MODULES(LIBBCG729, libbcg729 >= 0.1, [AC_DEFINE([HAVE_BCG729], [1], [Use bgc729 decoder/encoder])])
fi
@@ -75,14 +78,25 @@ AC_SUBST(osmo_ac_mgcp_transcoding)
found_libgtp=yes
PKG_CHECK_MODULES(LIBGTP, libgtp, , found_libgtp=no)
PKG_CHECK_MODULES(LIBGTP, libgtp >= 0.92, , found_libgtp=no)
AM_CONDITIONAL(HAVE_LIBGTP, test "$found_libgtp" = yes)
AC_SUBST(found_libgtp)
found_libcares=yes
PKG_CHECK_MODULES([LIBCARES], [libcares], [], [found_libcares=no])
AM_CONDITIONAL(HAVE_LIBCARES, test "$found_libcares" = yes)
AC_SUBST(found_libcares)
found_libgtp_and_libcares=no
if test "$found_libgtp" = "yes" -a "$found_libcares" = "yes"; then
found_libgtp_and_libcares=yes
fi
AC_SUBST(found_libgtp_and_libcares)
dnl checks for header files
AC_HEADER_STDC
AC_CHECK_HEADERS(dahdi/user.h,,AC_MSG_WARN(DAHDI input driver will not be built))
AC_CHECK_HEADERS(dbi/dbd.h,,AC_MSG_ERROR(DBI library is not installed))
AC_CHECK_HEADERS(pcap/pcap.h,,AC_MSG_ERROR(PCAP library is not installed))
found_cdk=yes
AC_CHECK_HEADERS(cdk/cdk.h,,found_cdk=no)
@@ -180,7 +194,9 @@ AC_OUTPUT(
src/libmgcp/Makefile
src/libcommon/Makefile
src/libfilter/Makefile
src/osmo-nitb/Makefile
src/libiu/Makefile
src/libxsc/Makefile
src/osmo-cscn/Makefile
src/osmo-bsc/Makefile
src/osmo-bsc_nat/Makefile
src/osmo-bsc_mgcp/Makefile
@@ -189,6 +205,7 @@ AC_OUTPUT(
src/gprs/Makefile
tests/Makefile
tests/atlocal
tests/libiudummy/Makefile
tests/gsm0408/Makefile
tests/db/Makefile
tests/channel/Makefile
@@ -203,6 +220,9 @@ AC_OUTPUT(
tests/trau/Makefile
tests/sgsn/Makefile
tests/subscr/Makefile
tests/oap/Makefile
tests/gtphub/Makefile
tests/mm_auth/Makefile
doc/Makefile
doc/examples/Makefile
Makefile)

View File

@@ -0,0 +1,65 @@
#!/usr/bin/env python2.7
"""
AGPLv3+ 2016 Copyright Holger Hans Peter Freyther
Example of how to connect to the USSD side-channel and how to respond
with a fixed message.
"""
import socket
import struct
ussdSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ussdSocket.connect(('127.0.0.1', 5001))
def send_dt1(dstref, data):
dlen = struct.pack('B', len(data)).encode('hex')
hex = '06' + dstref.encode('hex') + '00' + '01' + dlen + data.encode('hex')
pdata = hex.decode('hex')
out = struct.pack('>HB', len(pdata), 0xfd) + pdata
ussdSocket.send(out)
def send_rel(srcref, dstref):
hex = '04' + dstref.encode('hex') + srcref.encode('hex') + '000100'
pdata = hex.decode('hex')
out = struct.pack('>HB', len(pdata), 0xfd) + pdata
ussdSocket.send(out)
def recv_one():
plen = ussdSocket.recv(3)
(plen,ptype) = struct.unpack(">HB", plen)
data = ussdSocket.recv(plen)
return ptype, data
# Assume this is the ID request
data = ussdSocket.recv(4)
ussdSocket.send("\x00\x08\xfe\x05\x00" + "\x05\x01" + "ussd")
# ^len ^len of tag ... and ignore
# Expect a fake message. see struct ipac_msgt_sccp_state
ptype, data = recv_one()
print("%d %s" % (ptype, data.encode('hex')))
(srcref, dstref, transid, invokeid) = struct.unpack("<3s3sBB", data[1:9])
print("New transID %d invoke %d" % (transid, invokeid))
# Expect a the invocation.. todo.. extract invoke id
ptype, data = recv_one()
print("%d %s" % (ptype, data.encode('hex')))
# Reply with BSSAP + GSM 04.08 + MAP portion
# 00 == invoke id 0f == DCS
res = "01002a9b2a0802e1901c22a220020100301b02013b301604010f041155e7d2f9bc3a41412894991c06a9c9a713"
send_dt1(dstref, res.decode('hex'))
clear = "000420040109"
send_dt1(dstref, clear.decode('hex'))
# should be the clear complete
send_rel(srcref, dstref)
# Give it some time to handle connection shutdown properly
print("Gracefully sleeping")
import time
time.sleep(3)

View File

@@ -0,0 +1,608 @@
gprs_iu_tx
-- WORK IN PROGRESS --
This is an incomplete collection of call graphs between MSC and Osmo-BSC,
partly including Osmo-BTS. These traces helped understanding the separation of
the BSC part from Osmo-NITB. The aim: obtain a clearly separated "A" interface
towards the BSC, and have an Iu-CS interface to operate with HNB-GW and hNodeB.
The working title for the result is Osmo-CSCN (Circuit Switched Core Network),
combining an MSC with various other core network components, but without the
BSC parts.
Some Specs and Overview
0408: Radio interface
0411: PP-SMS on Radio interface
0802: A Interface MSC<->BSS (BSS = BSC + BTS)
0804: A Interface L1 MSC<->BSS
0806: A Interface L2 MSC<->BSS
0808: A Interface L3 MSC<->BSS
0808: Figure 1: A MSC<->BSS
0820: RA (Rate Adaption) MSC<->BSS
0851,0852: A-bis general BSC<->BTS
1221: A-bis NM BSC<->BTS
1201: Figure 9: A-bis BSC<->BTS
MS <-> BTS <-> BSC <-> MSC <-> cn
| | | | |
|<-------0408=DTAP----->| |
|<-------0411---------->| |
| | |<--0808>| |
| | |<BSSMAP>| |
| | | | |
| Abis | A |
MS <-> hNodeB <-> HNB-GW <-> MSC <-> cn
| | | | |
|<-0408->|<--Iu--->|<-Iu-cs->| |
|<-0411->| | | |
| | | | |
Entry/Exit points
Osmo-BSC <--A--> MSC or Osmo-CSCN
format: BSSAP/SCCP (where BSSAP = DTAP + BSSMAP)
Osmo-BSC
read from MSC: sccp_system_incoming_ctx()
write to MSC: sccp_connection_write() <-- osmo-bsc/osmo_bsc_sccp.c:bsc_queue_for_msc()
MSC:
third party
Osmo-CSCN:
read: does not exist yet
write: does not exist yet
HNB-GW <--Iu-CS--> Osmo-CSCN
format: CC+MM/RANAP/SUA
HNB-GW:
read: does not exist yet
write: does not exist yet
Osmo-CSCN:
read: does not exist yet
write: does not exist yet
Osmo-BTS <-Abis-> Osmo-BSC
Osmo-BSC:
read: libbsc/abis_rsl.c:abis_rsl_rcvmsg(msg)
write: libosmo-abis/src/e1_input.c:abis_sendmsg() (e1inp_sign_link*)msg->dst;
Osmo-BTS <-Abis-> Osmo-NITB
Osmo-NITB:
read:
osmo_signal_dispatch():
from on_dso_load_token() libmsc/token_auth.c
SS_SUBSCR: token_subscr_cb() libmsc/token_auth.c
SS_SMS: token_sms_cb() libmsc/token_auth.c
from subscr_sig_cb() libmsc/rrlp.c
SS_SUBSCR: subscr_sig_cb() libmsc/rrlp.c
SS_PAGING: paging_sig_cb() libmsc/rrlp.c
from on_dso_load_ho_dec() libbsc/handover_decision.c
SS_LCHAN: ho_dec_sig_cb() libbsc/handover_decision.c
from e1inp_init() libosmo-abis/src/e1_input.c
SS_L_GLOBAL: e1i_sig_cb() libosmo-abis/src/e1_input.c
bts_model_bs11_init();
bts_model_rbs2k_init();
bts_model_nanobts_init();
bts_model_nokia_site_init();
bts_model_sysmobts_init();
bsc_bootstrap_network():
osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);
osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
Call Trees
- A Interface
Osmo-BSC sends to MSC:
sccp_connection_write(conn->sccp, msg);
^ bsc_queue_for_msc()
^
| osmo-bsc/osmo_bsc_api.c:
| bsc_clear_request()
| queue_msg_or_return() osmo-bsc/osmo_bsc_api.c
| ^ bsc_sapi_n_reject()
| | ^send_sapi_reject()
| | ^ gsm0808_submit_dtap() libbsc/bsc_api.c
| | | ^ gsm48_conn_sendmsg() libmsc/gsm_04_08.c
| | | | ^ gsm48_cc_tx_notify_ss() libmsc/gsm_04_08.c
| | | | | mm_tx_identity_req() libmsc/gsm_04_08.c
| | | | | gsm48_tx_mm_info() libmsc/gsm_04_08.c
| | | | | gsm48_tx_mm_auth_req()
| | | | | gsm48_send_rr_app_info()
| | | | | gsm48_cc_tx_status()
| | | | | gsm48_tx_simple()
| | | | | ^ gsm48_tx_mm_auth_rej()
| | | | | gsm48_cc_tx_setup()
| | | | | gsm48_cc_tx_call_proc()
| | | | | gsm48_cc_tx_alerting()
| | | | | gsm48_cc_tx_progress()
| | | | | gsm48_cc_tx_connect()
| | | | | gsm48_cc_tx_connect_ack()
| | | | | gsm48_cc_tx_disconnect()
| | | | | gsm48_cc_tx_release()
| | | | | gsm48_cc_tx_release_compl()
| | | | | gsm48_cc_tx_facility()
| | | | | gsm48_cc_tx_hold_ack()
| | | | | gsm48_cc_tx_hold_rej()
| | | | | gsm48_cc_tx_retrieve_ack()
| | | | | gsm48_cc_tx_retrieve_rej()
| | | | | gsm48_cc_tx_start_dtmf_ack()
| | | | | gsm48_cc_tx_start_dtmf_rej()
| | | | | gsm48_cc_tx_stop_dtmf_ack()
| | | | | gsm48_cc_tx_modify()
| | | | | gsm48_cc_tx_modify_complete()
| | | | | gsm48_cc_tx_modify_reject()
| | | | | gsm48_cc_tx_notify()
| | | | | gsm48_cc_tx_userinfo()
| | | |
| | | | gsm0480_send_ussd_response() libmsc/gsm_04_80.c
| | | | gsm0480_send_ussd_reject() libmsc/gsm_04_80.c
| | | | gsm0480_send_ussdNotify() libmsc/gsm_04_80.c
| | | | ^ bsc_send_ussd_no_srv() osmo-bsc/osmo_bsc_api.c
| | | | gsm0480_send_releaseComplete() libmsc/gsm_04_80.c
| | | | ^ bsc_send_ussd_no_srv() osmo-bsc/osmo_bsc_api.c
| | | |
| | | | gsm411_sendmsg() libmsc/gsm_04_11.c
| | | |
| | | | bsc_maybe_lu_reject() osmo-bsc/osmo_bsc_api.c
| | | | ^ complete_layer3()
| | | | | bsc_dtap()
| | | |
| | | | dtap_rcvmsg() osmo-bsc/osmo_bsc_bssap.c
| | | |
| | | | gsm48_tx_mm_serv_ack() libbsc/gsm_04_08_utils.c
| | | | ^ _gsm48_rx_mm_serv_req_sec_cb()
| | | | | bsc_send_ussd_no_srv() osmo-bsc/osmo_bsc_api.c
| | | |
| | | | gsm48_tx_mm_serv_rej() libbsc/gsm_04_08_utils.c
| | |
| | | bsc_rll_req.cb = rll_ind_cb() from rll_establish() from gsm0808_submit_dtap()
| | | ^ complete_rllr() libbsc/bsc_rll.c
| | | | ^ timer_cb() libbsc/bsc_rll.c
| | | | | rll_indication() libbsc/bsc_rll.c
| | | | | rll_lchan_signal() libbsc/bsc_rll.c
| |
| | bsc_cipher_mode_compl()
| | ^ bsc_api.cipher_mode_compl()
| | | dispatch_dtap() (2)
| | | with GSM48_MT_RR_CIPH_M_COMPL
| |
| | bsc_dtap()
| | ^ cb from osmo-bsc/osmo_bsc_api.c
| | bsc_api.dtap()
| | ^ libbsc/bsc_api.c:
| | | dispatch_dtap() (2)
| | | case GSM48_MT_RR_APP_INFO
| | | case unknown 04.08 RR
| |
| | bsc_assign_compl()
| | ^ osmo-bsc/osmo_bsc_api.c
| | bsc_api.assign_compl()
| | ^ libbsc/bsc_api.c:
| | | dispatch_dtap() (2)
| | | case GSM48_MT_RR_CHAN_MODE_MODIF_ACK
| | | handle_ass_compl()
| | | ^ dispatch_dtap() (2)
| | | | case GSM48_MT_RR_ASS_COMPL
| |
| | bsc_assign_fail()
| |
| | bsc_cm_update()
|
| osmo-bsc/osmo_bsc_bssap.c:
| bssmap_handle_clear_command()
| bssmap_handle_cipher_mode()
| bssmap_handle_assignm_req()
|
Osmo-BSC receives from MSC:
sccp_system_incoming_ctx() (libosmo-sccp)
| L2 type:
v SCCP_MSG_TYPE_CR: _sccp_handle_connection_request(msgb, ctx);
SCCP_MSG_TYPE_RLSD: _sccp_handle_connection_released(msgb);
SCCP_MSG_TYPE_CREF: _sccp_handle_connection_refused(msgb);
SCCP_MSG_TYPE_CC: _sccp_handle_connection_confirm(msgb);
SCCP_MSG_TYPE_RLC: _sccp_handle_connection_release_complete(msgb);
SCCP_MSG_TYPE_DT1: _sccp_handle_connection_dt1(msgb);
Note: a dt1 target entry was created during one of:
- bsc_open_connection() (SCCP connections are established by the BSC, exclusively)
sccp_connection_connect()
_sccp_send_connection_request()
llist_add_tail(&connection->list, &sccp_connections);
- sccp_system_incoming_ctx()
SCCP_MSG_TYPE_CR:
_sccp_handle_connection_request(struct msgb *msgb, void *ctx)
cb->accept_cb() = msc_sccp_accept()
SCCP_MSG_TYPE_UDT: _sccp_handle_read(msgb) --read_cb--> osmo-bsc/osmo_bsc_sccp.c:msc_sccp_read()
msc_sccp_read()
| bsc_handle_udt() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_bssap.c:494
v bssmap_rcvmsg_udt() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_bssap.c:387
gsm0808_bssmap_name() ./libosmocore/src/gsm/gsm0808.c:535
bssmap_handle_reset_ack() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_bssap.c:91
LOGP()
bssmap_handle_paging() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_bssap.c:99
GSM0808_IE_IMSI
GSM0808_IE_CELL_IDENTIFIER_LIST
GSM0808_IE_TMSI
CELL_IDENT_LAC
CELL_IDENT_BSS
GSM0808_IE_CHANNEL_NEEDED
GSM0808_IE_EMLPP_PRIORITY
subscr_get_or_create() ./openbsc/openbsc/src/libcommon/gsm_subscriber_base.c:101
subscr_group
LOGL_INFO
bsc_grace_paging_request() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_grace.c:87
normal_paging() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_grace.c:37
if (msc->core_lac != -1)
paging_request_bts() ./openbsc/openbsc/src/libbsc/paging.c:307
trx_is_usable() ./openbsc/openbsc/src/libbsc/chan_alloc.c:49
if is_ipaccess_bts() and nm_is_running(): 0
else: 1
paging_init_if_needed() ./openbsc/openbsc/src/libbsc/paging.c:224
LAUNCH TIMER:
bts->paging.work_timer.cb = paging_worker;
paging_worker() ./openbsc/openbsc/src/libbsc/paging.c:217
paging_handle_pending_requests() ./openbsc/openbsc/src/libbsc/paging.c:169 (R):
paging_give_credit() ./openbsc/openbsc/src/libbsc/paging.c:107 (R):
recurse paging_handle_pending_requests()
can_send_pag_req() ./openbsc/openbsc/src/libbsc/paging.c:116
page_ms() ./openbsc/openbsc/src/libbsc/paging.c:69
gsm0808_page() ./openbsc/openbsc/src/libbsc/bsc_api.c:415
rsl_paging_cmd() ./openbsc/openbsc/src/libbsc/abis_rsl.c:751
abis_rsl_dchan_hdr
RSL_MT_PAGING_CMD
RSL_CHAN_PCH_AGCH
init_dchan_hdr() ./openbsc/openbsc/src/libbsc/abis_rsl.c:99
mdisc_by_msgtype() ./openbsc/openbsc/src/libbsc/abis_rsl.c:80
ABIS_RSL_MDISC_RLL
ABIS_RSL_MDISC_TRX
ABIS_RSL_MDISC_COM_CHAN
ABIS_RSL_MDISC_DED_CHAN
ABIS_RSL_MDISC_LOC
RSL_IE_CHAN_NR
RSL_IE_PAGING_GROUP
RSL_IE_MS_IDENTITY
RSL_IE_CHAN_NEEDED
abis_rsl_sendmsg() ./libosmo-abis/src/e1_input.c:258
_paging_request() ./openbsc/openbsc/src/libbsc/paging.c:279
llist_add_tail(&req->entry, &bts_entry->pending_requests);
paging_schedule_if_needed() ./openbsc/openbsc/src/libbsc/paging.c:96
if (msc->core_lac == -1)
paging_request()
gsm_bts_by_lac() ./openbsc/openbsc/src/libcommon/gsm_data.c:135
paging_request_bts() ./openbsc/openbsc/src/libbsc/paging.c:307
(see above)
if err
paging_request_stop()
(see below)
locked_paging() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_grace.c:54
paging_request_bts() ./openbsc/openbsc/src/libbsc/paging.c:307
(see above)
- A-bis Interface
Osmo-BSC to BTS:
abis_sendmsg()
^
| libosmo-abis/src/e1_input.c:abis_rsl_sendmsg()
| ^
| | libbsc/abis_rsl.c: 23 callers
| | rsl_bcch_info()
| | rsl_sacch_filling()
| | rsl_sacch_info_modify()
| | rsl_chan_bs_power_ctrl()
| | rsl_chan_ms_power_ctrl()
| | rsl_chan_activate_lchan()
| | rsl_chan_mode_modify_req()
| | rsl_encryption_cmd()
| | rsl_deact_sacch()
| | rsl_rf_chan_release()
| | rsl_paging_cmd()
| | rsl_imm_assign_cmd()
| | rsl_siemens_mrpci()
| | rsl_data_request()
| | rsl_establish_request()
| | rsl_release_request()
| | rsl_ipacc_crcx()
| | rsl_ipacc_mdcx()
| | rsl_ipacc_pdch_activate()
| | rsl_sms_cb_command()
| | rsl_nokia_si_begin()
| | rsl_nokia_si_end()
| | rsl_bs_power_control()
|
| libbsc/bts_nokia_site.c:nokia_abis_nm_queue_send_next()
|
| libbsc/abis_nm.c:_abis_nm_sendmsg()
| ^ abis_nm_sendmsg()
| | abis_nm_sendmsg_direct()
|
| osmo-bts/src/common/abis.c:abis_oml_sendmsg()
| osmo-bts/src/common/abis.c:abis_bts_rsl_sendmsg()
libbsc/e1_config.c:bts_isdn_e1inp_line_ops.sign_link =
libbsc/e1_config.c:bts_isdn_sign_link(struct msgb *msg)
case E1INP_SIGN_RSL:
libbsc/abis_rsl.c:abis_rsl_rcvmsg(msg) (1)
case E1INP_SIGN_OML:
ret = bts->model->oml_rcvmsg(msg);
libbsc/bts_ipaccess_nanobts.c:ipaccess_e1inp_line_ops.sign_link =
ipaccess_sign_link(struct msgb *msg)
case E1INP_SIGN_RSL:
libbsc/abis_rsl.c:abis_rsl_rcvmsg(msg) (1)
case E1INP_SIGN_OML:
libbsc/abis_nm.c:abis_nm_rcvmsg(msg);
(1)
libbsc/abis_rsl.c:abis_rsl_rcvmsg(msg)
case ABIS_RSL_MDISC_RLL:
libbsc/abis_rsl.c:abis_rsl_rx_rll(msg)
case DATA_IND, EST_IND:
libbsc/bsc_api.c:gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
msg->lchan->ts->trx->bts->network->bsc_api;
if (lchan->conn)
libbsc/bsc_api.c:dispatch_dtap() (2)
else
lchan->conn = subscr_con_allocate(msg->lchan);
rc = api->compl_l3(lchan->conn, msg, 0); (3)
case ABIS_RSL_MDISC_DED_CHAN:
rc = abis_rsl_rx_dchan(msg);
case ABIS_RSL_MDISC_COM_CHAN:
rc = abis_rsl_rx_cchan(msg);
case ABIS_RSL_MDISC_TRX:
rc = abis_rsl_rx_trx(msg);
case ABIS_RSL_MDISC_IPACCESS:
rc = abis_rsl_rx_ipacc(msg);
break;
case ABIS_RSL_MDISC_LOC:
LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
(2)
libbsc/bsc_api.c:dispatch_dtap()
struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
default:
if (api->dtap)
api->dtap(conn, link_id, msg); (5)
case GSM48_PDISC_RR:
case GSM48_MT_RR_HANDO_COMPL:
handle_rr_ho_compl(msg);
case GSM48_MT_RR_HANDO_FAIL:
handle_rr_ho_fail(msg);
case GSM48_MT_RR_CIPH_M_COMPL:
if (api->cipher_mode_compl)
api->cipher_mode_compl(conn, msg, (4)
conn->lchan->encr.alg_id);
case GSM48_MT_RR_ASS_COMPL:
handle_ass_compl(conn, msg);
case GSM48_MT_RR_ASS_FAIL:
handle_ass_fail(conn, msg);
case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
rc = gsm48_rx_rr_modif_ack(msg);
if (rc < 0) {
api->assign_fail(conn, GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE)
else
api->assign_compl()
case GSM48_MT_RR_CLSM_CHG:
handle_classmark_chg(conn, msg);
case GSM48_MT_RR_APP_INFO:
if (api->dtap)
api->dtap(conn, link_id, msg); (5)
default:
if (api->dtap)
api->dtap(conn, link_id, msg); (5)
case GSM48_MT_RR_GPRS_SUSP_REQ:
DEBUGP(DRR, "GRPS SUSPEND REQUEST\n");
case GSM48_MT_RR_STATUS:
LOGP(DRR, LOGL_NOTICE, "RR STATUS (cause: %s)\n",
case GSM48_MT_RR_MEAS_REP:
LOGP(DMEAS, LOGL_ERROR, "DIRECT GSM48 MEASUREMENT REPORT ?!? ");
(3)[0]
msc_bsc_api().compl_l3 =
libmsc/osmo_msc.c: msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
libmsc/gsm0408.c: gsm0408_dispatch() (6)
(3)[1]
osmo_bsc_api().compl_l3 =
osmo-bsc/osmo_bsc_api.c:bsc_compl_l3()
msc = bsc_find_msc(conn, msg);
complete_layer3(conn, msg, msc)
bsc_filter_initial(msc->network->bsc_data, msc, conn, msg,
&imsi, &con_type, &lu_cause);
bsc_create_new_connection(conn, msc, send_ping);
sccp->state_cb = msc_outgoing_sccp_state()
sccp->data_cb = msc_outgoing_sccp_data()
bsc_con->send_ping = send_ping()
bsc_con->sccp_it_timeout.cb = sccp_it_timeout()
bsc_con->sccp_cc_timeout.cb = sccp_cc_timeout()
bsc_scan_bts_msg(conn, msg); (7)
resp = gsm0808_create_layer3(msg, network_code, country_code, lac, ci);
(5)[0]
msc_bsc_api().dtap =
libmsc/osmo_msc.c: msc_dtap(conn, link_id, msg)
gsm0408_dispatch(conn, msg) (6)
(5)[1]
osmo_bsc_api().dtap =
osmo-bsc/osmo_bsc_api.c: bsc_dtap(conn, link_id, msg)
if (handle_cc_setup(conn, msg) >= 1) return;
if (bsc_filter_data(conn, msg, &lu_cause) < 0)
bsc_maybe_lu_reject()
return;
bsc_scan_bts_msg(conn, msg); (7)
resp = gsm0808_create_dtap(msg, link_id);
queue_msg_or_return(resp);
(7)
bsc_scan_bts_msg() <osmo-bsc/osmo_bsc_filter.c:212>:
if GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST
handle_lu_request() <osmo-bsc/osmo_bsc_filter.c:29>:
gsm48_generate_lai()
if GSM48_PDISC_RR, GSM48_MT_RR_PAG_RESP
handle_page_resp() <osmo-bsc/osmo_bsc_filter.c:97>:
extract_sub() <osmo-bsc/osmo_bsc_filter.c:57>
paging_request_stop() <libbsc/paging.c:390>:
log_set_context()
_paging_request_stop() <libbsc/paging.c:359>:
paging_init_if_needed() <libbsc/paging.c:224>:
paging_worker() <libbsc/paging.c:217>:
paging_handle_pending_requests() <libbsc/paging.c:169> (R):
cb()
paging_give_credit() <libbsc/paging.c:107> (R):
paging_handle_pending_requests() <libbsc/paging.c:169> (recursive: see 37)
can_send_pag_req() <libbsc/paging.c:116>:
page_ms() <libbsc/paging.c:69>:
gsm0808_page() <libbsc/bsc_api.c:415>:
rsl_paging_cmd() <libbsc/abis_rsl.c:751>:
abis_rsl_dchan_hdr = RSL_IE_CHAN_NR
mdisc_by_msgtype() <libbsc/abis_rsl.c:80>:
ABIS_RSL_MDISC_RLL
ABIS_RSL_MDISC_TRX
ABIS_RSL_MDISC_COM_CHAN
ABIS_RSL_MDISC_DED_CHAN
ABIS_RSL_MDISC_LOC
msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
rsl_link
abis_rsl_sendmsg()
cbfn() (8)
paging_remove_request() <libbsc/paging.c:60>:
subscr_put() <libcommon/gsm_subscriber_base.c:89>
subscr_put() <libcommon/gsm_subscriber_base.c:89>
(8)[0]
libmsc/gsm_04_08.c:mncc_tx_to_cc()
req->cbfn =
libmsc/gsm_04_08.c:setup_trig_pag_evt
(8)[1]
libmsc/gsm_04_11.c:gsm411_send_sms_subscr()
req->cbfn =
libmsc/gsm_04_11.c:paging_cb_send_sms
(9)
bsc_scan_msc_msg() ./osmo-bsc/osmo_bsc_filter.c:330
gsm48_hdr
send_welcome_ussd() ./osmo-bsc/osmo_bsc_filter.c:229
LOGP()
DMSC
LOGL_DEBUG
ussd_welcome_txt
BSS_SEND_USSD
GSM48_MT_MM_INFO
bsc_patch_mm_info() ./osmo-bsc/osmo_bsc_filter.c:255
uint8_t
tzbsd
dst
tlv_parse()
gsm48_mm_att_tlvdef
override
hr
mn
TLVP_PRESENT()
GSM48_IE_UTC
LOGP()
DMSC
LOGL_DEBUG
TLVP_VAL()
GSM48_IE_NET_TIME_TZ
GSM48_IE_NET_DST
(6)
libmsc/gsm0408.c: gsm0408_dispatch() (MSC rx from BSC)
if (silent_call_reroute(conn, msg))
return silent_call_rx(conn, msg);
case gsm48_pdisc_cc:
rc = gsm0408_rcv_cc(conn, msg);
case gsm48_pdisc_mm:
rc = gsm0408_rcv_mm(conn, msg);
case gsm48_pdisc_rr:
rc = gsm0408_rcv_rr(conn, msg);
case gsm48_pdisc_sms:
rc = gsm0411_rcv_sms(conn, msg);
case gsm48_pdisc_nc_ss:
rc = handle_rcv_ussd(conn, msg);
case gsm48_pdisc_mm_gprs:
case gsm48_pdisc_sm_gprs:
logp(drll, logl_notice, "unimplemented "
msc_bsc_api().assign_compl =
msc_assign_compl()
nothing
(4)[0]
libmsc/osmo_msc.c:msc_bsc_api().cipher_mode_compl =
msc_ciph_m_compl(conn, msg, alg_id)
conn->sec_operation->cb(GSM_HOOK_RR_SECURITY, GSM_SECURITY_SUCCEEDED,
NULL, conn, conn->sec_operation->cb_data)
release_security_operation(conn);
msc_release_connection(conn)
bsc_api.c:gsm0808_clear(conn)
libbsc/handover_logic.c:bsc_clear_handover(conn, 1)
libbsc/chan_alloc.c:lchan_release(ho->new_lchan, 0, RSL_REL_LOCAL_END);
libbsc/chan_alloc.c:lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END),
(conn->lchan, 1, RSL_REL_NORMAL)
bsc_api.c:subscr_con_free(conn)
libcommon/gsm_subscriber_base.c:subscr_put(conn->subscr);
(4)[1]
osmo-bsc/osmo_bsc_api.c:osmo_bsc_api().cipher_mode_compl =
bsc_cipher_mode_compl()
queue_msg_or_return() osmo-bsc/osmo_bsc_api.c
bsc_queue_for_msc()
libbsc/abis_nm.c:abis_nm_rcvmsg(msg);
case ABIS_OM_MDISC_FOM:
rc = abis_nm_rcvmsg_fom(msg);
case ABIS_OM_MDISC_MANUF:
rc = abis_nm_rcvmsg_manuf(msg);
case ABIS_OM_MDISC_MMI:
case ABIS_OM_MDISC_TRAU:
LOGP(DNM, LOGL_ERROR, "unimplemented ABIS OML message discriminator 0x%x\n",

View File

@@ -69,30 +69,30 @@ network
nominal power 23
max_power_red 20
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
msc
ip.access rtp-base 4000
timeout-ping 20

View File

@@ -0,0 +1,13 @@
nat
bsc 0
token lol
location_area_code 1234
description bsc
max-endpoints 32
paging forbidden 0
bsc 1
token wat
location_area_code 5678
description bsc
max-endpoints 32
paging forbidden 0

View File

@@ -62,11 +62,5 @@ nat
timeout ping 20
timeout pong 5
ip-dscp 0
bscs-config-file bscs.config
access-list bla imsi-allow ^11$
bsc 0
token bla
location_area_code 1234
description bsc
max-endpoints 32
paging forbidden 0

View File

@@ -0,0 +1,36 @@
!
! OsmoCSCN configuration saved from vty
!
line vty
no login
!
network
network country code 1
mobile network code 1
short name OsmoCSCN
long name OsmoCSCN
auth policy closed
location updating reject cause 13
encryption a5 0
rrlp mode none
mm info 1
handover 0
handover window rxlev averaging 10
handover window rxqual averaging 1
handover window rxlev neighbor averaging 10
handover power budget interval 6
handover power budget hysteresis 3
handover maximum distance 9999
timer t3101 10
timer t3103 0
timer t3105 0
timer t3107 0
timer t3109 4
timer t3111 0
timer t3113 60
timer t3115 0
timer t3117 0
timer t3119 0
timer t3141 0
cscn
subscriber-create-on-demand

View File

@@ -0,0 +1,44 @@
!
! OsmoGbProxy (UNKNOWN) configuration saved from vty
!!
!
log stderr
logging filter all 1
logging color 1
logging timestamp 0
logging level all everything
logging level gprs debug
logging level ns info
logging level bssgp debug
logging level lglobal notice
logging level llapd notice
logging level linp notice
logging level lmux notice
logging level lmi notice
logging level lmib notice
logging level lsms notice
!
line vty
no login
!
ns
nse 666 nsvci 666
nse 666 remote-role sgsn
! nse 666 encapsulation framerelay-gre
! nse 666 remote-ip 172.16.1.70
! nse 666 fr-dlci 666
timer tns-block 3
timer tns-block-retries 3
timer tns-reset 3
timer tns-reset-retries 3
timer tns-test 30
timer tns-alive 3
timer tns-alive-retries 10
encapsulation udp local-port 23000
! encapsulation framerelay-gre enabled 1
gbproxy
sgsn nsei 666
core-mobile-country-code 666
core-mobile-network-code 6
core-access-point-name none match-imsi ^666066|^66607
tlli-list max-length 200

View File

@@ -0,0 +1,90 @@
Here is a simple setup to test GTPHub operations. The IP addresses picked will
work well only on a system that creates local addresses (127.0.0.123) on the
fly (like linux) -- you may pick of course different IP addresses.
Overview of the example setup:
sgsnemu gtphub ggsn
127.0.0.1 <--> 127.0.0.3 127.0.0.4 <--> 127.0.0.2
Prerequisites: openggsn.
Have a local directory where you store config files and from which you launch
the GSNs and the hub (they will store restart counter files in that dir).
In it, have these config files:
ggsn.conf:
# GGSN local address
listen 127.0.0.2
# End User Addresses are picked from this range
net 10.23.42.0/24
pcodns1 8.8.8.8
logfile /tmp/foo
gtphub.conf:
gtphub
bind-to-sgsns 127.0.0.3
bind-to-ggsns 127.0.0.4
ggsn-proxy 127.0.0.2
end
(
You may omit the ggsn-proxy if GRX ares is working, or if you add the GRX
address and GGSN IP address to /etc/hosts something like:
127.0.0.2 internet.mnc070.mcc901.gprs
)
Once the config files are in place, start the programs, in separate terminals.
GGSN and SGSN need to be started with root priviliges to be able to create tun
interfaces. GTPHub may run as unprivileged user.
The LD_LIBRARY_PATH below may be needed if OpenGGSN installed to /usr/local.
1. GGSN:
sudo -s
cd <your-test-dir>
LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/ggsn -f -c ./ggsn.conf
2. GTPHub:
cd <your-test-dir>
path/to/openbsc/openbsc/src/gprs/osmo-gtphub -c gtphub.conf #-e 1 #for DEBUG level
3. SGSN tests:
sudo -s
cd <your-test-dir>
/usr/local/bin/sgsnemu --createif -l 127.0.0.1 -r 127.0.0.3 --imsi 420001214365100 --contexts=3
Add more SGSNs using different IMSIs and local ports (if the same IMSI is used,
the GGSN will reuse TEIs and tunnels will be discarded automatically):
/usr/local/bin/sgsnemu --createif -l 127.0.0.11 -r 127.0.0.3 --imsi 420001214365300 --contexts=3
This shows the basic setup of GTPHub. Testing internet traffic via sgsnemu
still needs some effort to announce a mobile subscriber or the like (I have
used a real BTS, osmo-sgsn and a testing SIM in a web phone, instead).
The core capability of GTPHub is to manage more than two GSNs, e.g. an SGSN
contacting various GGSNs over the single GTPHub link. You would configure the
SGSN to use one fixed GGSN (sending to gtphub) and gtphub will resolve the
GGSNs once it has received the messages. So the SGSN may be behind NAT (add
"sgsn-use-sender" to gtphub.conf) and communicate to various GGSNs over a
single link to gtphub.
I hope this helps to get you going.
Any suggestions/patches are welcome!
~Neels

View File

@@ -0,0 +1,25 @@
!
! Osmocom gtphub configuration
!
! This file is used for VTY tests, referenced by openbsc/osmoappdesc.py
! For the test, try to use most config commands.
!
line vty
no login
gtphub
! Local addresses to listen on and send from, both on one interface.
! The side towards SGSN uses nonstandard ports.
bind-to-sgsns ctrl 127.0.0.1 12123 user 127.0.0.1 12153
! The GGSN side with standard ports.
bind-to-ggsns 127.0.0.1
! Proxy: unconditionally direct all traffic to...
sgsn-proxy 127.0.0.4
! Proxy with nonstandard ports or separate IPs:
ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152
! Add a name server for GGSN resolution
grx-dns-add 192.168.0.1

View File

@@ -0,0 +1,25 @@
!
! Osmocom gtphub configuration
!
line vty
no login
gtphub
! Local addresses to listen on and send from, each on standard ports
! 2123 and 2152. Setting these addresses is mandatory.
bind-to-sgsns 127.0.0.1
bind-to-ggsns 127.0.0.2
! Local nonstandard ports or separate IPs:
!bind-to-sgsns ctrl 127.0.0.1 2342 user 127.0.0.1 4223
! Proxy: unconditionally direct all traffic to...
!ggsn-proxy 127.0.0.3
!sgsn-proxy 127.0.0.4
! Proxy with nonstandard ports or separate IPs:
!ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152
! Add a name server for GGSN resolution
!grx-dns-add 192.168.0.1

View File

@@ -60,38 +60,38 @@ network
max_power_red 12
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 1
timeslot 0
phys_chan_config CCCH
hopping enabled 0
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 3
timeslot 0
phys_chan_config CCCH
hopping enabled 0
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 3
trx 1
rf_locked 0
arfcn 119
@@ -99,66 +99,66 @@ network
max_power_red 12
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 2
timeslot 0
phys_chan_config SDCCH8
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
timeslot 1
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 4 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 4 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 4 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 5 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 5 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 5 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 5 sub-slot 3
timeslot 0
phys_chan_config SDCCH8
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
timeslot 1
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 4 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 4 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 4 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 5 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 5 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 5 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 1
hopping sequence-number 0
hopping maio 0
hopping arfcn add 117
hopping arfcn add 119
e1 line 0 timeslot 5 sub-slot 3

View File

@@ -29,56 +29,56 @@ network
max_power_red 0
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 1
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config SDCCH8
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 3
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config SDCCH8
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 3
trx 1
arfcn 123
max_power_red 0
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 2
timeslot 0
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 3
timeslot 0
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 3

View File

@@ -27,59 +27,59 @@ network
max_power_red 0
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 1
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 3
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 3
trx 1
arfcn 123
max_power_red 0
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 2
timeslot 0
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 3
timeslot 0
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 4 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 5 sub-slot 3
bts 1
type bs11
band GSM900
@@ -93,56 +93,56 @@ network
max_power_red 0
rsl e1 line 1 timeslot 6 sub-slot full
rsl e1 tei 1
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 1 timeslot 7 sub-slot 0
timeslot 1
phys_chan_config SDCCH8
e1 line 1 timeslot 7 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 1 timeslot 7 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 1 timeslot 7 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 1 timeslot 8 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 1 timeslot 8 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 1 timeslot 8 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 1 timeslot 8 sub-slot 3
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 1 timeslot 7 sub-slot 0
timeslot 1
phys_chan_config SDCCH8
e1 line 1 timeslot 7 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 1 timeslot 7 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 1 timeslot 7 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 1 timeslot 8 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 1 timeslot 8 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 1 timeslot 8 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 1 timeslot 8 sub-slot 3
trx 1
arfcn 124
max_power_red 0
rsl e1 line 1 timeslot 6 sub-slot full
rsl e1 tei 2
timeslot 0
phys_chan_config TCH/F
e1 line 1 timeslot 9 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 1 timeslot 9 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 1 timeslot 9 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 1 timeslot 9 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 1 timeslot 10 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 1 timeslot 10 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 1 timeslot 10 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 1 timeslot 10 sub-slot 3
timeslot 0
phys_chan_config TCH/F
e1 line 1 timeslot 9 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 1 timeslot 9 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 1 timeslot 9 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 1 timeslot 9 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 1 timeslot 10 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 1 timeslot 10 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 1 timeslot 10 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 1 timeslot 10 sub-slot 3

View File

@@ -29,28 +29,28 @@ network
max_power_red 0
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 1
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 3
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 3 sub-slot 3

View File

@@ -59,41 +59,41 @@ network
nominal power 23
max_power_red 0
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
timeslot 1
phys_chan_config SDCCH8
timeslot 2
phys_chan_config TCH/F
timeslot 3
phys_chan_config TCH/F
timeslot 4
phys_chan_config TCH/F
timeslot 5
phys_chan_config TCH/F
timeslot 6
phys_chan_config TCH/F
timeslot 7
phys_chan_config TCH/F
timeslot 0
phys_chan_config CCCH+SDCCH4
timeslot 1
phys_chan_config SDCCH8
timeslot 2
phys_chan_config TCH/F
timeslot 3
phys_chan_config TCH/F
timeslot 4
phys_chan_config TCH/F
timeslot 5
phys_chan_config TCH/F
timeslot 6
phys_chan_config TCH/F
timeslot 7
phys_chan_config TCH/F
trx 1
rf_locked 0
arfcn 873
nominal power 23
max_power_red 0
rsl e1 tei 0
timeslot 0
phys_chan_config SDCCH8
timeslot 1
phys_chan_config TCH/F
timeslot 2
phys_chan_config TCH/F
timeslot 3
phys_chan_config TCH/F
timeslot 4
phys_chan_config TCH/F
timeslot 5
phys_chan_config TCH/F
timeslot 6
phys_chan_config TCH/F
timeslot 7
phys_chan_config TCH/F
timeslot 0
phys_chan_config SDCCH8
timeslot 1
phys_chan_config TCH/F
timeslot 2
phys_chan_config TCH/F
timeslot 3
phys_chan_config TCH/F
timeslot 4
phys_chan_config TCH/F
timeslot 5
phys_chan_config TCH/F
timeslot 6
phys_chan_config TCH/F
timeslot 7
phys_chan_config TCH/F

View File

@@ -59,19 +59,19 @@ network
nominal power 23
max_power_red 20
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
timeslot 1
phys_chan_config SDCCH8
timeslot 2
phys_chan_config TCH/F
timeslot 3
phys_chan_config TCH/F
timeslot 4
phys_chan_config TCH/F
timeslot 5
phys_chan_config TCH/F
timeslot 6
phys_chan_config TCH/F
timeslot 7
phys_chan_config TCH/F
timeslot 0
phys_chan_config CCCH+SDCCH4
timeslot 1
phys_chan_config SDCCH8
timeslot 2
phys_chan_config TCH/F
timeslot 3
phys_chan_config TCH/F
timeslot 4
phys_chan_config TCH/F
timeslot 5
phys_chan_config TCH/F
timeslot 6
phys_chan_config TCH/F
timeslot 7
phys_chan_config TCH/F

View File

@@ -31,87 +31,87 @@ network
max_power_red 24
rsl e1 line 0 timeslot 2 sub-slot full
rsl e1 tei 1
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 0 timeslot 6 sub-slot full
timeslot 1
phys_chan_config SDCCH8
e1 line 0 timeslot 6 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 6 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 6 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 7 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 7 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 7 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 7 sub-slot 3
timeslot 0
phys_chan_config CCCH+SDCCH4
e1 line 0 timeslot 6 sub-slot full
timeslot 1
phys_chan_config SDCCH8
e1 line 0 timeslot 6 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 6 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 6 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 7 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 7 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 7 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 7 sub-slot 3
trx 1
arfcn 870
max_power_red 24
rsl e1 line 0 timeslot 3 sub-slot full
rsl e1 tei 2
timeslot 0
phys_chan_config TCH/F
e1 line 0 timeslot 8 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 8 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 8 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 8 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 9 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 9 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 9 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 9 sub-slot 3
timeslot 0
phys_chan_config TCH/F
e1 line 0 timeslot 8 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 8 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 8 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 8 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 9 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 9 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 9 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 9 sub-slot 3
trx 2
arfcn 874
max_power_red 24
rsl e1 line 0 timeslot 4 sub-slot full
rsl e1 tei 3
timeslot 0
phys_chan_config TCH/F
e1 line 0 timeslot 10 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 10 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 10 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 10 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 11 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 11 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 11 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 11 sub-slot 3
timeslot 0
phys_chan_config TCH/F
e1 line 0 timeslot 10 sub-slot 0
timeslot 1
phys_chan_config TCH/F
e1 line 0 timeslot 10 sub-slot 1
timeslot 2
phys_chan_config TCH/F
e1 line 0 timeslot 10 sub-slot 2
timeslot 3
phys_chan_config TCH/F
e1 line 0 timeslot 10 sub-slot 3
timeslot 4
phys_chan_config TCH/F
e1 line 0 timeslot 11 sub-slot 0
timeslot 5
phys_chan_config TCH/F
e1 line 0 timeslot 11 sub-slot 1
timeslot 6
phys_chan_config TCH/F
e1 line 0 timeslot 11 sub-slot 2
timeslot 7
phys_chan_config TCH/F
e1 line 0 timeslot 11 sub-slot 3

View File

@@ -67,38 +67,38 @@ network
max_power_red 12
rsl e1 line 0 timeslot 1 sub-slot full
rsl e1 tei 0
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 3
timeslot 0
phys_chan_config CCCH+SDCCH4
hopping enabled 0
e1 line 0 timeslot 1 sub-slot full
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 2 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 3 sub-slot 3
trx 1
rf_locked 0
arfcn 57
@@ -106,38 +106,38 @@ network
max_power_red 12
rsl e1 line 0 timeslot 4 sub-slot full
rsl e1 tei 1
timeslot 0
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot 0
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 6 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 6 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 6 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 6 sub-slot 3
timeslot 0
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot 0
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 5 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 6 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 6 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 6 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 6 sub-slot 3
trx 2
rf_locked 0
arfcn 59
@@ -145,38 +145,38 @@ network
max_power_red 12
rsl e1 line 0 timeslot 7 sub-slot full
rsl e1 tei 2
timeslot 0
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot 0
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot 3
timeslot 0
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot 0
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 8 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 9 sub-slot 3
trx 3
rf_locked 0
arfcn 61
@@ -184,38 +184,38 @@ network
max_power_red 12
rsl e1 line 0 timeslot 10 sub-slot full
rsl e1 tei 3
timeslot 0
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 11 sub-slot 0
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 11 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 11 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 11 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 12 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 12 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 12 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 12 sub-slot 3
timeslot 0
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 11 sub-slot 0
timeslot 1
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 11 sub-slot 1
timeslot 2
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 11 sub-slot 2
timeslot 3
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 11 sub-slot 3
timeslot 4
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 12 sub-slot 0
timeslot 5
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 12 sub-slot 1
timeslot 6
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 12 sub-slot 2
timeslot 7
phys_chan_config TCH/F
hopping enabled 0
e1 line 0 timeslot 12 sub-slot 3
e1_input
e1_line 0 driver dahdi

View File

@@ -0,0 +1,38 @@
digraph G {
net [label="gsm_network"]
subconns [label="subscr_conns"]
btslist [label="bts_list"]
bts [label="gsm_bts"]
trx [label="gsm_bts_trx"]
ts [label="gsm_bts_trx_ts"]
lchan [label="gsm_lchan"]
sub [label="gsm_subscriber"]
subcon [label="gsm_subscriber_conn"]
sccpcon [label="osmo_bsc_sccp_con"]
subgrp [label="gsm_subscriber_group"]
net -> btslist
btslist -> bts [label="llist"]
bts -> trx
trx -> ts
ts -> lchan
lchan -> ts
ts -> trx
trx -> bts
bts -> net
lchan -> subcon
net -> subconns
subconns -> subcon [label="llist"]
subcon -> sub
subcon -> sccpcon
subcon -> lchan
subcon -> lchan [label="ho_lchan"]
subcon -> bts
subcon -> lchan [label="secondary_lchan"]
sub -> subgrp
subgrp -> net
}

View File

@@ -0,0 +1,15 @@
digraph G {
net [label="gsm_network"]
subconns [label="subscr_conns"]
sub [label="gsm_subscriber"]
subcon [label="gsm_subscriber_conn"]
subgrp [label="gsm_subscriber_group"]
net -> subconns
subconns -> subcon [label="llist"]
subcon -> sub
subcon -> net
sub -> subgrp
subgrp -> net
}

View File

@@ -0,0 +1,250 @@
Osmocom Authentication Protocol (OAP)
1. General
The Osmocom Authentication Protocol employs mutual authentication to register a
client with a server over an IPA connection. Milenage is used as the
authentication algorithm, where client and server have a shared secret.
For example, an SGSN, as OAP client, may use its SGSN ID to register with a MAP
proxy, an OAP server.
1.1. Connection
The protocol expects that a reliable, ordered, packet boundaries preserving
connection is used (e.g. IPA over TCP).
1.2. Using IPA
By default, the following identifiers should be used:
- IPA protocol: 0xee (OSMO)
- IPA OSMO protocol extension: 0x06 (OAP)
2. Procedures
Ideal communication sequence:
Client Server
| |
| Register (ID) |
|----------------------------------->|
| |
| Challenge (RAND+AUTN) |
|<-----------------------------------|
| |
| Challenge Result (XRES) |
|----------------------------------->|
| |
| Register Result |
|<-----------------------------------|
Variation "test setup":
Client Server
| |
| Register (ID) |
|----------------------------------->|
| |
| Register Result |
|<-----------------------------------|
Variation "invalid sequence nr":
Client Server
| |
| Register (ID) |
|----------------------------------->|
| |
| Challenge (RAND+AUTN) |
|<-----------------------------------|
| |
| Sync Request (AUTS) |
|----------------------------------->|
| |
| Challenge (RAND'+AUTN') |
|<-----------------------------------|
| |
| Challenge Result (XRES) |
|----------------------------------->|
| |
| Register Result |
|<-----------------------------------|
2.1. Register
The client sends a REGISTER_REQ message containing an identifier number.
2.2. Challenge
The OAP server (optionally) sends back a CHALLENGE_REQ, containing random bytes
and a milenage authentication token generated from these random bytes, using a
shared secret, to authenticate itself to the OAP client. The server may omit
this challenge entirely, based on its configuration, and immediately reply with
a Register Result response. If the client cannot be registered (e.g. id is
invalid), the server sends a REGISTER_ERR response.
2.3. Challenge Result
When the client has received a Challenge, it may verify the server's
authenticity and validity of the sequence number (included in AUTN), and, if
valid, reply with a CHALLENGE_RES message. This shall contain an XRES
authentication token generated by milenage from the same random bytes received
from the server and the same shared secet. If the client decides to cancel the
registration (e.g. invalid AUTN), it shall not reply to the CHALLENGE_REQ; a
CHALLENGE_ERR message may be sent, but is not mandatory. For example, the
client may directly start with a new REGISTER_REQ message.
2.4. Sync Request
When the client has received a Challenge but sees an invalid sequence number
(embedded in AUTN, according to the milenage algorithm), the client may send a
SYNC_REQ message containing an AUTS synchronisation token.
2.5. Sync Result
If the server has received a valid Sync Request, it shall answer by directly
sending another Challenge (see 2.2.). If an invalid Sync Request is received,
the server shall reply with a REGISTER_ERR message.
2.6. Register Result
The server sends a REGISTER_RES message to indicate that registration has been
successful. If the server cannot register the client (e.g. invalid challenge
response), it shall send a REGISTER_ERR message.
3. Message Format
3.1. General
Every message is based on the following message format
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
The receiver shall be able to receive IEs in any order. Unknown IEs shall be
ignored.
3.2.1. Register Request
Client -> Server
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
30 Client ID big endian int (2 oct) M TLV 4
3.2.2. Register Error
Server -> Client
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
02 Cause GMM cause, M TLV 3
04.08: 10.5.5.14
3.2.6. Register Result
Server -> Client
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
3.2.3. Challenge
Server -> Client
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
20 RAND octet string (16) M TLV 18
23 AUTN octet string (16) M TLV 18
3.2.4. Challenge Error
Client -> Server
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
02 Cause GMM cause, M TLV 3
04.08: 10.5.5.14
3.2.5. Challenge Result
Client -> Server
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
21 XRES octet string (8) M TLV 10
3.2.3. Sync Request
Client -> Server
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
20 AUTS octet string (16) M TLV 18
3.2.4. Sync Error
Server -> Client
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
02 Cause GMM cause, M TLV 3
04.08: 10.5.5.14
4. Information Elements
4.1. General
[...]
4.2.1. Message Type
+---------------------------------------------------+
| 8 7 6 5 4 3 2 1 |
| |
| 0 0 0 0 0 1 0 0 - Register Request |
| 0 0 0 0 0 1 0 1 - Register Error |
| 0 0 0 0 0 1 1 0 - Register Result |
| |
| 0 0 0 0 1 0 0 0 - Challenge Request |
| 0 0 0 0 1 0 0 1 - Challenge Error |
| 0 0 0 0 1 0 1 0 - Challenge Result |
| |
| 0 0 0 0 1 1 0 0 - Sync Request |
| 0 0 0 0 1 1 0 1 - Sync Error (not used) |
| 0 0 0 0 1 1 1 0 - Sync Result (not used) |
| |
+---------------------------------------------------+
4.2.2. IE Identifier (informational)
These are the standard values for the IEI.
+---------------------------------------------------------+
| IEI Info Element Type |
| |
| 0x02 Cause GMM cause, 04.08: 10.5.5.14 |
| 0x20 RAND octet string |
| 0x23 AUTN octet string |
| 0x24 XRES octet string |
| 0x25 AUTS octet string |
| 0x30 Client ID big endian int (2 octets) |
+---------------------------------------------------------+
4.2.3. Client ID
8 7 6 5 4 3 2 1
+-----------------------------------------------------+
| | Client ID IEI | octet 1
+-----------------------------------------------------+
| Length of Client ID IE contents (2) | octet 2
+-----------------------------------------------------+
| Client ID number, most significant byte | octet 3
+-----------------------------------------------------+
| Client ID number, least significant byte | octet 4
+-----------------------------------------------------+
The Client ID number shall be interpreted as an unsigned 16bit integer, where 0
indicates an invalid / unset ID.

View File

@@ -120,6 +120,7 @@ Network peer -> SGSN
Message type 4.2.1 M V 1
01 IMSI 4.2.9 M TLV 2-10
08 MSISDN 4.2.10 O TLV 0-9
09 HLR Number 4.2.12 O TLV 0-9
04 PDP info complete 4.2.8 O TLV 2
05 PDP info 4.2.3 1-10 TLV
@@ -149,6 +150,7 @@ SGSN -> Network peer
IEI Info Element Type Pres. Format Length
Message type 4.2.1 M V 1
01 IMSI 4.2.9 M TLV 2-10
09 HLR Number 4.2.12 M TLV 0-9
3.2.10. Purge MS Error
@@ -357,6 +359,7 @@ IEI that shall be used for the encoding.
| 0x06 Cancel type 4.2.6 |
| 0x07 Freeze P-TMSI 4.2.8 |
| 0x08 MSISDN ISDN-AddressString/octet, 4.2.10 |
| 0x09 HLR Number 4.2.12 |
| 0x10 PDP context id big endian int |
| 0x11 PDP type 4.2.4 |
| 0x12 APN 04.08, 10.5.6.1 |
@@ -442,3 +445,24 @@ Priority and the reset are encoded as octets 3-N of 24.008.
+-----------------------------------------------------+
: : :
+-----------------------------------------------------+
4.2.12. HLR Number encoded as GSM 09.02 ISDN-AddressString
The HLR Number is encoded as an ISDN-AddressString in GSM 09.02. It
will be stored by the SGSN can be used by the CDR module to keep a
record.
8 7 6 5 4 3 2 1
+-----------------------------------------------------+
| | IEI | octet 1
+-----------------------------------------------------+
| Length of IE contents | octet 2
+-----------------------------------------------------+
| ext | Type of num | Numbering plan | octet 2
+-----------------------------------------------------+
| Number digit 2 | Number digit 1 | octet 3
+-----------------------------------------------------+
| Number digit 4 | Number digit 3 | octet 4
+-----------------------------------------------------+
: : :
+-----------------------------------------------------+

View File

@@ -15,8 +15,12 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
bss.h gsm_data_shared.h ipaccess.h mncc_int.h \
arfcn_range_encode.h nat_rewrite_trie.h bsc_nat_callstats.h \
osmux.h mgcp_transcode.h gprs_utils.h \
gprs_gb_parse.h smpp.h meas_feed.h gprs_gsup_messages.h \
gprs_gsup_client.h bsc_msg_filter.h
gprs_gb_parse.h smpp.h meas_feed.h \
gprs_gsup_client.h bsc_msg_filter.h \
oap.h oap_messages.h \
gtphub.h \
msc_api.h msc_ifaces.h iu.h iu_cs.h \
xsc.h
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
openbscdir = $(includedir)/openbsc

View File

@@ -31,6 +31,7 @@ struct gsm_lchan;
struct gsm_subscriber;
struct gsm_bts_trx_ts;
#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
const uint8_t *data, int len);

View File

@@ -1,16 +1,25 @@
#ifndef _AUTH_H
#define _AUTH_H
#include <osmocom/core/utils.h>
struct gsm_auth_tuple;
struct gsm_subscriber;
enum auth_action {
AUTH_ERROR = -1, /* Internal error */
AUTH_NOT_AVAIL = 0, /* No auth tuple available */
AUTH_DO_AUTH_THAN_CIPH = 1, /* Firsth authenticate, then cipher */
AUTH_DO_AUTH_THEN_CIPH = 1, /* Firsth authenticate, then cipher */
AUTH_DO_CIPH = 2, /* Only ciphering */
AUTH_DO_AUTH = 3, /* Only authentication, no ciphering */
};
extern const struct value_string auth_action_names[];
static inline const char *auth_action_str(enum auth_action a)
{
return get_value_string(auth_action_names, a);
}
int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple,
struct gsm_subscriber *subscr, int key_seq);

View File

@@ -40,7 +40,7 @@ struct bsc_api {
* not implemented AMR5.9 will be used.
*/
void (*mr_config)(struct gsm_subscriber_connection *conn,
struct gsm48_multi_rate_conf *conf);
struct gsm_lchan *lchan, int full_rate);
};
int bsc_api_init(struct gsm_network *network, struct bsc_api *api);
@@ -52,6 +52,4 @@ int gsm0808_page(struct gsm_bts *bts, unsigned int page_group,
unsigned int mi_len, uint8_t *mi, int chan_type);
int gsm0808_clear(struct gsm_subscriber_connection *conn);
struct llist_head *bsc_api_sub_connections(struct gsm_network *net);
#endif

View File

@@ -60,6 +60,6 @@ void bsc_msc_schedule_connect(struct bsc_msc_connection *);
void bsc_msc_lost(struct bsc_msc_connection *);
struct msgb *bsc_msc_id_get_resp(const char *token);
struct msgb *bsc_msc_id_get_resp(int fixed, const char *token, const uint8_t *res, int len);
#endif

View File

@@ -35,6 +35,7 @@
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <regex.h>
#include <stdbool.h>
#define DIR_BSC 1
#define DIR_MSC 2
@@ -84,6 +85,7 @@ struct bsc_connection {
/* do we know anything about this BSC? */
int authenticated;
uint8_t last_rand[16];
/* the fd we use to communicate */
struct osmo_wqueue write_queue;
@@ -147,6 +149,8 @@ enum bsc_cfg_ctr {
struct bsc_config {
struct llist_head entry;
uint8_t key[16];
uint8_t key_present;
char *token;
int nr;
@@ -161,6 +165,10 @@ struct bsc_config {
/* audio handling */
int max_endpoints;
/* used internally for reload handling */
bool remove;
bool token_updated;
/* backpointer */
struct bsc_nat *nat;
@@ -261,6 +269,11 @@ struct bsc_nat {
struct bsc_endpoint *bsc_endpoints;
/* path to file with BSC config */
char *include_file;
char *include_base;
char *resolved_path;
/* filter */
char *acc_lst_name;
@@ -317,8 +330,10 @@ struct bsc_nat_ussd_con {
};
/* create and init the structures */
struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token);
struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token,
unsigned int number);
struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num);
struct bsc_config *bsc_config_by_token(struct bsc_nat *nat, const char *token, int len);
void bsc_config_free(struct bsc_config *);
void bsc_config_add_lac(struct bsc_config *cfg, int lac);
void bsc_config_del_lac(struct bsc_config *cfg, int lac);
@@ -368,7 +383,7 @@ int bsc_mgcp_nat_init(struct bsc_nat *nat);
struct nat_sccp_connection *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
struct msgb *bsc_mgcp_rewrite(char *input, int length, int endp, const char *ip,
int port, int osmux, int *payload_type, int mode_set);
int port, int osmux, int *first_payload_type, int mode_set);
void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);
void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
@@ -419,7 +434,8 @@ void bsc_nat_num_rewr_entry_adapt(void *ctx, struct llist_head *head, const stru
void bsc_nat_send_mgcp_to_msc(struct bsc_nat *bsc_nat, struct msgb *msg);
void bsc_nat_handle_mgcp(struct bsc_nat *bsc, struct msgb *msg);
struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat, int port);
struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat,
const char *bind_addr, int port);
void bsc_nat_ctrl_del_pending(struct bsc_cmd_list *pending);
int bsc_nat_handle_ctrlif_msg(struct bsc_connection *bsc, struct msgb *msg);

View File

@@ -1,11 +1,14 @@
#ifndef _BSS_H_
#define _BSS_H_
#include <openbsc/xsc.h>
struct gsm_network;
struct msgb;
/* start and stop network */
extern int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *), const char *cfg_file);
extern int bsc_network_init(mncc_recv_cb_t mncc_recv);
extern int bsc_network_configure(const char *cfg_file);
extern int bsc_shutdown_net(struct gsm_network *net);
/* register all supported BTS */

View File

@@ -1,3 +1,4 @@
#pragma once
struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net, uint16_t port);
struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net,
const char *bind_addr, uint16_t port);

View File

@@ -33,6 +33,10 @@ enum {
DCTRL,
DSMPP,
DFILTER,
DGTPHUB,
DSUA,
DRANAP,
DIUCS,
Debug_LastEntry,
};

View File

@@ -48,8 +48,24 @@ enum gbproxy_peer_ctr {
GBPROX_PEER_CTR_PATCH_ERR,
GBPROX_PEER_CTR_ATTACH_REQS,
GBPROX_PEER_CTR_ATTACH_REJS,
GBPROX_PEER_CTR_ATTACH_ACKS,
GBPROX_PEER_CTR_ATTACH_COMPLS,
GBPROX_PEER_CTR_RA_UPD_REQS,
GBPROX_PEER_CTR_RA_UPD_REJS,
GBPROX_PEER_CTR_RA_UPD_ACKS,
GBPROX_PEER_CTR_RA_UPD_COMPLS,
GBPROX_PEER_CTR_GMM_STATUS_BSS,
GBPROX_PEER_CTR_GMM_STATUS_SGSN,
GBPROX_PEER_CTR_DETACH_REQS,
GBPROX_PEER_CTR_DETACH_ACKS,
GBPROX_PEER_CTR_PDP_ACT_REQS,
GBPROX_PEER_CTR_PDP_ACT_REJS,
GBPROX_PEER_CTR_PDP_ACT_ACKS,
GBPROX_PEER_CTR_PDP_DEACT_REQS,
GBPROX_PEER_CTR_PDP_DEACT_ACKS,
GBPROX_PEER_CTR_TLLI_UNKNOWN,
GBPROX_PEER_CTR_TLLI_CACHE_SIZE,
GBPROX_PEER_CTR_LAST,
};
enum gbproxy_keep_mode {
@@ -101,10 +117,6 @@ struct gbproxy_config {
/* IMSI checking/matching */
struct gbproxy_match matches[GBPROX_MATCH_LAST];
/* Used to generate identifiers */
unsigned bss_ptmsi_state;
unsigned sgsn_tlli_state;
};
struct gbproxy_patch_state {

View File

@@ -10,7 +10,9 @@ int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp);
int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme);
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme);
int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
uint16_t *sai);
int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx);
int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg);
void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx);

View File

@@ -23,6 +23,8 @@
#include <osmocom/core/timer.h>
#include <openbsc/oap.h>
#define GPRS_GSUP_RECONNECT_INTERVAL 10
#define GPRS_GSUP_PING_INTERVAL 20
@@ -38,6 +40,8 @@ struct gprs_gsup_client {
gprs_gsup_read_cb_t read_cb;
void *data;
struct oap_state oap_state;
struct osmo_timer_list ping_timer;
struct osmo_timer_list connect_timer;
int is_connected;
@@ -46,7 +50,8 @@ struct gprs_gsup_client {
struct gprs_gsup_client *gprs_gsup_client_create(const char *ip_addr,
unsigned int tcp_port,
gprs_gsup_read_cb_t read_cb);
gprs_gsup_read_cb_t read_cb,
struct oap_config *oap_config);
void gprs_gsup_client_destroy(struct gprs_gsup_client *gsupc);
int gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);

View File

@@ -1,116 +0,0 @@
/* GPRS Subscriber Update Protocol message encoder/decoder */
/* (C) 2014 by Sysmocom s.f.m.c. GmbH
* All Rights Reserved
*
* Author: Jacob Erlbeck
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/gsm_data.h>
/* Needed for GSM_IMSI_LENGTH: */
#include <openbsc/gsm_subscriber.h>
#define GPRS_GSUP_MAX_NUM_PDP_INFO 10 /* GSM 09.02 limits this to 50 */
#define GPRS_GSUP_MAX_NUM_AUTH_INFO 5
#define GPRS_GSUP_MAX_MSISDN_LEN 9
#define GPRS_GSUP_PDP_TYPE_SIZE 2
enum gprs_gsup_iei {
GPRS_GSUP_IMSI_IE = 0x01,
GPRS_GSUP_CAUSE_IE = 0x02,
GPRS_GSUP_AUTH_TUPLE_IE = 0x03,
GPRS_GSUP_PDP_INFO_COMPL_IE = 0x04,
GPRS_GSUP_PDP_INFO_IE = 0x05,
GPRS_GSUP_CANCEL_TYPE_IE = 0x06,
GPRS_GSUP_FREEZE_PTMSI_IE = 0x07,
GPRS_GSUP_MSISDN_IE = 0x08,
GPRS_GSUP_PDP_CONTEXT_ID_IE = 0x10,
GPRS_GSUP_PDP_TYPE_IE = 0x11,
GPRS_GSUP_ACCESS_POINT_NAME_IE = 0x12,
GPRS_GSUP_PDP_QOS_IE = 0x13,
GPRS_GSUP_RAND_IE = 0x20,
GPRS_GSUP_SRES_IE = 0x21,
GPRS_GSUP_KC_IE = 0x22
};
enum gprs_gsup_message_type {
GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST = 0b00000100,
GPRS_GSUP_MSGT_UPDATE_LOCATION_ERROR = 0b00000101,
GPRS_GSUP_MSGT_UPDATE_LOCATION_RESULT = 0b00000110,
GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST = 0b00001000,
GPRS_GSUP_MSGT_SEND_AUTH_INFO_ERROR = 0b00001001,
GPRS_GSUP_MSGT_SEND_AUTH_INFO_RESULT = 0b00001010,
GPRS_GSUP_MSGT_PURGE_MS_REQUEST = 0b00001100,
GPRS_GSUP_MSGT_PURGE_MS_ERROR = 0b00001101,
GPRS_GSUP_MSGT_PURGE_MS_RESULT = 0b00001110,
GPRS_GSUP_MSGT_INSERT_DATA_REQUEST = 0b00010000,
GPRS_GSUP_MSGT_INSERT_DATA_ERROR = 0b00010001,
GPRS_GSUP_MSGT_INSERT_DATA_RESULT = 0b00010010,
GPRS_GSUP_MSGT_DELETE_DATA_REQUEST = 0b00010100,
GPRS_GSUP_MSGT_DELETE_DATA_ERROR = 0b00010101,
GPRS_GSUP_MSGT_DELETE_DATA_RESULT = 0b00010110,
GPRS_GSUP_MSGT_LOCATION_CANCEL_REQUEST = 0b00011100,
GPRS_GSUP_MSGT_LOCATION_CANCEL_ERROR = 0b00011101,
GPRS_GSUP_MSGT_LOCATION_CANCEL_RESULT = 0b00011110,
};
#define GPRS_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00)
#define GPRS_GSUP_IS_MSGT_ERROR(msgt) (((msgt) & 0b00000011) == 0b01)
#define GPRS_GSUP_TO_MSGT_ERROR(msgt) (((msgt) & 0b11111100) | 0b01)
enum gprs_gsup_cancel_type {
GPRS_GSUP_CANCEL_TYPE_UPDATE = 1, /* on wire: 0 */
GPRS_GSUP_CANCEL_TYPE_WITHDRAW = 2, /* on wire: 1 */
};
struct gprs_gsup_pdp_info {
unsigned int context_id;
int have_info;
uint16_t pdp_type;
const uint8_t *apn_enc;
size_t apn_enc_len;
const uint8_t *qos_enc;
size_t qos_enc_len;
};
struct gprs_gsup_message {
enum gprs_gsup_message_type message_type;
char imsi[GSM_IMSI_LENGTH];
enum gsm48_gmm_cause cause;
enum gprs_gsup_cancel_type cancel_type;
int pdp_info_compl;
int freeze_ptmsi;
struct gsm_auth_tuple auth_tuples[GPRS_GSUP_MAX_NUM_AUTH_INFO];
size_t num_auth_tuples;
struct gprs_gsup_pdp_info pdp_infos[GPRS_GSUP_MAX_NUM_PDP_INFO];
size_t num_pdp_infos;
const uint8_t *msisdn_enc;
size_t msisdn_enc_len;
};
int gprs_gsup_decode(const uint8_t *data, size_t data_len,
struct gprs_gsup_message *gsup_msg);
void gprs_gsup_encode(struct msgb *msg, const struct gprs_gsup_message *gsup_msg);

View File

@@ -9,11 +9,10 @@
#include <osmocom/gsm/gsm48.h>
#include <osmocom/crypt/gprs_cipher.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
#include <openbsc/gsm_data.h>
#define GSM_IMSI_LENGTH 17
#define GSM_IMEI_LENGTH 17
#define GSM_EXTENSION_LENGTH 15
#define GSM_APN_LENGTH 102
@@ -24,7 +23,7 @@ struct gsm_subscriber;
enum gsm48_gsm_cause;
/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */
enum gprs_mm_state {
enum gprs_gmm_state {
GMM_DEREGISTERED, /* 4.1.3.3.1.1 */
GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */
GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */
@@ -32,6 +31,16 @@ enum gprs_mm_state {
GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
};
/* TS 23.060 6.1.1 and 6.1.2 Mobility management states A/Gb and Iu mode */
enum gprs_pmm_state {
PMM_DETACHED,
PMM_CONNECTED,
PMM_IDLE,
MM_IDLE = PMM_DETACHED,
MM_READY = PMM_CONNECTED,
MM_STANDBY = PMM_IDLE,
};
enum gprs_mm_ctr {
GMM_CTR_PKTS_SIG_IN,
GMM_CTR_PKTS_SIG_OUT,
@@ -70,24 +79,88 @@ enum sgsn_auth_state {
#define MS_RADIO_ACCESS_CAPA
enum sgsn_ggsn_lookup_state {
SGSN_GGSN_2DIGIT,
SGSN_GGSN_3DIGIT,
};
struct sgsn_ggsn_lookup {
int state;
struct sgsn_mm_ctx *mmctx;
/* APN string */
char apn_str[GSM_APN_LENGTH];
/* the original data */
struct msgb *orig_msg;
struct tlv_parsed tp;
/* for dealing with re-transmissions */
uint8_t nsapi;
uint8_t sapi;
uint8_t ti;
};
enum sgsn_ran_type {
/* GPRS/EDGE via Gb */
MM_CTX_T_GERAN_Gb,
/* UMTS via Iu */
MM_CTX_T_UTRAN_Iu,
/* GPRS/EDGE via Iu */
MM_CTX_T_GERAN_Iu,
};
struct service_info {
uint8_t type;
uint16_t pdp_status;
};
struct ue_conn_ctx;
/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */
/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */
struct sgsn_mm_ctx {
struct llist_head list;
char imsi[GSM_IMSI_LENGTH];
enum gprs_mm_state mm_state;
enum sgsn_ran_type ran_type;
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
enum gprs_gmm_state mm_state;
enum gprs_pmm_state pmm_state;
uint32_t p_tmsi;
uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */
uint32_t p_tmsi_sig;
char imei[GSM_IMEI_LENGTH];
char imei[GSM23003_IMEISV_NUM_DIGITS+1];
/* Opt: Software Version Numbber / TS 23.195 */
char msisdn[GSM_EXTENSION_LENGTH];
struct gprs_ra_id ra;
uint16_t cell_id;
uint32_t cell_id_age;
uint16_t sac; /* Iu: Service Area Code */
uint32_t sac_age;/* Iu: Service Area Code age */
struct {
uint16_t cell_id; /* Gb only */
uint32_t cell_id_age; /* Gb only */
uint8_t radio_prio_sms;
/* Additional bits not present in the GSM TS */
uint16_t nsei;
uint16_t bvci;
struct gprs_llc_llme *llme;
uint32_t tlli;
uint32_t tlli_new;
} gb;
struct {
int new_key;
uint16_t sac; /* Iu: Service Area Code */
uint32_t sac_age; /* Iu: Service Area Code age */
/* CSG ID */
/* CSG Membership */
/* Access Mode */
/* Seelected CN Operator ID (TS 23.251) */
/* CSG Subscription Data */
/* LIPA Allowed */
/* Voice Support Match Indicator */
struct ue_conn_ctx *ue_ctx;
struct service_info service;
} iu;
/* VLR number */
uint32_t new_sgsn_addr;
/* Authentication Triplet */
@@ -96,30 +169,38 @@ struct sgsn_mm_ctx {
/* Iu: CK, IK, KSI */
/* CKSN */
enum gprs_ciph_algo ciph_algo;
struct {
uint8_t len;
uint8_t buf[50]; /* GSM 04.08 10.5.5.12a, extended in TS 24.008 */
} ms_radio_access_capa;
/* Supported Codecs (SRVCC) */
struct {
uint8_t len;
uint8_t buf[8]; /* GSM 04.08 10.5.5.12, extended in TS 24.008 */
} ms_network_capa;
/* UE Netowrk Capability (E-UTRAN) */
uint16_t drx_parms;
/* Active Time value for PSM */
int mnrg; /* MS reported to HLR? */
int ngaf; /* MS reported to MSC/VLR? */
int ppf; /* paging for GPRS + non-GPRS? */
/* Subscribed Charging Characteristics */
/* Trace Reference */
/* Trace Type */
/* Trigger ID */
/* OMC Identity */
/* SMS Parameters */
int recovery;
uint8_t radio_prio_sms;
/* Access Restriction */
/* GPRS CSI (CAMEL) */
/* MG-CSI (CAMEL) */
/* Subscribed UE-AMBR */
/* UE-AMBR */
/* APN Subscribed */
struct llist_head pdp_list;
/* Additional bits not present in the GSM TS */
struct gprs_llc_llme *llme;
uint32_t tlli;
uint32_t tlli_new;
uint16_t nsei;
uint16_t bvci;
struct rate_ctr_group *ctrg;
struct osmo_timer_list timer;
unsigned int T; /* Txxxx number */
@@ -136,6 +217,12 @@ struct sgsn_mm_ctx {
enum sgsn_auth_state auth_state;
int is_authenticated;
/* the string representation of the current hlr */
char hlr[GSM_EXTENSION_LENGTH];
/* the current GGSN look-up operation */
struct sgsn_ggsn_lookup *ggsn_lookup;
struct gsm_subscriber *subscr;
};
@@ -148,16 +235,23 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
const struct gprs_ra_id *raid);
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx);
/* look-up by matching TLLI and P-TMSI (think twice before using this) */
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
const struct gprs_ra_id *raid);
/* Allocate a new SGSN MM context */
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
const struct gprs_ra_id *raid);
void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm);
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx);
void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx);
struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
struct tlv_parsed *tp,
enum gsm48_gsm_cause *gsm_cause);
enum gsm48_gsm_cause *gsm_cause,
char *apn_str);
enum pdp_ctx_state {
PDP_STATE_NONE,
@@ -180,6 +274,7 @@ struct sgsn_pdp_ctx {
struct llist_head list; /* list_head for mmctx->pdp_list */
struct llist_head g_list; /* list_head for global list */
struct sgsn_mm_ctx *mm; /* back pointer to MM CTX */
int destroy_ggsn; /* destroy it on destruction */
struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */
struct rate_ctr_group *ctrg;
@@ -208,6 +303,12 @@ struct sgsn_pdp_ctx {
struct osmo_timer_list timer;
unsigned int T; /* Txxxx number */
unsigned int num_T_exp; /* number of consecutive T expirations */
struct osmo_timer_list cdr_timer; /* CDR record wird timer */
struct timespec cdr_start; /* The start of the CDR */
uint64_t cdr_bytes_in;
uint64_t cdr_bytes_out;
uint32_t cdr_charging_id;
};
#define LOGPDPCTXP(level, pdp, fmt, args...) \
@@ -275,7 +376,8 @@ int sgsn_force_reattach_oldmsg(struct msgb *oldmsg);
* ctrl interface related work
*/
struct gsm_network;
struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *, uint16_t port);
struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *,
const char *bind_addr, uint16_t port);
int sgsn_ctrl_cmds_install(void);
/*
@@ -307,6 +409,9 @@ struct sgsn_subscriber_data {
uint8_t msisdn[9];
size_t msisdn_len;
uint8_t hlr[9];
size_t hlr_len;
};
#define SGSN_ERROR_CAUSE_NONE (-1)

View File

@@ -25,6 +25,7 @@
#include <sys/types.h>
struct msgb;
struct gprs_ra_id;
struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name);
int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area,
@@ -41,14 +42,4 @@ int gprs_is_mi_imsi(const uint8_t *value, size_t value_len);
int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi);
void gprs_parse_tmsi(const uint8_t *value, uint32_t *tmsi);
int gprs_shift_v_fixed(uint8_t **data, size_t *data_len,
size_t len, uint8_t **value);
int gprs_match_tv_fixed(uint8_t **data, size_t *data_len,
uint8_t tag, size_t len, uint8_t **value);
int gprs_shift_tlv(uint8_t **data, size_t *data_len,
uint8_t *tag, uint8_t **value, size_t *value_len);
int gprs_match_tlv(uint8_t **data, size_t *data_len,
uint8_t tag, uint8_t **value, size_t *value_len);
int gprs_shift_lv(uint8_t **data, size_t *data_len,
uint8_t **value, size_t *value_len);
int gprs_ra_id_equals(const struct gprs_ra_id *id1, const struct gprs_ra_id *id2);

View File

@@ -13,14 +13,30 @@ struct gsm_subscriber;
struct gsm_network;
struct gsm_trans;
struct gsm_subscriber_connection;
struct amr_multirate_conf;
struct amr_mode;
#define GSM48_ALLOC_SIZE 2048
#define GSM48_ALLOC_HEADROOM 256
static inline struct msgb *gsm48_msgb_alloc(void)
static inline struct msgb *gsm48_msgb_alloc_name(const char *name)
{
return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM,
"GSM 04.08");
name);
}
static inline int get_radio_link_timeout(struct gsm48_cell_options *cell_options)
{
return (cell_options->radio_link_timeout + 1) << 2;
}
static inline void set_radio_link_timeout(struct gsm48_cell_options *cell_options, int value)
{
if (value < 4)
value = 4;
if (value > 64)
value = 64;
cell_options->radio_link_timeout = (value >> 2) - 1;
}
/* config options controlling the behaviour of the lower leves */
@@ -61,6 +77,8 @@ int decode_bcd_number(char *output, int output_len, const uint8_t *bcd_lv,
int send_siemens_mrpci(struct gsm_lchan *lchan, uint8_t *classmark2_lv);
int gsm48_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type);
int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, uint8_t *mi_type);
/* TODO MSCSPLIT remove gsm48_handle_paging_resp() */
int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, struct msgb *msg, struct gsm_subscriber *subscr);
int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t lchan_mode);
@@ -75,4 +93,6 @@ void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
void release_security_operation(struct gsm_subscriber_connection *conn);
void allocate_security_operation(struct gsm_subscriber_connection *conn);
int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, struct amr_mode *modes);
#endif

View File

@@ -1,397 +1,21 @@
#ifndef _GSM48_GPRS_H
#define _GSM48_GPRS_H
#pragma once
#include <stdint.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
/* Table 10.4 / 10.4a, GPRS Mobility Management (GMM) */
#define GSM48_MT_GMM_ATTACH_REQ 0x01
#define GSM48_MT_GMM_ATTACH_ACK 0x02
#define GSM48_MT_GMM_ATTACH_COMPL 0x03
#define GSM48_MT_GMM_ATTACH_REJ 0x04
#define GSM48_MT_GMM_DETACH_REQ 0x05
#define GSM48_MT_GMM_DETACH_ACK 0x06
/* TODO: Move this to osmocom/gsm/protocol/gsm_04_08_gprs.h ? */
#define GSM48_MT_GMM_RA_UPD_REQ 0x08
#define GSM48_MT_GMM_RA_UPD_ACK 0x09
#define GSM48_MT_GMM_RA_UPD_COMPL 0x0a
#define GSM48_MT_GMM_RA_UPD_REJ 0x0b
/* Table 10.4 in 3GPP TS 24.008 (successor to 04.08) */
#define GSM48_MT_GMM_SERVICE_REQ 0x0c
#define GSM48_MT_GMM_SERVICE_ACK 0x0d
#define GSM48_MT_GMM_SERVICE_REJ 0x0e
#define GSM48_MT_GMM_PTMSI_REALL_CMD 0x10
#define GSM48_MT_GMM_PTMSI_REALL_COMPL 0x11
#define GSM48_MT_GMM_AUTH_CIPH_REQ 0x12
#define GSM48_MT_GMM_AUTH_CIPH_RESP 0x13
#define GSM48_MT_GMM_AUTH_CIPH_REJ 0x14
#define GSM48_MT_GMM_ID_REQ 0x15
#define GSM48_MT_GMM_ID_RESP 0x16
#define GSM48_MT_GMM_STATUS 0x20
#define GSM48_MT_GMM_INFO 0x21
/* Table 10.4a, GPRS Session Management (GSM) */
#define GSM48_MT_GSM_ACT_PDP_REQ 0x41
#define GSM48_MT_GSM_ACT_PDP_ACK 0x42
#define GSM48_MT_GSM_ACT_PDP_REJ 0x43
#define GSM48_MT_GSM_REQ_PDP_ACT 0x44
#define GSM48_MT_GSM_REQ_PDP_ACT_REJ 0x45
#define GSM48_MT_GSM_DEACT_PDP_REQ 0x46
#define GSM48_MT_GSM_DEACT_PDP_ACK 0x47
#define GSM48_MT_GSM_ACT_AA_PDP_REQ 0x50
#define GSM48_MT_GSM_ACT_AA_PDP_ACK 0x51
#define GSM48_MT_GSM_ACT_AA_PDP_REJ 0x52
#define GSM48_MT_GSM_DEACT_AA_PDP_REQ 0x53
#define GSM48_MT_GSM_DEACT_AA_PDP_ACK 0x54
#define GSM48_MT_GSM_STATUS 0x55
/* Chapter 10.5.5.2 / Table 10.5.135 */
#define GPRS_ATT_T_ATTACH 1
#define GPRS_ATT_T_ATT_WHILE_IMSI 2
#define GPRS_ATT_T_COMBINED 3
extern const struct value_string *gprs_att_t_strs;
/* Chapter 10.5.5.5 / Table 10.5.138 */
#define GPRS_DET_T_MO_GPRS 1
#define GPRS_DET_T_MO_IMSI 2
#define GPRS_DET_T_MO_COMBINED 3
/* Network to MS direction */
#define GPRS_DET_T_MT_REATT_REQ 1
#define GPRS_DET_T_MT_REATT_NOTREQ 2
#define GPRS_DET_T_MT_IMSI 3
extern const struct value_string *gprs_det_t_mo_strs;
extern const struct value_string *gprs_det_t_mt_strs;
/* Chapter 10.5.5.18 / Table 105.150 */
#define GPRS_UPD_T_RA 0
#define GPRS_UPD_T_RA_LA 1
#define GPRS_UPD_T_RA_LA_IMSI_ATT 2
#define GPRS_UPD_T_PERIODIC 3
extern const struct value_string *gprs_upd_t_strs;
enum gsm48_gprs_ie_mm {
GSM48_IE_GMM_CIPH_CKSN = 0x08, /* 10.5.1.2 */
GSM48_IE_GMM_TIMER_READY = 0x17, /* 10.5.7.3 */
GSM48_IE_GMM_ALLOC_PTMSI = 0x18, /* 10.5.1.4 */
GSM48_IE_GMM_PTMSI_SIG = 0x19, /* 10.5.5.8 */
GSM48_IE_GMM_AUTH_RAND = 0x21, /* 10.5.3.1 */
GSM48_IE_GMM_AUTH_SRES = 0x22, /* 10.5.3.2 */
GSM48_IE_GMM_IMEISV = 0x23, /* 10.5.1.4 */
GSM48_IE_GMM_CAUSE = 0x25, /* 10.5.5.14 */
GSM48_IE_GMM_DRX_PARAM = 0x27, /* 10.5.5.6 */
GSM48_IE_GMM_MS_NET_CAPA = 0x31, /* 10.5.5.12 */
GSM48_IE_GMM_PDP_CTX_STATUS = 0x32, /* 10.5.7.1 */
GSM48_IE_GMM_PS_LCS_CAPA = 0x33, /* 10.5.5.22 */
GSM48_IE_GMM_GMM_MBMS_CTX_ST = 0x35, /* 10.5.7.6 */
/* 3GPP 24.008 / Chapter 10.5.5.20 / Table 10.5.153a */
enum gsm48_gmm_service_type {
GPRS_SERVICE_T_SIGNALLING = 0x00,
GPRS_SERVICE_T_DATA = 0x01,
GPRS_SERVICE_T_PAGING_RESP = 0x02,
GPRS_SERVICE_T_MBMS_MC_SERV = 0x03,
GPRS_SERVICE_T_MBMS_BC_SERV = 0x04,
};
enum gsm48_gprs_ie_sm {
GSM48_IE_GSM_APN = 0x28, /* 10.5.6.1 */
GSM48_IE_GSM_PROTO_CONF_OPT = 0x27, /* 10.5.6.3 */
GSM48_IE_GSM_PDP_ADDR = 0x2b, /* 10.5.6.4 */
GSM48_IE_GSM_AA_TMR = 0x29, /* 10.5.7.3 */
GSM48_IE_GSM_NAME_FULL = 0x43, /* 10.5.3.5a */
GSM48_IE_GSM_NAME_SHORT = 0x45, /* 10.5.3.5a */
GSM48_IE_GSM_TIMEZONE = 0x46, /* 10.5.3.8 */
GSM48_IE_GSM_UTC_AND_TZ = 0x47, /* 10.5.3.9 */
GSM48_IE_GSM_LSA_ID = 0x48, /* 10.5.3.11 */
/* Fake IEs that are not present on the Layer3 air interface,
* but which we use to simplify internal APIs */
OSMO_IE_GSM_REQ_QOS = 0xfd,
OSMO_IE_GSM_REQ_PDP_ADDR = 0xfe,
OSMO_IE_GSM_SUB_QOS = 0xff,
};
/* Chapter 9.4.15 / Table 9.4.15 */
struct gsm48_ra_upd_ack {
uint8_t force_stby:4, /* 10.5.5.7 */
upd_result:4; /* 10.5.5.17 */
uint8_t ra_upd_timer; /* 10.5.7.3 */
struct gsm48_ra_id ra_id; /* 10.5.5.15 */
uint8_t data[0];
} __attribute__((packed));
/* Chapter 10.5.7.3 */
enum gsm48_gprs_tmr_unit {
GPRS_TMR_2SECONDS = 0 << 5,
GPRS_TMR_MINUTE = 1 << 5,
GPRS_TMR_6MINUTE = 2 << 5,
GPRS_TMR_DEACTIVATED = 7 << 5,
};
#define GPRS_TMR_UNIT_MASK (7 << 5)
#define GPRS_TMR_FACT_MASK ((1 << 5)-1)
/* Chapter 9.4.2 / Table 9.4.2 */
struct gsm48_attach_ack {
uint8_t att_result:4, /* 10.5.5.7 */
force_stby:4; /* 10.5.5.1 */
uint8_t ra_upd_timer; /* 10.5.7.3 */
uint8_t radio_prio; /* 10.5.7.2 */
struct gsm48_ra_id ra_id; /* 10.5.5.15 */
uint8_t data[0];
} __attribute__((packed));
/* Chapter 9.4.9 / Table 9.4.9 */
struct gsm48_auth_ciph_req {
uint8_t ciph_alg:4, /* 10.5.5.3 */
imeisv_req:4; /* 10.5.5.10 */
uint8_t force_stby:4, /* 10.5.5.7 */
ac_ref_nr:4; /* 10.5.5.19 */
uint8_t data[0];
} __attribute__((packed));
/* optional: TV RAND, TV CKSN */
struct gsm48_auth_ciph_resp {
uint8_t ac_ref_nr:4,
spare:4;
uint8_t data[0];
} __attribute__((packed));
/* Chapter 9.5.1 / Table 9.5.1 */
struct gsm48_act_pdp_ctx_req {
uint8_t req_nsapi;
uint8_t req_llc_sapi;
uint8_t data[0];
} __attribute__((packed));
/* Chapter 10.5.5.14 / Table 10.5.147 */
enum gsm48_gmm_cause {
GMM_CAUSE_IMSI_UNKNOWN = 0x02,
GMM_CAUSE_ILLEGAL_MS = 0x03,
GMM_CAUSE_ILLEGAL_ME = 0x06,
GMM_CAUSE_GPRS_NOTALLOWED = 0x07,
GMM_CAUSE_GPRS_OTHER_NOTALLOWED = 0x08,
GMM_CAUSE_MS_ID_NOT_DERIVED = 0x09,
GMM_CAUSE_IMPL_DETACHED = 0x0a,
GMM_CAUSE_PLMN_NOTALLOWED = 0x0b,
GMM_CAUSE_LA_NOTALLOWED = 0x0c,
GMM_CAUSE_ROAMING_NOTALLOWED = 0x0d,
GMM_CAUSE_NO_GPRS_PLMN = 0x0e,
GMM_CAUSE_MSC_TEMP_NOTREACH = 0x10,
GMM_CAUSE_NET_FAIL = 0x11,
GMM_CAUSE_CONGESTION = 0x16,
GMM_CAUSE_SEM_INCORR_MSG = 0x5f,
GMM_CAUSE_INV_MAND_INFO = 0x60,
GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
GMM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
GMM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
GMM_CAUSE_COND_IE_ERR = 0x64,
GMM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
GMM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
};
extern const struct value_string *gsm48_gmm_cause_names;
/* Chapter 10.4.6.6 / Table 10.5.157 */
enum gsm48_gsm_cause {
GSM_CAUSE_INSUFF_RSRC = 0x1a,
GSM_CAUSE_MISSING_APN = 0x1b,
GSM_CAUSE_UNKNOWN_PDP = 0x1c,
GSM_CAUSE_AUTH_FAILED = 0x1d,
GSM_CAUSE_ACT_REJ_GGSN = 0x1e,
GSM_CAUSE_ACT_REJ_UNSPEC = 0x1f,
GSM_CAUSE_SERV_OPT_NOTSUPP = 0x20,
GSM_CAUSE_REQ_SERV_OPT_NOTSUB = 0x21,
GSM_CAUSE_SERV_OPT_TEMP_OOO = 0x22,
GSM_CAUSE_NSAPI_IN_USE = 0x23,
GSM_CAUSE_DEACT_REGULAR = 0x24,
GSM_CAUSE_QOS_NOT_ACCEPTED = 0x25,
GSM_CAUSE_NET_FAIL = 0x26,
GSM_CAUSE_REACT_RQD = 0x27,
GSM_CAUSE_FEATURE_NOTSUPP = 0x28,
GSM_CAUSE_INVALID_TRANS_ID = 0x51,
GSM_CAUSE_SEM_INCORR_MSG = 0x5f,
GSM_CAUSE_INV_MAND_INFO = 0x60,
GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
GSM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
GSM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
GSM_CAUSE_COND_IE_ERR = 0x64,
GSM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
GSM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
};
extern const struct value_string *gsm48_gsm_cause_names;
/* Section 6.1.2.2: Session management states on the network side */
enum gsm48_pdp_state {
PDP_S_INACTIVE,
PDP_S_ACTIVE_PENDING,
PDP_S_ACTIVE,
PDP_S_INACTIVE_PENDING,
PDP_S_MODIFY_PENDING,
};
/* Table 10.5.155/3GPP TS 24.008 */
enum gsm48_pdp_type_org {
PDP_TYPE_ORG_ETSI = 0x00,
PDP_TYPE_ORG_IETF = 0x01,
};
enum gsm48_pdp_type_nr {
PDP_TYPE_N_ETSI_RESERVED = 0x00,
PDP_TYPE_N_ETSI_PPP = 0x01,
PDP_TYPE_N_IETF_IPv4 = 0x21,
PDP_TYPE_N_IETF_IPv6 = 0x57,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_reliab_class {
GSM48_QOS_RC_LLC_ACK_RLC_ACK_DATA_PROT = 2,
GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT = 3,
GSM48_QOS_RC_LLC_UN_RLC_UN_PROT_DATA = 4,
GSM48_QOS_RC_LLC_UN_RLC_UN_DATA_UN = 5,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_preced_class {
GSM48_QOS_PC_HIGH = 1,
GSM48_QOS_PC_NORMAL = 2,
GSM48_QOS_PC_LOW = 3,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_peak_tput {
GSM48_QOS_PEAK_TPUT_1000bps = 1,
GSM48_QOS_PEAK_TPUT_2000bps = 2,
GSM48_QOS_PEAK_TPUT_4000bps = 3,
GSM48_QOS_PEAK_TPUT_8000bps = 4,
GSM48_QOS_PEAK_TPUT_16000bps = 5,
GSM48_QOS_PEAK_TPUT_32000bps = 6,
GSM48_QOS_PEAK_TPUT_64000bps = 7,
GSM48_QOS_PEAK_TPUT_128000bps = 8,
GSM48_QOS_PEAK_TPUT_256000bps = 9,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_mean_tput {
GSM48_QOS_MEAN_TPUT_100bph = 1,
GSM48_QOS_MEAN_TPUT_200bph = 2,
GSM48_QOS_MEAN_TPUT_500bph = 3,
GSM48_QOS_MEAN_TPUT_1000bph = 4,
GSM48_QOS_MEAN_TPUT_2000bph = 5,
GSM48_QOS_MEAN_TPUT_5000bph = 6,
GSM48_QOS_MEAN_TPUT_10000bph = 7,
GSM48_QOS_MEAN_TPUT_20000bph = 8,
GSM48_QOS_MEAN_TPUT_50000bph = 9,
GSM48_QOS_MEAN_TPUT_100kbph = 10,
GSM48_QOS_MEAN_TPUT_200kbph = 11,
GSM48_QOS_MEAN_TPUT_500kbph = 0xc,
GSM48_QOS_MEAN_TPUT_1Mbph = 0xd,
GSM48_QOS_MEAN_TPUT_2Mbph = 0xe,
GSM48_QOS_MEAN_TPUT_5Mbph = 0xf,
GSM48_QOS_MEAN_TPUT_10Mbph = 0x10,
GSM48_QOS_MEAN_TPUT_20Mbph = 0x11,
GSM48_QOS_MEAN_TPUT_50Mbph = 0x12,
GSM48_QOS_MEAN_TPUT_BEST_EFFORT = 0x1f,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_err_sdu {
GSM48_QOS_ERRSDU_NODETECT = 1,
GSM48_QOS_ERRSDU_YES = 2,
GSM48_QOS_ERRSDU_NO = 3,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_deliv_order {
GSM48_QOS_DO_ORDERED = 1,
GSM48_QOS_DO_UNORDERED = 2,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_traf_class {
GSM48_QOS_TC_CONVERSATIONAL = 1,
GSM48_QOS_TC_STREAMING = 2,
GSM48_QOS_TC_INTERACTIVE = 3,
GSM48_QOS_TC_BACKGROUND = 4,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_max_sdu_size {
/* values below in 10 octet granularity */
GSM48_QOS_MAXSDU_1502 = 0x97,
GSM48_QOS_MAXSDU_1510 = 0x98,
GSM48_QOS_MAXSDU_1520 = 0x99,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_max_bitrate {
GSM48_QOS_MBRATE_1k = 0x01,
GSM48_QOS_MBRATE_63k = 0x3f,
GSM48_QOS_MBRATE_64k = 0x40,
GSM48_QOS_MBRATE_568k = 0x7f,
GSM48_QOS_MBRATE_576k = 0x80,
GSM48_QOS_MBRATE_8640k = 0xfe,
GSM48_QOS_MBRATE_0k = 0xff,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_resid_ber {
GSM48_QOS_RBER_5e_2 = 0x01,
GSM48_QOS_RBER_1e_2 = 0x02,
GSM48_QOS_RBER_5e_3 = 0x03,
GSM48_QOS_RBER_4e_3 = 0x04,
GSM48_QOS_RBER_1e_3 = 0x05,
GSM48_QOS_RBER_1e_4 = 0x06,
GSM48_QOS_RBER_1e_5 = 0x07,
GSM48_QOS_RBER_1e_6 = 0x08,
GSM48_QOS_RBER_6e_8 = 0x09,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
enum gsm48_qos_sdu_err {
GSM48_QOS_SERR_1e_2 = 0x01,
GSM48_QOS_SERR_7e_2 = 0x02,
GSM48_QOS_SERR_1e_3 = 0x03,
GSM48_QOS_SERR_1e_4 = 0x04,
GSM48_QOS_SERR_1e_5 = 0x05,
GSM48_QOS_SERR_1e_6 = 0x06,
GSM48_QOS_SERR_1e_1 = 0x07,
};
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
struct gsm48_qos {
/* octet 3 */
uint8_t reliab_class:3;
uint8_t delay_class:3;
uint8_t spare:2;
/* octet 4 */
uint8_t preced_class:3;
uint8_t spare2:1;
uint8_t peak_tput:4;
/* octet 5 */
uint8_t mean_tput:5;
uint8_t spare3:3;
/* octet 6 */
uint8_t deliv_err_sdu:3;
uint8_t deliv_order:2;
uint8_t traf_class:3;
/* octet 7 */
uint8_t max_sdu_size;
/* octet 8 */
uint8_t max_bitrate_up;
/* octet 9 */
uint8_t max_bitrate_down;
/* octet 10 */
uint8_t sdu_err_ratio:4;
uint8_t resid_ber:4;
/* octet 11 */
uint8_t handling_prio:2;
uint8_t xfer_delay:6;
/* octet 12 */
uint8_t guar_bitrate_up;
/* octet 13 */
uint8_t guar_bitrate_down;
/* octet 14 */
uint8_t src_stats_desc:4;
uint8_t sig_ind:1;
uint8_t spare5:3;
/* octet 15 */
uint8_t max_bitrate_down_ext;
/* octet 16 */
uint8_t guar_bitrate_down_ext;
};
#endif /* _GSM48_GPRS_H */
extern const struct value_string *gprs_service_t_strs;

View File

@@ -38,5 +38,5 @@ int gsm411_send_sms(struct gsm_subscriber_connection *conn,
struct gsm_sms *sms);
void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn);
uint8_t sms_next_rp_msg_ref(struct gsm_subscriber_connection *conn);
uint8_t sms_next_rp_msg_ref(uint8_t *next_rp_ref);
#endif

View File

@@ -14,6 +14,9 @@ int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
const struct msgb *msg,
const struct ussd_request *request);
struct msgb *gsm0480_gen_ussdNotify(int level, const char *text);
struct msgb *gsm0480_gen_releaseComplete(void);
int gsm0480_send_ussdNotify(struct gsm_subscriber_connection *conn, int level, const char *text);
int gsm0480_send_releaseComplete(struct gsm_subscriber_connection *conn);

View File

@@ -5,8 +5,10 @@
#include <osmocom/core/timer.h>
#include <osmocom/core/select.h>
#include <osmocom/crypt/auth.h>
#include <openbsc/rest_octets.h>
#include <openbsc/xsc.h>
/** annotations for msgb ownership */
#define __uses
@@ -47,9 +49,7 @@ struct gsm_auth_info {
struct gsm_auth_tuple {
int use_count;
int key_seq;
uint8_t rand[16];
uint8_t sres[4];
uint8_t kc[8];
struct osmo_auth_vector vec;
};
#define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */
@@ -98,7 +98,19 @@ struct neigh_meas_proc {
uint8_t last_seen_nr;
};
/* the per subscriber data for lchan */
enum interface_type {
IFACE_UNKNOWN = -1,
IFACE_A = 0, /* A-interface for 2G */
IFACE_IU = 1 /* Iu-interface for UMTS aka 3G (IuCS or IuPS) */
};
enum integrity_protection_state {
INTEGRITY_PROTECTION_NONE = 0,
INTEGRITY_PROTECTION_IK = 1,
INTEGRITY_PROTECTION_IK_CK = 2,
};
/* mobile subscriber data */
struct gsm_subscriber_connection {
struct llist_head entry;
@@ -120,18 +132,45 @@ struct gsm_subscriber_connection {
/* Are we part of a special "silent" call */
int silent_call;
/* bsc structures */
struct osmo_bsc_sccp_con *sccp_con;
/* MNCC rtp bridge markers */
int mncc_rtp_bridge;
int mncc_rtp_create_pending;
int mncc_rtp_connect_pending;
/* back pointers */
struct gsm_network *network;
/* The BSC used to be an integral part of OsmoNITB. In OsmoCSCN, the
* BSC and/or RNC is a separate entity, and no back pointers to the bts
* and lchan structures are available. To facilitate separation of the
* code paths, I'm explicitly excluding the unavailable structures from
* the build. Once separated, this split may become unnecessary. */
#if COMPILING_LIBMSC
int in_release;
uint16_t lac;
struct gsm_encr encr;
/* 2G or 3G? See enum interface_type */
int via_iface;
/* which Iu-CS connection, if any. */
struct {
struct ue_conn_ctx *ue_ctx;
int integrity_protection;
} iu;
#else
struct gsm_bts *bts;
struct gsm_lchan *lchan;
struct gsm_lchan *ho_lchan;
struct gsm_bts *bts;
/* bsc structures */
struct osmo_bsc_sccp_con *sccp_con;
/* for assignment handling */
struct osmo_timer_list T10;
struct gsm_lchan *secondary_lchan;
#endif
};
@@ -203,7 +242,20 @@ enum gsm_auth_policy {
#define GSM_T3113_DEFAULT 60
#define GSM_T3122_DEFAULT 10
struct gsm_tz {
int override; /* if 0, use system's time zone instead. */
int hr; /* hour */
int mn; /* minute */
int dst; /* daylight savings */
};
struct gsm_network {
/* TODO MSCSPLIT the gsm_network struct is basically a kitchen sink for
* global settings and variables, "madly" mixing BSC and MSC stuff. Split
* this in e.g. struct osmo_bsc and struct osmo_msc, with the things
* these have in common, like country and network code, put in yet
* separate structs and placed as members in osmo_bsc and osmo_msc. */
/* global parameters */
uint16_t country_code;
uint16_t network_code;
@@ -281,8 +333,24 @@ struct gsm_network {
struct gsm_subscriber_group *subscr_group;
struct gsm_sms_queue *sms_queue;
/* nitb related control */
int avoid_tmsi;
/* control interface */
struct ctrl_handle *ctrl;
/* all active subscriber connections. */
struct llist_head subscr_conns;
/* if override is nonzero, this timezone data is used for all MM
* contexts. */
/* TODO: in OsmoNITB, tz-override used to be BTS-specific. To enable
* BTS|RNC specific timezone overrides for multi-tz networks in
* OsmoCSCN, this should be tied to the location area code (LAC). */
struct gsm_tz tz;
/* Periodic location update default value */
uint8_t t3212;
};
struct osmo_esme;
@@ -329,13 +397,12 @@ struct gsm_sms {
char text[SMS_TEXT_SIZE];
};
struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code,
int (*mncc_recv)(struct gsm_network *, struct msgb *));
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
struct gsm_network *gsm_network_init(void *ctx,
uint16_t country_code,
uint16_t network_code,
mncc_recv_cb_t mncc_recv);
/* Get reference to a neighbor cell on a given BCCH ARFCN */
struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
uint16_t arfcn, uint8_t bsic);
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
enum gsm_bts_type parse_btstype(const char *arg);
const char *btstype2str(enum gsm_bts_type type);
@@ -419,17 +486,19 @@ int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);
int gsm48_ra_id_by_bts(uint8_t *buf, struct gsm_bts *bts);
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat);
int gsm_bts_model_register(struct gsm_bts_model *model);
struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan);
void subscr_con_free(struct gsm_subscriber_connection *conn);
struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lchan);
void bsc_subscr_con_free(struct gsm_subscriber_connection *conn);
struct gsm_subscriber_connection *msc_subscr_con_allocate(struct gsm_network *network);
void msc_subscr_con_free(struct gsm_subscriber_connection *conn);
struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net,
enum gsm_bts_type type,
uint8_t tsc, uint8_t bsic);
uint8_t bsic);
void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
uint8_t e1_ts, uint8_t e1_ts_ss);
@@ -438,6 +507,7 @@ void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
int gsm_bts_has_feature(struct gsm_bts *bts, enum gsm_bts_features feat);
struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx);
int gsm_bts_set_system_infos(struct gsm_bts *bts);
/* generic E1 line operations for all ISDN-based BTS. */
extern struct e1inp_line_ops bts_isdn_e1inp_line_ops;

View File

@@ -24,6 +24,8 @@
#include <osmocom/gsm/lapdm.h>
#endif
#include <openbsc/xsc.h>
struct osmo_bsc_data;
struct osmo_bsc_sccp_con;
@@ -50,7 +52,6 @@ enum gsm_chreq_reason_t {
#define TS_MAX_LCHAN 8
#define HARDCODED_ARFCN 123
#define HARDCODED_TSC 7
#define HARDCODED_BSIC 0x3f /* NCC = 7 / BCC = 7 */
/* for multi-drop config */
@@ -101,11 +102,11 @@ struct gsm_abis_mo {
struct gsm_bts *bts;
};
#define MAX_A5_KEY_LEN (128/8)
#define A38_XOR_MIN_KEY_LEN 12
#define A38_XOR_MAX_KEY_LEN 16
#define A38_COMP128_KEY_LEN 16
#define RSL_ENC_ALG_A5(x) (x+1)
#define MAX_EARFCN_LIST 32
/* is the data link established? who established it? */
#define LCHAN_SAPI_UNUSED 0
@@ -153,9 +154,11 @@ struct amr_mode {
uint8_t threshold;
uint8_t hysteresis;
};
struct amr_multirate_conf {
uint8_t gsm48_ie[2];
struct amr_mode mode[4];
struct amr_mode ms_mode[4];
struct amr_mode bts_mode[4];
uint8_t num_modes;
};
/* /BTS ONLY */
@@ -200,14 +203,11 @@ struct gsm_lchan {
uint8_t bs_power;
uint8_t ms_power;
/* Encryption information */
struct {
uint8_t alg_id;
uint8_t key_len;
uint8_t key[MAX_A5_KEY_LEN];
} encr;
struct gsm_encr encr;
/* AMR bits */
struct gsm48_multi_rate_conf mr_conf;
uint8_t mr_ms_lv[7];
uint8_t mr_bts_lv[7];
/* Established data link layer services */
uint8_t sapis[8];
@@ -231,6 +231,8 @@ struct gsm_lchan {
uint8_t rqd_ta;
char *name;
#ifdef ROLE_BSC
struct osmo_timer_list T3101;
struct osmo_timer_list T3109;
@@ -346,7 +348,7 @@ struct gsm_bts_trx_ts {
struct gsm_lchan lchan[TS_MAX_LCHAN];
};
/* One TRX in a BTS */
/* One TRX (transceiver) in a BTS */
struct gsm_bts_trx {
/* list header in bts->trx_list */
struct llist_head list;
@@ -566,9 +568,8 @@ struct gsm_bts {
uint16_t cell_identity;
/* location area code of this BTS */
uint16_t location_area_code;
/* Training Sequence Code */
uint8_t tsc;
/* Base Station Identification Code (BSIC) */
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
* which is used as TSC for the CCCH */
uint8_t bsic;
/* type of BTS */
enum gsm_bts_type type;
@@ -605,14 +606,6 @@ struct gsm_bts {
/* buffers where we put the pre-computed SI */
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
/* TimeZone hours, mins, and bts specific */
struct {
int hr;
int mn;
int override;
int dst;
} tz;
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
union {
struct {
@@ -712,12 +705,18 @@ struct gsm_bts {
struct bitvec neigh_list;
struct bitvec cell_alloc;
struct bitvec si5_neigh_list;
struct osmo_earfcn_si2q si2quater_neigh_list;
size_t uarfcn_length; /* index for uarfcn and scramble lists */
struct {
/* bitmask large enough for all possible ARFCN's */
uint8_t neigh_list[1024/8];
uint8_t cell_alloc[1024/8];
/* If the user wants a different neighbor list in SI5 than in SI2 */
uint8_t si5_neigh_list[1024/8];
uint8_t meas_bw_list[MAX_EARFCN_LIST];
uint16_t earfcn_list[MAX_EARFCN_LIST];
uint16_t uarfcn_list[MAX_EARFCN_LIST];
uint16_t scramble_list[MAX_EARFCN_LIST];
} data;
} si_common;
@@ -732,6 +731,11 @@ struct gsm_bts {
/* BTS dependencies bit field */
uint32_t depends_on[256/(8*4)];
/* full and half rate multirate config */
struct amr_multirate_conf mr_full;
struct amr_multirate_conf mr_half;
#endif /* ROLE_BSC */
void *role;
};
@@ -753,9 +757,13 @@ const char *gsm_lchant_name(enum gsm_chan_t c);
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
char *gsm_trx_name(const struct gsm_bts_trx *trx);
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);
char *gsm_lchan_name(const struct gsm_lchan *lchan);
char *gsm_lchan_name_compute(const struct gsm_lchan *lchan);
const char *gsm_lchans_name(enum gsm_lchan_state s);
static inline char *gsm_lchan_name(const struct gsm_lchan *lchan)
{
return lchan->name;
}
void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
@@ -790,7 +798,7 @@ static inline uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)
if (ts->tsc != -1)
return ts->tsc;
else
return ts->trx->bts->tsc;
return ts->trx->bts->bsic & 7;
}

View File

@@ -1,11 +1,12 @@
#ifndef _GSM_SUBSCR_H
#define _GSM_SUBSCR_H
#include <stdbool.h>
#include "gsm_data.h"
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
#define GSM_IMEI_LENGTH 17
#define GSM_IMSI_LENGTH 17
#define GSM_NAME_LENGTH 160
#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */
@@ -32,7 +33,7 @@ struct gsm_subscriber_group {
struct gsm_equipment {
long long unsigned int id;
char imei[GSM_IMEI_LENGTH];
char imei[GSM23003_IMEISV_NUM_DIGITS+1];
char name[GSM_NAME_LENGTH];
struct gsm48_classmark1 classmark1;
@@ -45,7 +46,7 @@ struct gsm_equipment {
struct gsm_subscriber {
struct gsm_subscriber_group *group;
long long unsigned int id;
char imsi[GSM_IMSI_LENGTH];
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
uint32_t tmsi;
uint16_t lac;
char name[GSM_NAME_LENGTH];
@@ -69,6 +70,7 @@ struct gsm_subscriber {
/* pending requests */
int is_paging;
struct osmo_timer_list paging_timeout;
struct llist_head requests;
/* GPRS/SGSN related fields */
@@ -88,6 +90,20 @@ enum gsm_subscriber_update_reason {
GSM_SUBSCRIBER_UPDATE_EQUIPMENT,
};
/*
* Struct for pending channel requests. This is managed in the
* llist_head requests of each subscriber. The reference counting
* should work in such a way that a subscriber with a pending request
* remains in memory.
*/
struct subscr_request {
struct llist_head entry;
/* the callback data */
gsm_cbfn *cbfn;
void *param;
};
struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp,
@@ -102,7 +118,8 @@ struct gsm_subscriber *subscr_get_by_id(struct gsm_subscriber_group *sgrp,
unsigned long long id);
struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
const char *imsi);
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
int subscr_update(struct gsm_network *network, struct gsm_subscriber *s,
uint16_t lac, int reason);
struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
uint32_t tmsi);
struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
@@ -113,14 +130,18 @@ char *subscr_name(struct gsm_subscriber *subscr);
int subscr_purge_inactive(struct gsm_subscriber_group *sgrp);
void subscr_update_from_db(struct gsm_subscriber *subscr);
void subscr_expire(struct gsm_subscriber_group *sgrp);
int subscr_update_expire_lu(struct gsm_subscriber *subscr, struct gsm_bts *bts);
int subscr_update_expire_lu(struct gsm_network *network, struct gsm_subscriber *subscr);
bool subscr_authorized(struct gsm_subscriber *subsc);
/*
* Paging handling with authentication
*/
struct subscr_request *subscr_request_channel(struct gsm_subscriber *subscr,
int type, gsm_cbfn *cbfn, void *param);
struct subscr_request *subscr_request_conn(struct gsm_subscriber *subscr,
gsm_cbfn *cbfn, void *param);
void subscr_remove_request(struct subscr_request *req);
int subscr_rx_paging_response(struct msgb *msg,
struct gsm_subscriber_connection *conn);
/* internal */
struct gsm_subscriber *subscr_alloc(void);

View File

@@ -0,0 +1,523 @@
/* GTP Hub Implementation */
/* (C) 2015 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdint.h>
#include <sys/socket.h>
#include <osmocom/core/select.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/rate_ctr.h>
#include <openbsc/gprs_sgsn.h>
/* support */
/* TODO move to osmocom/core/socket.c ? */
#include <netdb.h> /* for IPPROTO_* etc */
struct osmo_sockaddr {
struct sockaddr_storage a;
socklen_t l;
};
/* TODO move to osmocom/core/socket.c ? */
/*! \brief Initialize a sockaddr
* \param[out] addr Valid osmo_sockaddr pointer to write result to
* \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC
* \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
* \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
* \param[in] host Remote host name or IP address in string form
* \param[in] port Remote port number in host byte order
* \returns 0 on success, otherwise an error code (from getaddrinfo()).
*
* Copy the first result from a getaddrinfo() call with the given parameters to
* *addr and *addr_len. On error, do not change *addr and return nonzero.
*/
int osmo_sockaddr_init(struct osmo_sockaddr *addr,
uint16_t family, uint16_t type, uint8_t proto,
const char *host, uint16_t port);
/* Conveniently pass AF_UNSPEC, SOCK_DGRAM and IPPROTO_UDP to
* osmo_sockaddr_init(). */
static inline int osmo_sockaddr_init_udp(struct osmo_sockaddr *addr,
const char *host, uint16_t port)
{
return osmo_sockaddr_init(addr, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,
host, port);
}
/*! \brief convert sockaddr to human readable string.
* \param[out] addr_str Valid pointer to a buffer of length addr_str_len.
* \param[in] addr_str_len Size of buffer addr_str points at.
* \param[out] port_str Valid pointer to a buffer of length port_str_len.
* \param[in] port_str_len Size of buffer port_str points at.
* \param[in] addr Binary representation as returned by osmo_sockaddr_init().
* \param[in] flags flags as passed to getnameinfo().
* \returns 0 on success, an error code on error.
*
* Return the IPv4 or IPv6 address string and the port (a.k.a. service) string
* representations of the given struct osmo_sockaddr in two caller provided
* char buffers. Flags of (NI_NUMERICHOST | NI_NUMERICSERV) return numeric
* address and port. Either one of addr_str or port_str may be NULL, in which
* case nothing is returned there.
*
* See also osmo_sockaddr_to_str() (less flexible, but much more convenient). */
int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len,
char *port_str, size_t port_str_len,
const struct osmo_sockaddr *addr,
int flags);
/*! \brief concatenate the parts returned by osmo_sockaddr_to_strs().
* \param[in] addr Binary representation as returned by osmo_sockaddr_init().
* \param[in] buf A buffer to use for string operations.
* \param[in] buf_len Length of the buffer.
* \returns Address string (in buffer).
*
* Compose a string of the numeric IP-address and port represented by *addr of
* the form "<ip-addr> port <port>". The returned string is valid until the
* next invocation of this function.
*/
const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr,
char *buf, size_t buf_len);
/*! \brief conveniently return osmo_sockaddr_to_strb() in a static buffer.
* \param[in] addr Binary representation as returned by osmo_sockaddr_init().
* \returns Address string in static buffer.
*
* See osmo_sockaddr_to_strb().
*
* Note: only one osmo_sockaddr_to_str() call will work per print/log
* statement. For two or more, use osmo_sockaddr_to_strb() with a separate
* buffer each.
*/
const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *addr);
/*! \brief compare two osmo_sockaddr.
* \param[in] a The first address to compare.
* \param[in] b The other address to compare.
* \returns 0 if equal, otherwise -1 or 1.
*/
int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,
const struct osmo_sockaddr *b);
/*! \brief Overwrite *dst with *src.
* Like memcpy(), but copy only the valid bytes. */
void osmo_sockaddr_copy(struct osmo_sockaddr *dst,
const struct osmo_sockaddr *src);
/* general */
enum gtphub_plane_idx {
GTPH_PLANE_CTRL = 0,
GTPH_PLANE_USER = 1,
GTPH_PLANE_N
};
enum gtphub_side_idx {
GTPH_SIDE_SGSN = 0,
GTPH_SIDE_GGSN = 1,
GTPH_SIDE_N
};
#define for_each_side(I) for (I = 0; I < GTPH_SIDE_N; I++)
#define for_each_plane(I) for (I = 0; I < GTPH_PLANE_N; I++)
#define for_each_side_and_plane(I,J) for_each_side(I) for_each_plane(J)
static inline int other_side_idx(int side_idx)
{
return (side_idx + 1) & 1;
}
extern const char* const gtphub_plane_idx_names[GTPH_PLANE_N];
extern const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N];
extern const char* const gtphub_side_idx_names[GTPH_SIDE_N];
/* A host address in the form that is expected in the 7.7.32 GSN Address IE.
* len is either 4 (IPv4) or 16 (IPv6), any other value is invalid. If no
* address is set, len shall be 0. */
struct gsn_addr {
uint16_t len;
uint8_t buf[16];
};
void gsn_addr_copy(struct gsn_addr *gsna, const struct gsn_addr *src);
int gsn_addr_from_str(struct gsn_addr *gsna, const char *numeric_addr_str);
/* Return gsna in numeric string form, in a static buffer. */
const char *gsn_addr_to_str(const struct gsn_addr *gsna);
/* note: strbuf_len doesn't need to be larger than INET6_ADDRSTRLEN + 1. */
const char *gsn_addr_to_strb(const struct gsn_addr *gsna,
char *strbuf, int strbuf_len);
/* Return 1 on match, zero otherwise. */
int gsn_addr_same(const struct gsn_addr *a, const struct gsn_addr *b);
/* Decode sa to gsna. Return 0 on success. If port is non-NULL, the port number
* from sa is also returned. */
int gsn_addr_from_sockaddr(struct gsn_addr *gsna, uint16_t *port,
const struct osmo_sockaddr *sa);
/* expiry */
struct expiring_item;
typedef void (*del_cb_t)(struct expiring_item *);
struct expiring_item {
struct llist_head entry;
time_t expiry;
del_cb_t del_cb;
};
struct expiry {
int expiry_in_seconds;
struct llist_head items;
};
/* Initialize an expiry queue. */
void expiry_init(struct expiry *exq, int expiry_in_seconds);
/* Add a new mapping, or restart the expiry timeout for an already listed
* mapping. */
void expiry_add(struct expiry *exq, struct expiring_item *item, time_t now);
/* Initialize to all-empty; must be called before using the item in any way. */
void expiring_item_init(struct expiring_item *item);
/* Remove the given item from its expiry queue, and call item->del_cb, if set.
* This sets item->del_cb to NULL and is harmless when run a second time on the
* same item, so the del_cb may choose to call this function, too, to allow
* deleting items from several code paths. */
void expiring_item_del(struct expiring_item *item);
/* Carry out due expiry of mappings. Must be invoked regularly.
* 'now' is the current clock count in seconds and must correspond to the clock
* count passed to nr_map_add(). A monotonous clock counter should be used. */
int expiry_tick(struct expiry *exq, time_t now);
/* Expire all items. */
void expiry_clear(struct expiry *exq);
/* number map */
/* A number map assigns a "random" mapped number to each user provided number.
* If the same number is requested multiple times, the same mapped number is
* returned.
*
* Number maps plug into possibly shared pools and expiry queues, for example:
*
* mapA -----------+-> pool1 <-+-- mapB
* {10->1, 11->5} | {1, 2, 3, ...} | {10->2, 11->3}
* | |
* | |
* /-> \-> expiry1 <-/
* | (30 seconds)
* |
* mapC -------+-----> pool2 <-+-- mapD
* {10->1, 11->3} {1, 2, 3, ...} | {10->2, 11->5}
* |
* expiry2 <-/
* (60 seconds)
*
* A map contains mappings ("10->1"). Each map needs a number pool, which can
* be shared with other maps. Each new mapping receives a number from the pool,
* which is then unavailable to any other map using the same pool.
*
* A map may point at an expiry queue, in which case all mappings added to it
* are also appended to the expiry queue (using a separate llist entry in the
* mapping). Any number of maps may submit to the same expiry queue, if they
* desire the same expiry timeout. An expiry queue stores the mappings in
* chronological order, so that expiry checking is needed only from the start
* of the queue; hence only mappings with identical expiry timeout can be added
* to the same expiry queue. Upon expiry, a mapping is dropped from the map it
* was submitted at. expiry_tick() needs to be called regularly for each expiry
* queue.
*
* A nr_mapping can be embedded in a larger struct: each mapping can have a
* distinct destructor (del_cb), and each del_cb can figure out the container
* struct's address and free that upon expiry or manual deletion. So in expiry
* queues (and even maps), mappings of different container types can be mixed.
* This can help to drastically reduce the amount of unnecessary visits during
* expiry checking, for the case that no expiry is pending. An expiry queue
* always knows which mappings to expire next, because they are right at the
* start of its list.
*
* Mapping allocation and a del_cb are provided by the caller. If del_cb is
* NULL, no deallocation will be done (allowing statically allocated entries).
*/
typedef unsigned int nr_t;
/* Generator for unused numbers. So far this counts upwards from zero, but the
* implementation may change in the future. Treat this like an opaque struct.
* If this becomes random, the tests need to be fixed. */
struct nr_pool {
nr_t last_nr;
nr_t nr_min;
nr_t nr_max;
};
struct nr_mapping {
struct llist_head entry;
struct expiring_item expiry_entry;
void *origin;
nr_t orig;
nr_t repl;
};
struct nr_map {
struct nr_pool *pool; /* multiple nr_maps can share a nr_pool. */
struct expiry *add_items_to_expiry;
struct llist_head mappings;
};
void nr_pool_init(struct nr_pool *pool, nr_t nr_min, nr_t nr_max);
/* Return the next unused number from the nr_pool. */
nr_t nr_pool_next(struct nr_pool *pool);
/* Initialize the nr_mapping to zero/empty values. */
void nr_mapping_init(struct nr_mapping *mapping);
/* Remove the given mapping from its parent map and expiry queue, and call
* mapping->del_cb, if set. */
void nr_mapping_del(struct nr_mapping *mapping);
/* Initialize an (already allocated) nr_map, and set the map's number pool.
* Multiple nr_map instances may use the same nr_pool. Set the nr_map's expiry
* queue to exq, so that all added mappings are automatically expired after the
* time configured in exq. exq may be NULL to disable automatic expiry. */
void nr_map_init(struct nr_map *map, struct nr_pool *pool,
struct expiry *exq);
/* Add a new entry to the map. mapping->orig, mapping->origin and
* mapping->del_cb must be set before calling this function. The remaining
* fields of *mapping will be overwritten. mapping->repl is set to the next
* available mapped number from map->pool. 'now' is the current clock count in
* seconds; if no map->expiry is used, just pass 0 for 'now'. */
void nr_map_add(struct nr_map *map, struct nr_mapping *mapping,
time_t now);
/* Restart the timeout for the given mapping. mapping must be a member of map.
*/
void nr_map_refresh(struct nr_map *map, struct nr_mapping *mapping,
time_t now);
/* Return a known mapping from nr_orig and the given origin. If nr_orig is
* unknown, return NULL. */
struct nr_mapping *nr_map_get(const struct nr_map *map,
void *origin, nr_t nr_orig);
/* Return a known mapping to nr_repl. If nr_repl is unknown, return NULL. */
struct nr_mapping *nr_map_get_inv(const struct nr_map *map, nr_t nr_repl);
/* Remove all mappings from map. */
void nr_map_clear(struct nr_map *map);
/* Return 1 if map has no entries, 0 otherwise. */
int nr_map_empty(const struct nr_map *map);
/* config */
static const int GTPH_EXPIRE_QUICKLY_SECS = 30; /* TODO is there a spec for this? */
static const int GTPH_EXPIRE_SLOWLY_MINUTES = 6 * 60; /* TODO is there a spec for this? */
struct gtphub_cfg_addr {
const char *addr_str;
uint16_t port;
};
struct gtphub_cfg_bind {
struct gtphub_cfg_addr bind;
};
struct gtphub_cfg {
struct gtphub_cfg_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N];
struct gtphub_cfg_addr proxy[GTPH_SIDE_N][GTPH_PLANE_N];
int sgsn_use_sender; /* Use sender, not GSN addr IE with std ports */
};
/* state */
struct gtphub_peer {
struct llist_head entry;
struct llist_head addresses; /* Alternatives, not load balancing. */
struct nr_pool seq_pool;
struct nr_map seq_map;
};
struct gtphub_peer_addr {
struct llist_head entry;
struct gtphub_peer *peer;
struct gsn_addr addr;
struct llist_head ports;
};
struct gtphub_peer_port {
struct llist_head entry;
struct gtphub_peer_addr *peer_addr;
uint16_t port;
unsigned int ref_count; /* references from other peers' seq_maps */
struct osmo_sockaddr sa; /* a "cache" for (peer_addr->addr, port) */
int last_restart_count; /* 0..255 = valid, all else means unknown */
struct rate_ctr_group *counters_io;
};
struct gtphub_tunnel_endpoint {
struct gtphub_peer_port *peer;
uint32_t tei_orig; /* from/to peer */
struct rate_ctr_group *counters_io;
};
struct gtphub_tunnel {
struct llist_head entry;
struct expiring_item expiry_entry;
uint32_t tei_repl; /* unique TEI to replace peers' TEIs */
struct gtphub_tunnel_endpoint endpoint[GTPH_SIDE_N][GTPH_PLANE_N];
};
struct gtphub_bind {
struct gsn_addr local_addr;
uint16_t local_port;
struct osmo_fd ofd;
/* list of struct gtphub_peer */
struct llist_head peers;
const char *label; /* For logging */
struct rate_ctr_group *counters_io;
};
struct gtphub_resolved_ggsn {
struct llist_head entry;
struct expiring_item expiry_entry;
/* The APN OI, the Operator Identifier, is the combined address,
* including parts of the IMSI and APN NI, and ending with ".gprs". */
char apn_oi_str[GSM_APN_LENGTH];
/* Which address and port we resolved that to. */
struct gtphub_peer_port *peer;
};
struct gtphub {
struct gtphub_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N];
/* pointers to an entry of to_gsns[s][p].peers */
struct gtphub_peer_port *proxy[GTPH_SIDE_N][GTPH_PLANE_N];
/* The TEI numbers will simply wrap and be reused, which will work out
* in practice. Problems would arise if one given peer maintained the
* same TEI for a time long enough for the TEI nr map to wrap an entire
* uint32_t; if a new TEI were mapped every second, this would take
* more than 100 years (in which a single given TEI must not time out)
* to cause a problem. */
struct nr_pool tei_pool;
struct llist_head tunnels; /* struct gtphub_tunnel */
struct llist_head pending_deletes; /* opaque (gtphub.c) */
struct llist_head ggsn_lookups; /* opaque (gtphub_ares.c) */
struct llist_head resolved_ggsns; /* struct gtphub_resolved_ggsn */
struct osmo_timer_list gc_timer;
struct expiry expire_quickly;
struct expiry expire_slowly;
uint8_t restart_counter;
int sgsn_use_sender;
};
struct gtp_packet_desc;
/* api */
int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg);
int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file);
/* Initialize and start gtphub: bind to ports, run expiry timers. */
int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg,
uint8_t restart_counter);
/* Close all sockets, expire all maps and peers and free all allocations. The
* struct is then unusable, unless gtphub_start() is run on it again. */
void gtphub_stop(struct gtphub *hub);
time_t gtphub_now(void);
/* Remove expired items, empty peers, ... */
void gtphub_gc(struct gtphub *hub, time_t now);
/* Return the string of the first address for this peer. */
const char *gtphub_peer_str(struct gtphub_peer *peer);
/* Return a human readable description of tun in a static buffer. */
const char *gtphub_tunnel_str(struct gtphub_tunnel *tun);
/* Return 1 if all of tun's endpoints are fully established, 0 otherwise. */
int gtphub_tunnel_complete(struct gtphub_tunnel *tun);
int gtphub_handle_buf(struct gtphub *hub,
unsigned int side_idx,
unsigned int port_idx,
const struct osmo_sockaddr *from_addr,
uint8_t *buf,
size_t received,
time_t now,
uint8_t **reply_buf,
struct osmo_fd **to_ofd,
struct osmo_sockaddr *to_addr);
struct gtphub_peer_port *gtphub_port_have(struct gtphub *hub,
struct gtphub_bind *bind,
const struct gsn_addr *addr,
uint16_t port);
struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind,
const struct osmo_sockaddr *addr);
void gtphub_resolved_ggsn(struct gtphub *hub, const char *apn_oi_str,
struct gsn_addr *resolved_addr,
time_t now);
const char *gtphub_port_str(struct gtphub_peer_port *port);
int gtphub_write(const struct osmo_fd *to,
const struct osmo_sockaddr *to_addr,
const uint8_t *buf, size_t buf_len);

View File

@@ -5,13 +5,14 @@
#include "gsm_subscriber.h"
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/protocol/ipaccess.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
struct ipac_msgt_sccp_state {
uint8_t src_ref[3];
uint8_t dst_ref[3];
uint8_t trans_id;
uint8_t invoke_id;
char imsi[GSM_IMSI_LENGTH];
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
uint8_t data[0];
} __attribute__((packed));

View File

@@ -0,0 +1,61 @@
#pragma once
#include <stdbool.h>
struct sgsn_pdp_ctx;
struct msgb;
struct gprs_ra_id;
struct RANAP_RAB_SetupOrModifiedItemIEs_s;
struct RANAP_GlobalRNC_ID;
struct ue_conn_ctx {
struct llist_head list;
struct osmo_sua_link *link;
uint32_t conn_id;
int integrity_active;
struct gprs_ra_id ra_id;
};
enum iu_event_type {
IU_EVENT_RAB_ASSIGN,
IU_EVENT_SECURITY_MODE_COMPLETE,
IU_EVENT_IU_RELEASE, /* An actual Iu Release message was received */
IU_EVENT_LINK_INVALIDATED, /* A SUA link was lost or closed down */
/* FIXME: maybe IU_EVENT_IU_RELEASE and IU_EVENT_LINK_INVALIDATED
* should be combined to one generic event that simply means the
* ue_conn_ctx should no longer be used, for whatever reason. */
};
extern const struct value_string iu_event_type_names[];
static inline const char *iu_event_type_str(enum iu_event_type e)
{
return get_value_string(iu_event_type_names, e);
}
/* Implementations of iu_recv_cb_t shall find the ue_conn_ctx in msg->dst. */
typedef int (* iu_recv_cb_t )(struct msgb *msg, struct gprs_ra_id *ra_id,
/* TODO "gprs_" in generic CS+PS domain ^ */
uint16_t *sai);
typedef int (* iu_event_cb_t )(struct ue_conn_ctx *ue_ctx,
enum iu_event_type type, void *data);
typedef int (* iu_rab_ass_resp_cb_t )(struct ue_conn_ctx *ue_ctx, uint8_t rab_id,
struct RANAP_RAB_SetupOrModifiedItemIEs_s *setup_ies);
int iu_init(void *ctx, const char *listen_addr, uint16_t listen_port,
iu_recv_cb_t iu_recv_cb, iu_event_cb_t iu_event_cb);
void iu_link_del(struct osmo_sua_link *link);
int iu_tx(struct msgb *msg, uint8_t sapi);
int iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac);
int iu_page_ps(const char *imsi, const uint32_t *ptmsi, uint16_t lac, uint8_t rac);
int iu_rab_act_cs(struct ue_conn_ctx *ue_ctx, uint32_t rtp_ip, uint16_t rtp_port);
int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp, bool use_x213_nsap);
int iu_rab_deact(struct ue_conn_ctx *ue_ctx, uint8_t rab_id);
int iu_tx_sec_mode_cmd(struct ue_conn_ctx *uectx, struct gsm_auth_tuple *tp,
int send_ck, int new_key);

View File

@@ -0,0 +1,7 @@
#pragma once
int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg,
uint16_t *lac);
struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network,
struct ue_conn_ctx *ue);

View File

@@ -17,13 +17,25 @@ struct meas_feed_meas {
char name[31+1];
char scenario[31+1];
struct gsm_meas_rep mr;
/* The logical channel type, enum gsm_chan_t */
uint8_t lchan_type;
/* The physical channel type, enum gsm_phys_chan_config */
uint8_t pchan_type;
/* number of ths BTS in network */
uint8_t bts_nr;
/* number of this TRX in the BTS */
uint8_t trx_nr;
/* number of this timeslot at the TRX */
uint8_t ts_nr;
/* The logical subslot number in the TS */
uint8_t ss_nr;
};
enum meas_feed_msgtype {
MEAS_FEED_MEAS = 0,
};
#define MEAS_FEED_VERSION 0
#define MEAS_FEED_VERSION 1
#endif

View File

@@ -30,6 +30,9 @@
#include "debug.h"
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define RTP_PORT_DEFAULT 4000
#define RTP_PORT_NET_DEFAULT 16000
@@ -114,6 +117,9 @@ typedef void (*mgcp_get_format)(struct mgcp_endpoint *endp,
struct mgcp_port_range {
int mode;
/* addr or NULL to fall-back to default */
char *bind_addr;
/* pre-allocated from a base? */
int base_port;
@@ -214,6 +220,8 @@ struct mgcp_config {
/* osmux translator: 0 means disabled, 1 means enabled */
int osmux;
/* addr to bind the server to */
char *osmux_addr;
/* The BSC-NAT may ask for enabling osmux on demand. This tells us if
* the osmux socket is already initialized.
*/
@@ -224,6 +232,10 @@ struct mgcp_config {
int osmux_batch_size;
/* osmux port */
uint16_t osmux_port;
/* Pad circuit with dummy messages until we see the first voice
* message.
*/
uint16_t osmux_dummy;
};
/* config management */

View File

@@ -22,6 +22,8 @@
#pragma once
#include <string.h>
#include <osmocom/core/select.h>
#define CI_UNUSED 0
@@ -190,6 +192,8 @@ struct mgcp_endpoint {
/* Osmux state: disabled, activating, active */
enum osmux_state state;
/* Allocated Osmux circuit ID for this endpoint */
int allocated_cid;
/* Used Osmux circuit ID for this endpoint */
uint8_t cid;
/* handle to batch messages */
struct osmux_in_handle *in;
@@ -203,11 +207,51 @@ struct mgcp_endpoint {
} osmux;
};
#define for_each_line(line, save) \
for (line = strline_r(NULL, &save); line;\
line = strline_r(NULL, &save))
static inline char *strline_r(char *str, char **saveptr)
{
char *result;
if (str)
*saveptr = str;
result = *saveptr;
if (*saveptr != NULL) {
*saveptr = strpbrk(*saveptr, "\r\n");
if (*saveptr != NULL) {
char *eos = *saveptr;
if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n')
(*saveptr)++;
(*saveptr)++;
if ((*saveptr)[0] == '\0')
*saveptr = NULL;
*eos = '\0';
}
}
return result;
}
#define ENDPOINT_NUMBER(endp) abs((int)(endp - endp->tcfg->endpoints))
struct mgcp_msg_ptr {
unsigned int start;
unsigned int length;
/**
* Internal structure while parsing a request
*/
struct mgcp_parse_data {
struct mgcp_config *cfg;
struct mgcp_endpoint *endp;
char *trans;
char *save;
int found;
};
int mgcp_send_dummy(struct mgcp_endpoint *endp);
@@ -260,5 +304,39 @@ enum {
MGCP_DEST_BTS,
};
#define MGCP_DUMMY_LOAD 0x23
/**
* SDP related information
*/
/* Assume audio frame length of 20ms */
#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
#define DEFAULT_RTP_AUDIO_PACKET_DURATION_MS 20
#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000
#define DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS 1
#define PTYPE_UNDEFINED (-1)
int mgcp_parse_sdp_data(struct mgcp_endpoint *endp, struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p);
int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
int payload_type, const char *audio_name);
/**
* Internal network related
*/
static inline const char *mgcp_net_src_addr(struct mgcp_endpoint *endp)
{
if (endp->cfg->net_ports.bind_addr)
return endp->cfg->net_ports.bind_addr;
return endp->cfg->source_addr;
}
static inline const char *mgcp_bts_src_addr(struct mgcp_endpoint *endp)
{
if (endp->cfg->bts_ports.bind_addr)
return endp->cfg->bts_ports.bind_addr;
return endp->cfg->source_addr;
}

View File

@@ -33,7 +33,8 @@ enum audio_format {
AF_L16,
AF_GSM,
AF_G729,
AF_PCMA
AF_PCMA,
AF_PCMU
};

View File

@@ -92,6 +92,9 @@ struct gsm_call {
#define MNCC_FRAME_RECV 0x0201
#define MNCC_FRAME_DROP 0x0202
#define MNCC_LCHAN_MODIFY 0x0203
#define MNCC_RTP_CREATE 0x0204
#define MNCC_RTP_CONNECT 0x0205
#define MNCC_RTP_FREE 0x0206
#define GSM_TCHF_FRAME 0x0300
#define GSM_TCHF_FRAME_EFR 0x0301
@@ -163,7 +166,7 @@ struct gsm_data_frame {
unsigned char data[0];
};
#define MNCC_SOCK_VERSION 4
#define MNCC_SOCK_VERSION 5
struct gsm_mncc_hello {
uint32_t msg_type;
uint32_t version;
@@ -179,7 +182,21 @@ struct gsm_mncc_hello {
uint32_t lchan_type_offset;
};
char *get_mncc_name(int value);
struct gsm_mncc_rtp {
uint32_t msg_type;
uint32_t callref;
uint32_t ip;
uint16_t port;
uint32_t payload_type;
uint32_t payload_msg_type;
};
struct gsm_mncc_bridge {
uint32_t msg_type;
uint32_t callref[2];
};
const char *get_mncc_name(int value);
void mncc_set_cause(struct gsm_mncc *data, int loc, int val);
void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg);
@@ -189,7 +206,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg);
/* input from CC code into mncc_sock */
int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg);
int mncc_sock_init(struct gsm_network *gsmnet);
int mncc_sock_init(struct gsm_network *net, const char *sock_path);
#define mncc_is_data_frame(msg_type) \
(msg_type == GSM_TCHF_FRAME \

View File

@@ -9,4 +9,6 @@ struct mncc_int {
extern struct mncc_int mncc_int;
uint8_t mncc_codec_for_mode(int lchan_type);
#endif

View File

@@ -0,0 +1,29 @@
#pragma once
/* These functions receive or send MM|CC|... messages from/to the BSC|RNC
* direction, while they are not concerned with which particular external
* interface is actually involved (A or IuCS).
*
* For the interface specific decisions see msc_iface.[hc]
*/
/* MSCSPLIT WIP: this will gradually replace the role that the bsc_api.h had in
* OsmoNITB. Actually, osmo_msc.[hc] has the same role as this file, but having
* separate files helps me to keep track of how far I've gotten yet. */
#include <stdint.h>
struct gsm_subscriber_connection;
struct msgb;
enum {
MSC_CONN_ACCEPT = 0,
MSC_CONN_REJECT = 1,
};
/* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or
* MSC_CONN_REJECT */
int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
uint16_t chosen_channel);
/* TODO: is chosen_channel BSC land == NITB legacy? */

View File

@@ -0,0 +1,40 @@
#pragma once
#include <osmocom/core/msgb.h>
#include <openbsc/gsm_data.h>
/* These are the interfaces of the MSC layer towards (from?) the BSC and RNC,
* i.e. in the direction towards the mobile device (MS aka UE).
*
* 2G will use the A-interface,
* 3G aka UMTS will use the Iu-interface (for the MSC, it's IuCS).
*
* To allow linking parts of the MSC code without having to include entire
* infrastructures of external libraries, the core transmitting and receiving
* functions are left unimplemented. For example, a unit test does not need to
* link against external ASN1 libraries if it is never going to encode actual
* outgoing messages. It is up to each building scope to implement real world
* functions or to plug mere dummy implementations.
*
* For example, msc_tx_dtap(conn, msg), depending on conn->via_iface, will call
* either iu_tx() or a_tx() [note: at time of writing, the A-interface is not
* yet implemented]. When you try to link against libmsc, you will find that
* the compiler complains about an undefined reference to iu_tx(). If you,
* however, link against libiu as well as the osmo-iuh libs (etc.), iu_tx() is
* available. A unit test may instead simply implement a dummy iu_tx() function
* and not link against osmo-iuh.
*/
/* Each main linkage must implement this function (see comment above). */
extern int iu_tx(struct msgb *msg, uint8_t sapi);
/* So far this is a dummy implemented in libmsc/a_iface.c. When A-interface
* gets implemented, it should be in a separate lib (like libiu), this function
* should move there, and the following comment should remain here: "
* Each main linkage must implement this function (see comment above).
* " */
extern int a_tx(struct msgb *msg);
int msc_tx_dtap(struct gsm_subscriber_connection *conn,
struct msgb *msg);

View File

@@ -0,0 +1,78 @@
/* Osmocom Authentication Protocol API */
/* (C) 2015 by Sysmocom s.f.m.c. GmbH
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
struct msgb;
struct osmo_oap_message;
/* This is the config part for vty. It is essentially copied in oap_state,
* where values are copied over once the config is considered valid. */
struct oap_config {
uint16_t client_id;
int secret_k_present;
uint8_t secret_k[16];
int secret_opc_present;
uint8_t secret_opc[16];
};
/* The runtime state of the OAP client. client_id and the secrets are in fact
* duplicated from oap_config, so that a separate validation of the config data
* is possible, and so that only a struct oap_state* is passed around. */
struct oap_state {
enum {
OAP_UNINITIALIZED = 0, /* just allocated. */
OAP_DISABLED, /* disabled by config. */
OAP_INITIALIZED, /* enabled, config is valid. */
OAP_REQUESTED_CHALLENGE,
OAP_SENT_CHALLENGE_RESULT,
OAP_REGISTERED
} state;
uint16_t client_id;
uint8_t secret_k[16];
uint8_t secret_opc[16];
int registration_failures;
};
/* From config, initialize state. Return 0 on success. */
int oap_init(struct oap_config *config, struct oap_state *state);
/* Construct an OAP registration message and return in *msg_tx. Use
* state->client_id and update state->state.
* Return 0 on success, or a negative value on error.
* If an error is returned, *msg_tx is guaranteed to be NULL. */
int oap_register(struct oap_state *state, struct msgb **msg_tx);
/* Decode and act on a received OAP message msg_rx. Update state->state. If a
* non-NULL pointer is returned in *msg_tx, that msgb should be sent to the OAP
* server (and freed) by the caller. The received msg_rx is not freed.
* Return 0 on success, or a negative value on error.
* If an error is returned, *msg_tx is guaranteed to be NULL. */
int oap_handle(struct oap_state *state, const struct msgb *msg_rx, struct msgb **msg_tx);
/* Allocate a msgb and in it, return the encoded oap_msg. Return NULL on
* error. (Like oap_encode(), but also allocates a msgb.)
* About the name: the idea is do_something(oap_encoded(my_struct)) */
struct msgb *oap_encoded(const struct osmo_oap_message *oap_msg);

View File

@@ -0,0 +1,70 @@
/* Osmocom Authentication Protocol message encoder/decoder */
/* (C) 2015 by Sysmocom s.f.m.c. GmbH
* All Rights Reserved
*
* Author: Neels Hofmeyr
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
/* Some numbers are out of sequence because (so far) they match gprs_gsup_iei.
*/
enum oap_iei {
OAP_CAUSE_IE = 0x02,
OAP_RAND_IE = 0x20,
OAP_AUTN_IE = 0x23,
OAP_XRES_IE = 0x24,
OAP_AUTS_IE = 0x25,
OAP_CLIENT_ID_IE = 0x30,
};
enum osmo_oap_message_type {
OAP_MSGT_REGISTER_REQUEST = 0b00000100,
OAP_MSGT_REGISTER_ERROR = 0b00000101,
OAP_MSGT_REGISTER_RESULT = 0b00000110,
OAP_MSGT_CHALLENGE_REQUEST = 0b00001000,
OAP_MSGT_CHALLENGE_ERROR = 0b00001001,
OAP_MSGT_CHALLENGE_RESULT = 0b00001010,
OAP_MSGT_SYNC_REQUEST = 0b00001100,
OAP_MSGT_SYNC_ERROR = 0b00001101,
OAP_MSGT_SYNC_RESULT = 0b00001110,
};
struct osmo_oap_message {
enum osmo_oap_message_type message_type;
enum gsm48_gmm_cause cause;
uint16_t client_id;
int rand_present;
uint8_t rand[16];
int autn_present;
uint8_t autn[16];
int xres_present;
uint8_t xres[8];
int auts_present;
uint8_t auts[16];
};
int osmo_oap_decode(struct osmo_oap_message *oap_msg,
const uint8_t *data, size_t data_len);
void osmo_oap_encode(struct msgb *msg, const struct osmo_oap_message *oap_msg);

View File

@@ -59,13 +59,16 @@ struct osmo_msc_data {
/* Connection data */
char *bsc_token;
uint8_t bsc_key[16];
uint8_t bsc_key_present;
int ping_timeout;
int pong_timeout;
struct osmo_timer_list ping_timer;
struct osmo_timer_list pong_timer;
int advanced_ping;
struct bsc_msc_connection *msc_con;
int core_ncc;
int core_mnc;
int core_mcc;
int core_lac;
int core_ci;

View File

@@ -14,6 +14,8 @@ int osmux_init(int role, struct mgcp_config *cfg);
int osmux_enable_endpoint(struct mgcp_endpoint *endp, int role,
struct in_addr *addr, uint16_t port);
void osmux_disable_endpoint(struct mgcp_endpoint *endp);
void osmux_allocate_cid(struct mgcp_endpoint *endp);
void osmux_release_cid(struct mgcp_endpoint *endp);
int osmux_xfrm_to_rtp(struct mgcp_endpoint *endp, int type, char *buf, int rc);
int osmux_xfrm_to_osmux(int type, char *buf, int rc, struct mgcp_endpoint *endp);
@@ -22,6 +24,7 @@ int osmux_send_dummy(struct mgcp_endpoint *endp);
int osmux_get_cid(void);
void osmux_put_cid(uint8_t osmux_cid);
int osmux_used_cid(void);
enum osmux_state {
OSMUX_STATE_DISABLED = 0,
@@ -29,4 +32,10 @@ enum osmux_state {
OSMUX_STATE_ENABLED,
};
enum osmux_usage {
OSMUX_USAGE_OFF = 0,
OSMUX_USAGE_ON = 1,
OSMUX_USAGE_ONLY = 2,
};
#endif

View File

@@ -1,10 +1,17 @@
#ifndef _REST_OCTETS_H
#define _REST_OCTETS_H
#include <stdbool.h>
#include <openbsc/gsm_04_08.h>
#include <osmocom/gsm/sysinfo.h>
#define SI2Q_MAX_LEN 160
#define SI2Q_MIN_LEN 18
/* generate SI1 rest octets */
int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net);
int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e,
const uint16_t *u, const uint16_t *sc, size_t u_len);
struct gsm48_si_selection_params {
uint16_t penalty_time:5,
@@ -43,7 +50,8 @@ struct gsm48_si_ro_info {
present:1;
} scheduling;
struct gsm48_si3_gprs_ind gprs_ind;
/* SI 3 specific */
uint8_t si2quater_indicator;
/* SI 4 specific */
struct gsm48_lsa_params lsa_params;
uint16_t cell_id;

View File

@@ -6,8 +6,12 @@
#include <osmocom/gprs/gprs_ns.h>
#include <openbsc/gprs_sgsn.h>
#include <openbsc/oap.h>
#include <ares.h>
struct gprs_gsup_client;
struct hostent;
enum sgsn_auth_policy {
SGSN_AUTH_POLICY_OPEN,
@@ -16,6 +20,11 @@ enum sgsn_auth_policy {
SGSN_AUTH_POLICY_REMOTE
};
struct sgsn_cdr {
char *filename;
int interval;
};
struct sgsn_config {
/* parsed from config file */
@@ -33,6 +42,28 @@ struct sgsn_config {
int require_authentication;
int require_update_location;
/* CDR configuration */
struct sgsn_cdr cdr;
struct {
int T3312;
int T3322;
int T3350;
int T3360;
int T3370;
int T3313;
int T3314;
int T3316;
int T3385;
int T3386;
int T3395;
int T3397;
} timers;
int dynamic_lookup;
struct oap_config oap;
};
struct sgsn_instance {
@@ -50,6 +81,12 @@ struct sgsn_instance {
struct gprs_gsup_client *gsup_client;
/* LLME inactivity timer */
struct osmo_timer_list llme_timer;
/* c-ares event loop integration */
struct osmo_timer_list ares_timer;
struct llist_head ares_fds;
ares_channel ares_channel;
struct ares_addr_node *ares_servers;
};
extern struct sgsn_instance *sgsn;
@@ -85,4 +122,17 @@ int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi
int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle,
uint8_t *hdr, uint16_t len);
/*
* CDR related functionality
*/
int sgsn_cdr_init(struct sgsn_instance *sgsn);
/*
* C-ARES related functionality
*/
int sgsn_ares_init(struct sgsn_instance *sgsn);
int sgsn_ares_query(struct sgsn_instance *sgsm, const char *name, ares_host_callback cb, void *data);
#endif

View File

@@ -1,5 +1,5 @@
/* Generic signalling/notification infrastructure */
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
/* (C) 2009-2010, 2015 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
* (C) 2010 by On-Waves
* All Rights Reserved
@@ -46,6 +46,7 @@ enum signal_subsystems {
SS_MSC,
SS_HO,
SS_CCCH,
SS_SGSN,
};
/* SS_PAGING signals */
@@ -141,7 +142,6 @@ struct gsm_subscriber;
struct paging_signal_data {
struct gsm_subscriber *subscr;
struct gsm_bts *bts;
int paging_result;
@@ -241,4 +241,22 @@ struct ccch_signal_data {
uint16_t rach_access_count;
};
/* GPRS SGSN signals SS_SGSN */
enum signal_sgsn {
S_SGSN_ATTACH,
S_SGSN_DETACH,
S_SGSN_UPDATE,
S_SGSN_PDP_ACT,
S_SGSN_PDP_DEACT,
S_SGSN_PDP_TERMINATE,
S_SGSN_PDP_FREE,
S_SGSN_MM_FREE,
};
struct sgsn_mm_ctx;
struct sgsn_signal_data {
struct sgsn_mm_ctx *mm;
struct sgsn_pdp_ctx *pdp; /* non-NULL for PDP_ACT, PDP_DEACT, PDP_FREE */
};
#endif

View File

@@ -1,4 +1,4 @@
#pragma once
int smpp_openbsc_init(void *ctx, uint16_t port);
void smpp_openbsc_set_net(struct gsm_network *net);
int smpp_openbsc_alloc_init(void *ctx);
int smpp_openbsc_start(struct gsm_network *net);

View File

@@ -6,5 +6,13 @@
struct gsm_bts;
int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type);
uint16_t encode_fdd(uint16_t scramble, bool diversity);
unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len);
unsigned earfcn_size(const struct osmo_earfcn_si2q *e);
unsigned range1024_p(unsigned n);
unsigned range512_q(unsigned m);
bool si2q_size_check(const struct gsm_bts *bts);
int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble);
int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble,
bool diversity);
#endif

View File

@@ -32,17 +32,22 @@ enum bsc_vty_node {
TRUNK_NODE,
PGROUP_NODE,
MNCC_INT_NODE,
NITB_NODE,
BSC_NODE,
SMPP_NODE,
SMPP_ESME_NODE,
GTPHUB_NODE,
CSCN_NODE,
};
extern int bsc_vty_is_config_node(struct vty *vty, int node);
extern void bsc_replace_string(void *ctx, char **dst, const char *newstr);
struct log_info;
int bsc_vty_init(const struct log_info *cat);
int bsc_vty_init(const struct log_info *cat, struct gsm_network *network);
int bsc_vty_init_extra(void);
void cscn_vty_init(void);
struct gsm_network *gsmnet_from_vty(struct vty *vty);
#endif

View File

@@ -0,0 +1,23 @@
#pragma once
#include <stdint.h>
struct msgb;
struct gsm_network;
struct log_info;
struct ctrl_handle;
typedef int (*mncc_recv_cb_t)(struct gsm_network *, struct msgb *);
#define MAX_A5_KEY_LEN (128/8)
struct gsm_encr {
uint8_t alg_id;
uint8_t key_len;
uint8_t key[MAX_A5_KEY_LEN];
};
extern struct gsm_network *vty_global_gsm_network;
int xsc_vty_init(struct gsm_network *network);

View File

@@ -31,10 +31,12 @@ app_configs = {
"osmo-bsc": ["doc/examples/osmo-bsc/osmo-bsc.cfg"],
"nat": ["doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg"],
"mgcp": ["doc/examples/osmo-bsc_mgcp/mgcp.cfg"],
"gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg"],
"gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg",
"doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg"],
"sgsn": ["doc/examples/osmo-sgsn/osmo-sgsn.cfg"],
"nitb": ["doc/examples/osmo-nitb/nanobts/openbsc-multitrx.cfg",
"doc/examples/osmo-nitb/nanobts/openbsc.cfg"]
"doc/examples/osmo-nitb/nanobts/openbsc.cfg"],
"gtphub": ["doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg"]
}
@@ -43,10 +45,11 @@ apps = [(4242, "src/osmo-bsc/osmo-bsc", "OsmoBSC", "osmo-bsc"),
(4243, "src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "mgcp"),
(4246, "src/gprs/osmo-gbproxy", "OsmoGbProxy", "gbproxy"),
(4245, "src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn"),
(4242, "src/osmo-nitb/osmo-nitb", "OpenBSC", "nitb")
(4242, "src/osmo-nitb/osmo-nitb", "OpenBSC", "nitb"),
(4253, "src/gprs/osmo-gtphub", "OsmoGTPhub", "gtphub")
]
vty_command = ["./src/osmo-nitb/osmo-nitb", "-c",
"doc/examples/osmo-nitb/nanobts/openbsc.cfg"]
vty_app = apps[-1]
vty_app = apps[5] # reference apps[] entry for osmo-nitb

View File

@@ -2,7 +2,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS)
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(COVERAGE_LDFLAGS)
SUBDIRS = libcommon libmgcp libbsc libmsc libtrau libfilter osmo-nitb osmo-bsc_mgcp utils ipaccess gprs
SUBDIRS = libcommon libmgcp libbsc libiu libmsc libtrau libfilter libxsc osmo-cscn osmo-bsc_mgcp utils ipaccess gprs
# Conditional modules
if BUILD_NAT

View File

@@ -1,30 +1,49 @@
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
AM_CFLAGS=-Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS)
$(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \
$(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) \
$(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS)
OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
$(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS)
$(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) -ltalloc -lm
noinst_HEADERS = gprs_sndcp.h
if HAVE_LIBGTP
bin_PROGRAMS = osmo-gbproxy osmo-sgsn
else
bin_PROGRAMS = osmo-gbproxy
if HAVE_LIBGTP
if HAVE_LIBCARES
bin_PROGRAMS += osmo-sgsn osmo-gtphub
endif
endif
IUHDIR = $(top_srcdir)/../../osmo-iuh
osmo_gbproxy_SOURCES = gb_proxy.c gb_proxy_main.c gb_proxy_vty.c \
gb_proxy_patch.c gb_proxy_tlli.c gb_proxy_peer.c \
gprs_gb_parse.c gprs_llc_parse.c crc24.c gprs_utils.c
osmo_gbproxy_LDADD = $(top_builddir)/src/libcommon/libcommon.a \
$(OSMO_LIBS) -lrt
$(OSMO_LIBS) $(LIBCRYPTO_LIBS) -lrt
osmo_sgsn_SOURCES = gprs_gmm.c gprs_sgsn.c gprs_sndcp.c gprs_sndcp_vty.c \
sgsn_main.c sgsn_vty.c sgsn_libgtp.c \
gprs_llc.c gprs_llc_parse.c gprs_llc_vty.c crc24.c \
sgsn_ctrl.c sgsn_auth.c gprs_subscriber.c \
gprs_gsup_messages.c gprs_utils.c gprs_gsup_client.c \
gsm_04_08_gprs.c
gprs_utils.c gprs_gsup_client.c \
gsm_04_08_gprs.c sgsn_cdr.c sgsn_ares.c \
oap.c oap_messages.c
osmo_sgsn_LDADD = \
$(top_builddir)/src/libcommon/libcommon.a \
-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) -lrt
$(top_builddir)/src/libiu/libiu.a \
-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \
$(LIBCRYPTO_LIBS) -lrt \
$(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS)
osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \
gtphub_vty.c sgsn_ares.c gprs_utils.c
osmo_gtphub_LDADD = \
$(top_builddir)/src/libcommon/libcommon.a \
-lgtp $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
$(LIBCARES_LIBS) -lrt

View File

@@ -34,6 +34,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
@@ -47,9 +48,11 @@
#include <openbsc/gprs_llc.h>
#include <openbsc/gsm_04_08.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <openbsc/gprs_utils.h>
#include <openssl/rand.h>
static const struct rate_ctr_desc global_ctr_description[] = {
{ "inv-bvci", "Invalid BVC Identifier " },
{ "inv-lai", "Invalid Location Area Identifier" },
@@ -70,6 +73,7 @@ static const struct rate_ctr_group_desc global_ctrg_desc = {
.group_description = "GBProxy Global Statistics",
.num_ctr = ARRAY_SIZE(global_ctr_description),
.ctr_desc = global_ctr_description,
.class_id = OSMO_STATS_CLASS_GLOBAL,
};
static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer,
@@ -232,7 +236,11 @@ uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer,
bss_ptmsi = sgsn_ptmsi;
} else {
do {
bss_ptmsi = rand_r(&peer->cfg->bss_ptmsi_state);
if (RAND_bytes((uint8_t *) &bss_ptmsi, sizeof(bss_ptmsi)) != 1) {
bss_ptmsi = GSM_RESERVED_TMSI;
break;
}
bss_ptmsi = bss_ptmsi | 0xC0000000;
if (gbproxy_link_info_by_ptmsi(peer, bss_ptmsi))
@@ -265,7 +273,11 @@ uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer,
} else {
do {
/* create random TLLI, 0b01111xxx... */
sgsn_tlli = rand_r(&peer->cfg->sgsn_tlli_state);
if (RAND_bytes((uint8_t *) &sgsn_tlli, sizeof(sgsn_tlli)) != 1) {
sgsn_tlli = 0;
break;
}
sgsn_tlli = (sgsn_tlli & 0x7fffffff) | 0x78000000;
if (gbproxy_link_info_by_any_sgsn_tlli(peer, sgsn_tlli))
@@ -381,7 +393,7 @@ static void gbproxy_acquire_imsi(struct gbproxy_peer *peer,
struct msgb *idreq_msg;
/* Send IDENT REQ */
idreq_msg = gsm48_msgb_alloc();
idreq_msg = gsm48_msgb_alloc_name("GSM 04.08 ACQ IMSI");
gprs_put_identity_req(idreq_msg, GSM_MI_TYPE_IMSI);
gbproxy_gsm48_to_peer(peer, link_info, bvci, idreq_msg);
}
@@ -393,7 +405,7 @@ static void gbproxy_tx_detach_acc(struct gbproxy_peer *peer,
struct msgb *detacc_msg;
/* Send DETACH ACC */
detacc_msg = gsm48_msgb_alloc();
detacc_msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACC");
gprs_put_mo_detach_acc(detacc_msg);
gbproxy_gsm48_to_peer(peer, link_info, bvci, detacc_msg);
}
@@ -450,8 +462,8 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer,
if (link_info->imsi_acq_pending && link_info->imsi_len > 0) {
int is_ident_resp =
parse_ctx->g48_hdr &&
parse_ctx->g48_hdr->proto_discr == GSM48_PDISC_MM_GPRS &&
parse_ctx->g48_hdr->msg_type == GSM48_MT_GMM_ID_RESP;
gsm48_hdr_pdisc(parse_ctx->g48_hdr) == GSM48_PDISC_MM_GPRS &&
gsm48_hdr_msg_type(parse_ctx->g48_hdr) == GSM48_MT_GMM_ID_RESP;
/* The IMSI is now available */
gbproxy_flush_stored_messages(peer, msg, now, link_info,
@@ -581,6 +593,27 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
case GSM48_MT_GMM_ATTACH_REQ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REQS]);
break;
case GSM48_MT_GMM_DETACH_REQ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DETACH_REQS]);
break;
case GSM48_MT_GMM_ATTACH_COMPL:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_COMPLS]);
break;
case GSM48_MT_GMM_RA_UPD_REQ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REQS]);
break;
case GSM48_MT_GMM_RA_UPD_COMPL:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_COMPLS]);
break;
case GSM48_MT_GMM_STATUS:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_BSS]);
break;
case GSM48_MT_GSM_ACT_PDP_REQ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REQS]);
break;
case GSM48_MT_GSM_DEACT_PDP_REQ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_REQS]);
break;
default:
break;
@@ -666,9 +699,33 @@ static void gbprox_process_bssgp_dl(struct gbproxy_config *cfg,
if (parse_ctx.g48_hdr) {
switch (parse_ctx.g48_hdr->msg_type) {
case GSM48_MT_GMM_ATTACH_ACK:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_ACKS]);
break;
case GSM48_MT_GMM_ATTACH_REJ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REJS]);
break;
case GSM48_MT_GMM_DETACH_ACK:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DETACH_ACKS]);
break;
case GSM48_MT_GMM_RA_UPD_ACK:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_ACKS]);
break;
case GSM48_MT_GMM_RA_UPD_REJ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REJS]);
break;
case GSM48_MT_GMM_STATUS:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_SGSN]);
break;
case GSM48_MT_GSM_ACT_PDP_ACK:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_ACKS]);
break;
case GSM48_MT_GSM_ACT_PDP_REJ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REJS]);
break;
case GSM48_MT_GSM_DEACT_PDP_ACK:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_ACKS]);
break;
default:
break;
@@ -1365,8 +1422,6 @@ int gbproxy_init_config(struct gbproxy_config *cfg)
INIT_LLIST_HEAD(&cfg->bts_peers);
cfg->ctrg = rate_ctr_group_alloc(tall_bsc_ctx, &global_ctrg_desc, 0);
clock_gettime(CLOCK_REALTIME, &tp);
cfg->bss_ptmsi_state = tp.tv_sec + tp.tv_nsec;
cfg->sgsn_tlli_state = tp.tv_sec - tp.tv_nsec;
return 0;
}

View File

@@ -36,6 +36,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
@@ -48,6 +49,7 @@
#include <osmocom/vty/command.h>
#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/logging.h>
#include <osmocom/vty/stats.h>
#include <osmocom/vty/ports.h>
#include "../../bscconfig.h"
@@ -189,7 +191,7 @@ static void handle_options(int argc, char **argv)
extern void *tall_msgb_ctx;
extern enum node_type bsc_vty_go_parent(struct vty *vty);
extern int bsc_vty_go_parent(struct vty *vty);
static struct vty_app_info vty_info = {
.name = "OsmoGbProxy",
@@ -242,15 +244,13 @@ int main(int argc, char **argv)
vty_info.copyright = openbsc_copyright;
vty_init(&vty_info);
logging_vty_add_cmds(&gprs_log_info);
osmo_stats_vty_add_cmds(&gprs_log_info);
gbproxy_vty_init();
handle_options(argc, argv);
rate_ctr_init(tall_bsc_ctx);
rc = telnet_init(tall_bsc_ctx, &dummy_network, OSMO_VTY_PORT_GBPROXY);
if (rc < 0)
exit(1);
osmo_stats_init(tall_bsc_ctx);
bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb, tall_bsc_ctx);
if (!bssgp_nsi) {
@@ -270,6 +270,14 @@ int main(int argc, char **argv)
exit(2);
}
/* start telnet after reading config for vty_get_bind_addr() */
LOGP(DGPRS, LOGL_NOTICE, "VTY at %s %d\n",
vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY);
rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network,
vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY);
if (rc < 0)
exit(1);
if (!gprs_nsvc_by_nsei(gbcfg.nsi, gbcfg.nsip_sgsn_nsei)) {
LOGP(DGPRS, LOGL_FATAL, "You cannot proxy to NSEI %u "
"without creating that NSEI before\n",

View File

@@ -23,7 +23,6 @@
#include <openbsc/gprs_utils.h>
#include <openbsc/gprs_gb_parse.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>

View File

@@ -24,11 +24,11 @@
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_data_shared.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/debug.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/core/talloc.h>
#include <string.h>
@@ -50,15 +50,33 @@ static const struct rate_ctr_desc peer_ctr_description[] = {
{ "mod-err", "Patch error: other " },
{ "attach-reqs", "Attach Request count " },
{ "attach-rejs", "Attach Reject count " },
{ "attach-acks", "Attach Accept count " },
{ "attach-cpls", "Attach Completed count " },
{ "ra-upd-reqs", "RoutingArea Update Request count" },
{ "ra-upd-rejs", "RoutingArea Update Reject count " },
{ "ra-upd-acks", "RoutingArea Update Accept count " },
{ "ra-upd-cpls", "RoutingArea Update Compltd count" },
{ "gmm-status", "GMM Status count (BSS)" },
{ "gmm-status", "GMM Status count (SGSN)" },
{ "detach-reqs", "Detach Request count " },
{ "detach-acks", "Detach Accept count " },
{ "pdp-act-reqs", "PDP Activation Request count " },
{ "pdp-act-rejs", "PDP Activation Reject count " },
{ "pdp-act-acks", "PDP Activation Accept count " },
{ "pdp-deact-reqs","PDP Deactivation Request count " },
{ "pdp-deact-acks","PDP Deactivation Accept count " },
{ "tlli-unknown", "TLLI from SGSN unknown " },
{ "tlli-cache", "TLLI cache size " },
};
osmo_static_assert(ARRAY_SIZE(peer_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described);
static const struct rate_ctr_group_desc peer_ctrg_desc = {
.group_name_prefix = "gbproxy.peer",
.group_description = "GBProxy Peer Statistics",
.num_ctr = ARRAY_SIZE(peer_ctr_description),
.ctr_desc = peer_ctr_description,
.class_id = OSMO_STATS_CLASS_PEER,
};

View File

@@ -746,6 +746,55 @@ DEFUN(delete_gb_link, delete_gb_link_cmd,
return CMD_SUCCESS;
}
/*
* legacy commands to provide an upgrade path from "broken" releases
* or pre-releases
*/
DEFUN_DEPRECATED(cfg_gbproxy_broken_apn_match,
cfg_gbproxy_broken_apn_match_cmd,
"core-access-point-name none match-imsi .REGEXP",
GBPROXY_CORE_APN_STR GBPROXY_MATCH_IMSI_STR "Remove APN\n"
"Patch MS related information elements on match only\n"
"Route to the secondary SGSN on match only\n"
"Regular expression for the IMSI match\n")
{
const char *filter = argv[0];
const char *err_msg = NULL;
struct gbproxy_match *match;
enum gbproxy_match_id match_id = get_string_value(match_ids, "patching");
/* apply APN none */
set_core_apn(vty, "");
/* do the matching... with copy and paste */
OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING &&
match_id < GBPROX_MATCH_LAST);
match = &g_cfg->matches[match_id];
if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) {
vty_out(vty, "Match expression invalid: %s%s",
err_msg, VTY_NEWLINE);
return CMD_WARNING;
}
g_cfg->acquire_imsi = 1;
return CMD_SUCCESS;
}
#define GBPROXY_TLLI_LIST_STR "Set TLLI list parameters\n"
#define GBPROXY_MAX_LEN_STR "Limit list length\n"
DEFUN_DEPRECATED(cfg_gbproxy_depr_tlli_list_max_len,
cfg_gbproxy_depr_tlli_list_max_len_cmd,
"tlli-list max-length <1-99999>",
GBPROXY_TLLI_LIST_STR GBPROXY_MAX_LEN_STR
"Maximum number of TLLIs in the list\n")
{
g_cfg->tlli_max_len = atoi(argv[0]);
return CMD_SUCCESS;
}
int gbproxy_vty_init(void)
{
install_element_ve(&show_gbproxy_cmd);
@@ -780,6 +829,10 @@ int gbproxy_vty_init(void)
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd);
/* broken or deprecated to allow an upgrade path */
install_element(GBPROXY_NODE, &cfg_gbproxy_broken_apn_match_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_depr_tlli_list_max_len_cmd);
return 0;
}

View File

@@ -19,12 +19,12 @@
*/
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <openbsc/gprs_gb_parse.h>
#include <openbsc/gprs_utils.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/debug.h>
#include <osmocom/gprs/gprs_bssgp.h>
@@ -38,7 +38,7 @@ static int gprs_gb_parse_gmm_attach_req(uint8_t *data, size_t data_len,
parse_ctx->llc_msg_name = "ATTACH_REQ";
/* Skip MS network capability */
if (gprs_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
value_len < 1 || value_len > 8)
/* invalid */
return 0;
@@ -46,10 +46,10 @@ static int gprs_gb_parse_gmm_attach_req(uint8_t *data, size_t data_len,
/* Skip Attach type */
/* Skip Ciphering key sequence number */
/* Skip DRX parameter */
gprs_shift_v_fixed(&data, &data_len, 3, NULL);
osmo_shift_v_fixed(&data, &data_len, 3, NULL);
/* Get Mobile identity */
if (gprs_shift_lv(&data, &data_len, &value, &value_len) <= 0 ||
if (osmo_shift_lv(&data, &data_len, &value, &value_len) <= 0 ||
value_len < 5 || value_len > 8)
/* invalid */
return 0;
@@ -61,7 +61,7 @@ static int gprs_gb_parse_gmm_attach_req(uint8_t *data, size_t data_len,
parse_ctx->imsi_len = value_len;
}
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->old_raid_enc = value;
@@ -82,21 +82,21 @@ static int gprs_gb_parse_gmm_attach_ack(uint8_t *data, size_t data_len,
/* Skip Periodic RA update timer */
/* Skip Radio priority for SMS */
/* Skip Spare half octet */
gprs_shift_v_fixed(&data, &data_len, 3, NULL);
osmo_shift_v_fixed(&data, &data_len, 3, NULL);
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->raid_enc = value;
/* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */
gprs_match_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
osmo_match_shift_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
/* Skip Negotiated READY timer value (GPRS timer, opt, TV, length 2) */
gprs_match_tv_fixed(&data, &data_len, GSM48_IE_GMM_TIMER_READY, 1, NULL);
osmo_match_shift_tv_fixed(&data, &data_len, GSM48_IE_GMM_TIMER_READY, 1, NULL);
/* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */
if (gprs_match_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
if (osmo_match_shift_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
&value, &value_len) > 0 &&
gprs_is_mi_tmsi(value, value_len))
parse_ctx->new_ptmsi_enc = value + 1;
@@ -111,7 +111,7 @@ static int gprs_gb_parse_gmm_attach_rej(uint8_t *data, size_t data_len,
parse_ctx->llc_msg_name = "ATTACH_REJ";
/* GMM cause */
if (gprs_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
return 0;
parse_ctx->invalidate_tlli = 1;
@@ -132,7 +132,7 @@ static int gprs_gb_parse_gmm_detach_req(uint8_t *data, size_t data_len,
/* Skip spare half octet */
/* Get Detach type */
if (gprs_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
/* invalid */
return 0;
@@ -150,7 +150,7 @@ static int gprs_gb_parse_gmm_detach_req(uint8_t *data, size_t data_len,
parse_ctx->invalidate_tlli = 1;
/* Get P-TMSI (Mobile identity), see GSM 24.008, 9.4.5.2 */
if (gprs_match_tlv(&data, &data_len,
if (osmo_match_shift_tlv(&data, &data_len,
GSM48_IE_GMM_ALLOC_PTMSI, &value, &value_len) > 0)
{
if (gprs_is_mi_tmsi(value, value_len))
@@ -170,9 +170,9 @@ static int gprs_gb_parse_gmm_ra_upd_req(uint8_t *data, size_t data_len,
/* Skip Update type */
/* Skip GPRS ciphering key sequence number */
gprs_shift_v_fixed(&data, &data_len, 1, NULL);
osmo_shift_v_fixed(&data, &data_len, 1, NULL);
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->old_raid_enc = value;
@@ -190,14 +190,14 @@ static int gprs_gb_parse_gmm_ra_upd_rej(uint8_t *data, size_t data_len,
parse_ctx->llc_msg_name = "RA_UPD_REJ";
/* GMM cause */
if (gprs_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
return 0;
cause = value[0];
/* Force to standby, 1/2 */
/* spare bits, 1/2 */
if (gprs_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
return 0;
force_standby = (value[0] & 0x07) == 0x01;
@@ -221,18 +221,18 @@ static int gprs_gb_parse_gmm_ra_upd_ack(uint8_t *data, size_t data_len,
/* Skip Force to standby */
/* Skip Update result */
/* Skip Periodic RA update timer */
gprs_shift_v_fixed(&data, &data_len, 2, NULL);
osmo_shift_v_fixed(&data, &data_len, 2, NULL);
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->raid_enc = value;
/* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */
gprs_match_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
osmo_match_shift_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
/* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */
if (gprs_match_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
if (osmo_match_shift_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
&value, &value_len) > 0 &&
gprs_is_mi_tmsi(value, value_len))
parse_ctx->new_ptmsi_enc = value + 1;
@@ -252,11 +252,11 @@ static int gprs_gb_parse_gmm_ptmsi_reall_cmd(uint8_t *data, size_t data_len,
"Got P-TMSI Reallocation Command which is not covered by unit tests yet.\n");
/* Allocated P-TMSI */
if (gprs_shift_lv(&data, &data_len, &value, &value_len) > 0 &&
if (osmo_shift_lv(&data, &data_len, &value, &value_len) > 0 &&
gprs_is_mi_tmsi(value, value_len))
parse_ctx->new_ptmsi_enc = value + 1;
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
return 0;
parse_ctx->raid_enc = value;
@@ -273,7 +273,7 @@ static int gprs_gb_parse_gmm_id_resp(uint8_t *data, size_t data_len,
parse_ctx->llc_msg_name = "ID_RESP";
/* Mobile identity, Mobile identity 10.5.1.4, M LV 2-10 */
if (gprs_shift_lv(&data, &data_len, &value, &value_len) <= 0 ||
if (osmo_shift_lv(&data, &data_len, &value, &value_len) <= 0 ||
value_len < 1 || value_len > 9)
/* invalid */
return 0;
@@ -299,22 +299,22 @@ static int gprs_gb_parse_gsm_act_pdp_req(uint8_t *data, size_t data_len,
/* Skip Requested NSAPI */
/* Skip Requested LLC SAPI */
gprs_shift_v_fixed(&data, &data_len, 2, NULL);
osmo_shift_v_fixed(&data, &data_len, 2, NULL);
/* Skip Requested QoS (support 04.08 and 24.008) */
if (gprs_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
value_len < 4 || value_len > 14)
/* invalid */
return 0;
/* Skip Requested PDP address */
if (gprs_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
value_len < 2 || value_len > 18)
/* invalid */
return 0;
/* Access point name */
old_len = gprs_match_tlv(&data, &data_len,
old_len = osmo_match_shift_tlv(&data, &data_len,
GSM48_IE_GSM_APN, &value, &value_len);
if (old_len > 0 && value_len >=1 && value_len <= 100) {
@@ -329,17 +329,20 @@ int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
struct gprs_gb_parse_context *parse_ctx)
{
struct gsm48_hdr *g48h;
uint8_t pdisc;
uint8_t msg_type;
if (gprs_shift_v_fixed(&data, &data_len, sizeof(*g48h), (uint8_t **)&g48h) <= 0)
if (osmo_shift_v_fixed(&data, &data_len, sizeof(*g48h), (uint8_t **)&g48h) <= 0)
return 0;
parse_ctx->g48_hdr = g48h;
if ((g48h->proto_discr & 0x0f) != GSM48_PDISC_MM_GPRS &&
(g48h->proto_discr & 0x0f) != GSM48_PDISC_SM_GPRS)
pdisc = gsm48_hdr_pdisc(g48h);
if (pdisc != GSM48_PDISC_MM_GPRS && pdisc != GSM48_PDISC_SM_GPRS)
return 1;
switch (g48h->msg_type) {
msg_type = gsm48_hdr_msg_type(g48h);
switch (msg_type) {
case GSM48_MT_GMM_ATTACH_REQ:
return gprs_gb_parse_gmm_attach_req(data, data_len, parse_ctx);
@@ -376,6 +379,10 @@ int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
break;
default:
LOGP(DLLC, LOGL_NOTICE,
"Unknown GSM 04.08 message type 0x%02hhx for protocol"
" discriminator 0x%02hhx.\n",
msg_type, pdisc);
break;
};

File diff suppressed because it is too large Load Diff

View File

@@ -100,6 +100,28 @@ static void connect_timer_cb(void *gsupc_)
gsup_client_connect(gsupc);
}
static void gsup_client_send(struct gprs_gsup_client *gsupc, int proto_ext, struct msgb *msg_tx)
{
ipa_prepend_header_ext(msg_tx, proto_ext);
ipa_msg_push_header(msg_tx, IPAC_PROTO_OSMO);
ipa_client_conn_send(gsupc->link, msg_tx);
/* msg_tx is now queued and will be freed. */
}
static void gsup_client_oap_register(struct gprs_gsup_client *gsupc)
{
struct msgb *msg_tx;
int rc;
rc = oap_register(&gsupc->oap_state, &msg_tx);
if ((rc < 0) || (!msg_tx)) {
LOGP(DGPRS, LOGL_ERROR, "GSUP OAP set up, but cannot register.\n");
return;
}
gsup_client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
}
static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
{
struct gprs_gsup_client *gsupc = link->data;
@@ -112,6 +134,9 @@ static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
if (up) {
start_test_procedure(gsupc);
if (gsupc->oap_state.state == OAP_INITIALIZED)
gsup_client_oap_register(gsupc);
osmo_timer_del(&gsupc->connect_timer);
} else {
osmo_timer_del(&gsupc->ping_timer);
@@ -121,6 +146,22 @@ static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
}
}
static int gsup_client_oap_handle(struct gprs_gsup_client *gsupc, struct msgb *msg_rx)
{
int rc;
struct msgb *msg_tx;
rc = oap_handle(&gsupc->oap_state, msg_rx, &msg_tx);
msgb_free(msg_rx);
if (rc < 0)
return rc;
if (msg_tx)
gsup_client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
return 0;
}
static int gsup_client_read_cb(struct ipa_client_conn *link, struct msgb *msg)
{
struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
@@ -160,16 +201,21 @@ static int gsup_client_read_cb(struct ipa_client_conn *link, struct msgb *msg)
if (hh->proto != IPAC_PROTO_OSMO)
goto invalid;
if (!he || msgb_l2len(msg) < sizeof(*he) ||
he->proto != IPAC_PROTO_EXT_GSUP)
if (!he || msgb_l2len(msg) < sizeof(*he))
goto invalid;
msg->l2h = &he->data[0];
OSMO_ASSERT(gsupc->read_cb != NULL);
gsupc->read_cb(gsupc, msg);
if (he->proto == IPAC_PROTO_EXT_GSUP) {
OSMO_ASSERT(gsupc->read_cb != NULL);
gsupc->read_cb(gsupc, msg);
/* expecting read_cb() to free msg */
} else if (he->proto == IPAC_PROTO_EXT_OAP) {
return gsup_client_oap_handle(gsupc, msg);
/* gsup_client_oap_handle frees msg */
} else
goto invalid;
/* Not freeing msg here, because that must be done by the read_cb. */
return 0;
invalid:
@@ -214,7 +260,8 @@ static void start_test_procedure(struct gprs_gsup_client *gsupc)
struct gprs_gsup_client *gprs_gsup_client_create(const char *ip_addr,
unsigned int tcp_port,
gprs_gsup_read_cb_t read_cb)
gprs_gsup_read_cb_t read_cb,
struct oap_config *oap_config)
{
struct gprs_gsup_client *gsupc;
int rc;
@@ -222,6 +269,10 @@ struct gprs_gsup_client *gprs_gsup_client_create(const char *ip_addr,
gsupc = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
OSMO_ASSERT(gsupc);
rc = oap_init(oap_config, &gsupc->oap_state);
if (rc != 0)
goto failed;
gsupc->link = ipa_client_conn_create(gsupc,
/* no e1inp */ NULL,
0,
@@ -275,9 +326,7 @@ int gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
return -EAGAIN;
}
ipa_prepend_header_ext(msg, IPAC_PROTO_EXT_GSUP);
ipa_msg_push_header(msg, IPAC_PROTO_OSMO);
ipa_client_conn_send(gsupc->link, msg);
gsup_client_send(gsupc, IPAC_PROTO_EXT_GSUP, msg);
return 0;
}

View File

@@ -1,439 +0,0 @@
/* GPRS Subscriber Update Protocol message encoder/decoder */
/*
* (C) 2014 by Sysmocom s.f.m.c. GmbH
* (C) 2015 by Holger Hans Peter Freyther
* All Rights Reserved
*
* Author: Jacob Erlbeck
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <openbsc/gprs_gsup_messages.h>
#include <openbsc/debug.h>
#include <openbsc/gprs_utils.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/msgb.h>
#include <stdint.h>
static uint64_t decode_big_endian(const uint8_t *data, size_t data_len)
{
uint64_t value = 0;
while (data_len > 0) {
value = (value << 8) + *data;
data += 1;
data_len -= 1;
}
return value;
}
static uint8_t *encode_big_endian(uint64_t value, size_t data_len)
{
static uint8_t buf[sizeof(uint64_t)];
int idx;
OSMO_ASSERT(data_len <= ARRAY_SIZE(buf));
for (idx = data_len - 1; idx >= 0; idx--) {
buf[idx] = (uint8_t)value;
value = value >> 8;
}
return buf;
}
static int decode_pdp_info(uint8_t *data, size_t data_len,
struct gprs_gsup_pdp_info *pdp_info)
{
int rc;
uint8_t tag;
uint8_t *value;
size_t value_len;
/* specific parts */
while (data_len > 0) {
enum gprs_gsup_iei iei;
rc = gprs_shift_tlv(&data, &data_len, &tag, &value, &value_len);
if (rc < 0)
return -GMM_CAUSE_PROTO_ERR_UNSPEC;
iei = tag;
switch (iei) {
case GPRS_GSUP_PDP_CONTEXT_ID_IE:
pdp_info->context_id = decode_big_endian(value, value_len);
break;
case GPRS_GSUP_PDP_TYPE_IE:
pdp_info->pdp_type =
decode_big_endian(value, value_len) & 0x0fff;
break;
case GPRS_GSUP_ACCESS_POINT_NAME_IE:
pdp_info->apn_enc = value;
pdp_info->apn_enc_len = value_len;
break;
case GPRS_GSUP_PDP_QOS_IE:
pdp_info->qos_enc = value;
pdp_info->qos_enc_len = value_len;
break;
default:
LOGP(DGPRS, LOGL_ERROR,
"GSUP IE type %d not expected in PDP info\n", iei);
continue;
}
}
return 0;
}
static int decode_auth_info(uint8_t *data, size_t data_len,
struct gsm_auth_tuple *auth_tuple)
{
int rc;
uint8_t tag;
uint8_t *value;
size_t value_len;
enum gprs_gsup_iei iei;
/* specific parts */
while (data_len > 0) {
rc = gprs_shift_tlv(&data, &data_len, &tag, &value, &value_len);
if (rc < 0)
return -GMM_CAUSE_PROTO_ERR_UNSPEC;
iei = tag;
switch (iei) {
case GPRS_GSUP_RAND_IE:
if (value_len != sizeof(auth_tuple->rand))
goto parse_error;
memcpy(auth_tuple->rand, value, value_len);
break;
case GPRS_GSUP_SRES_IE:
if (value_len != sizeof(auth_tuple->sres))
goto parse_error;
memcpy(auth_tuple->sres, value, value_len);
break;
case GPRS_GSUP_KC_IE:
if (value_len != sizeof(auth_tuple->kc))
goto parse_error;
memcpy(auth_tuple->kc, value, value_len);
break;
default:
LOGP(DGPRS, LOGL_ERROR,
"GSUP IE type %d not expected in PDP info\n", iei);
continue;
}
}
return 0;
parse_error:
LOGP(DGPRS, LOGL_ERROR,
"GSUP IE type %d, length %zu invalid in PDP info\n", iei, value_len);
return -1;
}
int gprs_gsup_decode(const uint8_t *const_data, size_t data_len,
struct gprs_gsup_message *gsup_msg)
{
int rc;
uint8_t tag;
/* the shift/match functions expect non-const pointers, but we'll
* either copy the data or cast pointers back to const before returning
* them
*/
uint8_t *data = (uint8_t *)const_data;
uint8_t *value;
size_t value_len;
static const struct gprs_gsup_pdp_info empty_pdp_info = {0};
static const struct gsm_auth_tuple empty_auth_info = {0};
static const struct gprs_gsup_message empty_gsup_message = {0};
*gsup_msg = empty_gsup_message;
/* generic part */
rc = gprs_shift_v_fixed(&data, &data_len, 1, &value);
if (rc < 0)
return -GMM_CAUSE_INV_MAND_INFO;
gsup_msg->message_type = decode_big_endian(value, 1);
rc = gprs_match_tlv(&data, &data_len, GPRS_GSUP_IMSI_IE,
&value, &value_len);
if (rc <= 0)
return -GMM_CAUSE_INV_MAND_INFO;
if (value_len * 2 + 1 > sizeof(gsup_msg->imsi))
return -GMM_CAUSE_INV_MAND_INFO;
/* Note that gsm48_decode_bcd_number expects the number of encoded IMSI
* octets in the first octet. By coincidence (the TLV encoding) the byte
* before the value part already contains this length so we can use it
* here.
*/
OSMO_ASSERT(value[-1] == value_len);
gsm48_decode_bcd_number(gsup_msg->imsi, sizeof(gsup_msg->imsi),
value - 1, 0);
/* specific parts */
while (data_len > 0) {
enum gprs_gsup_iei iei;
struct gprs_gsup_pdp_info pdp_info;
struct gsm_auth_tuple auth_info;
rc = gprs_shift_tlv(&data, &data_len, &tag, &value, &value_len);
if (rc < 0)
return -GMM_CAUSE_PROTO_ERR_UNSPEC;
iei = tag;
switch (iei) {
case GPRS_GSUP_IMSI_IE:
case GPRS_GSUP_PDP_TYPE_IE:
case GPRS_GSUP_ACCESS_POINT_NAME_IE:
case GPRS_GSUP_RAND_IE:
case GPRS_GSUP_SRES_IE:
case GPRS_GSUP_KC_IE:
LOGP(DGPRS, LOGL_NOTICE,
"GSUP IE type %d not expected (ignored)\n", iei);
continue;
case GPRS_GSUP_CAUSE_IE:
gsup_msg->cause = decode_big_endian(value, value_len);
break;
case GPRS_GSUP_CANCEL_TYPE_IE:
gsup_msg->cancel_type =
decode_big_endian(value, value_len) + 1;
break;
case GPRS_GSUP_PDP_INFO_COMPL_IE:
gsup_msg->pdp_info_compl = 1;
break;
case GPRS_GSUP_FREEZE_PTMSI_IE:
gsup_msg->freeze_ptmsi = 1;
break;
case GPRS_GSUP_PDP_CONTEXT_ID_IE:
/* When these IE appear in the top-level part of the
* message, they are used by Delete Subscr Info to delete
* single entries. We don't have an extra list for
* these but use the PDP info list instead */
/* fall through */
case GPRS_GSUP_PDP_INFO_IE:
if (gsup_msg->num_pdp_infos >= GPRS_GSUP_MAX_NUM_PDP_INFO) {
LOGP(DGPRS, LOGL_ERROR,
"GSUP IE type %d (PDP_INFO) max exceeded\n",
iei);
return -GMM_CAUSE_COND_IE_ERR;
}
pdp_info = empty_pdp_info;
if (iei == GPRS_GSUP_PDP_INFO_IE) {
rc = decode_pdp_info(value, value_len, &pdp_info);
if (rc < 0)
return rc;
pdp_info.have_info = 1;
} else {
pdp_info.context_id =
decode_big_endian(value, value_len);
}
gsup_msg->pdp_infos[gsup_msg->num_pdp_infos++] =
pdp_info;
break;
case GPRS_GSUP_AUTH_TUPLE_IE:
if (gsup_msg->num_auth_tuples >= GPRS_GSUP_MAX_NUM_AUTH_INFO) {
LOGP(DGPRS, LOGL_ERROR,
"GSUP IE type %d (AUTH_INFO) max exceeded\n",
iei);
return -GMM_CAUSE_INV_MAND_INFO;
}
auth_info = empty_auth_info;
auth_info.key_seq = gsup_msg->num_auth_tuples;
rc = decode_auth_info(value, value_len, &auth_info);
if (rc < 0)
return rc;
gsup_msg->auth_tuples[gsup_msg->num_auth_tuples++] =
auth_info;
break;
case GPRS_GSUP_MSISDN_IE:
gsup_msg->msisdn_enc = value;
gsup_msg->msisdn_enc_len = value_len;
break;
default:
LOGP(DGPRS, LOGL_NOTICE,
"GSUP IE type %d unknown\n", iei);
continue;
}
}
return 0;
}
static void encode_pdp_info(struct msgb *msg, enum gprs_gsup_iei iei,
const struct gprs_gsup_pdp_info *pdp_info)
{
uint8_t *len_field;
size_t old_len;
uint8_t u8;
len_field = msgb_tlv_put(msg, iei, 0, NULL) - 1;
old_len = msgb_length(msg);
u8 = pdp_info->context_id;
msgb_tlv_put(msg, GPRS_GSUP_PDP_CONTEXT_ID_IE, sizeof(u8), &u8);
if (pdp_info->pdp_type) {
msgb_tlv_put(msg, GPRS_GSUP_PDP_TYPE_IE,
GPRS_GSUP_PDP_TYPE_SIZE,
encode_big_endian(pdp_info->pdp_type | 0xf000,
GPRS_GSUP_PDP_TYPE_SIZE));
}
if (pdp_info->apn_enc) {
msgb_tlv_put(msg, GPRS_GSUP_ACCESS_POINT_NAME_IE,
pdp_info->apn_enc_len, pdp_info->apn_enc);
}
if (pdp_info->qos_enc) {
msgb_tlv_put(msg, GPRS_GSUP_PDP_QOS_IE,
pdp_info->qos_enc_len, pdp_info->qos_enc);
}
/* Update length field */
*len_field = msgb_length(msg) - old_len;
}
static void encode_auth_info(struct msgb *msg, enum gprs_gsup_iei iei,
const struct gsm_auth_tuple *auth_tuple)
{
uint8_t *len_field;
size_t old_len;
len_field = msgb_tlv_put(msg, iei, 0, NULL) - 1;
old_len = msgb_length(msg);
msgb_tlv_put(msg, GPRS_GSUP_RAND_IE,
sizeof(auth_tuple->rand), auth_tuple->rand);
msgb_tlv_put(msg, GPRS_GSUP_SRES_IE,
sizeof(auth_tuple->sres), auth_tuple->sres);
msgb_tlv_put(msg, GPRS_GSUP_KC_IE,
sizeof(auth_tuple->kc), auth_tuple->kc);
/* Update length field */
*len_field = msgb_length(msg) - old_len;
}
void gprs_gsup_encode(struct msgb *msg, const struct gprs_gsup_message *gsup_msg)
{
uint8_t u8;
int idx;
uint8_t bcd_buf[GSM48_MI_SIZE] = {0};
size_t bcd_len;
/* generic part */
OSMO_ASSERT(gsup_msg->message_type);
msgb_v_put(msg, gsup_msg->message_type);
bcd_len = gsm48_encode_bcd_number(bcd_buf, sizeof(bcd_buf), 0,
gsup_msg->imsi);
OSMO_ASSERT(bcd_len > 1);
/* Note that gsm48_encode_bcd_number puts the length into the first
* octet. Since msgb_tlv_put will add this length byte, we'll have to
* skip it */
msgb_tlv_put(msg, GPRS_GSUP_IMSI_IE, bcd_len - 1, &bcd_buf[1]);
/* specific parts */
if (gsup_msg->msisdn_enc)
msgb_tlv_put(msg, GPRS_GSUP_MSISDN_IE,
gsup_msg->msisdn_enc_len, gsup_msg->msisdn_enc);
if ((u8 = gsup_msg->cause))
msgb_tlv_put(msg, GPRS_GSUP_CAUSE_IE, sizeof(u8), &u8);
if ((u8 = gsup_msg->cancel_type)) {
u8 -= 1;
msgb_tlv_put(msg, GPRS_GSUP_CANCEL_TYPE_IE, sizeof(u8), &u8);
}
if (gsup_msg->pdp_info_compl)
msgb_tlv_put(msg, GPRS_GSUP_PDP_INFO_COMPL_IE, 0, &u8);
if (gsup_msg->freeze_ptmsi)
msgb_tlv_put(msg, GPRS_GSUP_FREEZE_PTMSI_IE, 0, &u8);
for (idx = 0; idx < gsup_msg->num_pdp_infos; idx++) {
const struct gprs_gsup_pdp_info *pdp_info;
pdp_info = &gsup_msg->pdp_infos[idx];
if (pdp_info->context_id == 0)
continue;
if (pdp_info->have_info) {
encode_pdp_info(msg, GPRS_GSUP_PDP_INFO_IE, pdp_info);
} else {
u8 = pdp_info->context_id;
msgb_tlv_put(msg, GPRS_GSUP_PDP_CONTEXT_ID_IE,
sizeof(u8), &u8);
}
}
for (idx = 0; idx < gsup_msg->num_auth_tuples; idx++) {
const struct gsm_auth_tuple *auth_info;
auth_info = &gsup_msg->auth_tuples[idx];
if (auth_info->key_seq == GSM_KEY_SEQ_INVAL)
continue;
encode_auth_info(msg, GPRS_GSUP_AUTH_TUPLE_IE, auth_info);
}
}

View File

@@ -38,21 +38,6 @@
static struct gprs_llc_llme *llme_alloc(uint32_t tlli);
/* If the TLLI is foreign, return its local version */
static inline uint32_t tlli_foreign2local(uint32_t tlli)
{
uint32_t new_tlli;
if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
new_tlli = tlli | 0x40000000;
LOGP(DLLC, LOGL_NOTICE, "TLLI 0x%08x is foreign, converting to "
"local TLLI 0x%08x\n", tlli, new_tlli);
} else
new_tlli = tlli;
return new_tlli;
}
/* Entry function from upper level (LLC), asking us to transmit a BSSGP PDU
* to a remote MS (identified by TLLI) at a BTS identified by its BVCI and NSEI */
static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx)
@@ -71,10 +56,8 @@ static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx)
dup.ms_ra_cap.v = mmctx->ms_radio_access_capa.buf;
/* make sure we only send it to the right llme */
OSMO_ASSERT(msgb_tlli(msg) == mmctx->llme->tlli
|| msgb_tlli(msg) == mmctx->llme->old_tlli
|| tlli_foreign2local(msgb_tlli(msg)) == mmctx->llme->tlli
|| tlli_foreign2local(msgb_tlli(msg)) == mmctx->llme->old_tlli);
OSMO_ASSERT(msgb_tlli(msg) == mmctx->gb.llme->tlli
|| msgb_tlli(msg) == mmctx->gb.llme->old_tlli);
}
memcpy(&dup.qos_profile, qos_profile_default,
sizeof(qos_profile_default));
@@ -175,10 +158,6 @@ struct gprs_llc_lle *gprs_lle_get_or_create(const uint32_t tlli, uint8_t sapi)
if (lle)
return lle;
lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi);
if (lle)
return lle;
LOGP(DLLC, LOGL_NOTICE, "LLC: unknown TLLI 0x%08x, "
"creating LLME on the fly\n", tlli);
llme = llme_alloc(tlli);
@@ -204,7 +183,7 @@ static struct gprs_llc_lle *lle_for_rx_by_tlli_sapi(const uint32_t tlli,
/* Maybe it is a routing area update but we already know this sapi? */
if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi);
lle = lle_by_tlli_sapi(tlli, sapi);
if (lle) {
LOGP(DLLC, LOGL_NOTICE,
"LLC RX: Found a local entry for TLLI 0x%08x\n",
@@ -679,12 +658,12 @@ int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv)
return rc;
/* llhp.data is only set when we need to send LL_[UNIT]DATA_IND up */
if (llhp.data) {
if (llhp.cmd == GPRS_LLC_UI && llhp.data && llhp.data_len) {
msgb_gmmh(msg) = llhp.data;
switch (llhp.sapi) {
case GPRS_SAPI_GMM:
/* send LL_UNITDATA_IND to GMM */
rc = gsm0408_gprs_rcvmsg(msg, lle->llme);
rc = gsm0408_gprs_rcvmsg_gb(msg, lle->llme);
break;
case GPRS_SAPI_SNDCP3:
case GPRS_SAPI_SNDCP5:

View File

@@ -25,21 +25,28 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/core/backtrace.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <openbsc/gsm_subscriber.h>
#include <openbsc/debug.h>
#include <openbsc/gprs_sgsn.h>
#include <openbsc/sgsn.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/gprs_gmm.h>
#include <openbsc/gprs_utils.h>
#include <openbsc/signal.h>
#include "openbsc/gprs_llc.h"
#include <openbsc/iu.h>
#include <pdp.h>
#include <time.h>
#include <openssl/rand.h>
#define GPRS_LLME_CHECK_TICK 30
extern struct sgsn_instance *sgsn;
@@ -68,6 +75,7 @@ static const struct rate_ctr_group_desc mmctx_ctrg_desc = {
.group_description = "SGSN MM Context Statistics",
.num_ctr = ARRAY_SIZE(mmctx_ctr_description),
.ctr_desc = mmctx_ctr_description,
.class_id = OSMO_STATS_CLASS_SUBSCRIBER,
};
static const struct rate_ctr_desc pdpctx_ctr_description[] = {
@@ -82,19 +90,20 @@ static const struct rate_ctr_group_desc pdpctx_ctrg_desc = {
.group_description = "SGSN PDP Context Statistics",
.num_ctr = ARRAY_SIZE(pdpctx_ctr_description),
.ctr_desc = pdpctx_ctr_description,
.class_id = OSMO_STATS_CLASS_SUBSCRIBER,
};
static int ra_id_equals(const struct gprs_ra_id *id1,
const struct gprs_ra_id *id2)
/* look-up a SGSN MM context based on TLLI + RAI */
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx)
{
return (id1->mcc == id2->mcc && id1->mnc == id2->mnc &&
id1->lac == id2->lac && id1->rac == id2->rac);
}
struct sgsn_mm_ctx *ctx;
/* See 03.02 Chapter 2.6 */
static inline uint32_t tlli_foreign(uint32_t tlli)
{
return ((tlli | 0x80000000) & ~0x40000000);
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && uectx == ctx->iu.ue_ctx)
return ctx;
}
return NULL;
}
/* look-up a SGSN MM context based on TLLI + RAI */
@@ -102,34 +111,36 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
const struct gprs_ra_id *raid)
{
struct sgsn_mm_ctx *ctx;
int tlli_type;
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
if (tlli == ctx->tlli &&
ra_id_equals(raid, &ctx->ra))
if ((tlli == ctx->gb.tlli || tlli == ctx->gb.tlli_new) &&
gprs_ra_id_equals(raid, &ctx->ra))
return ctx;
}
return NULL;
}
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
const struct gprs_ra_id *raid)
{
struct sgsn_mm_ctx *ctx;
int tlli_type;
/* TODO: Also check the P_TMSI signature to be safe. That signature
* should be different (at least with a sufficiently high probability)
* after SGSN restarts and for multiple SGSN instances.
*/
tlli_type = gprs_tlli_type(tlli);
switch (tlli_type) {
case TLLI_LOCAL:
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
if ((ctx->p_tmsi | 0xC0000000) == tlli ||
(ctx->p_tmsi_old && (ctx->p_tmsi_old | 0xC0000000) == tlli)) {
ctx->tlli = tlli;
return ctx;
}
}
break;
case TLLI_FOREIGN:
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
if (tlli == tlli_foreign(ctx->tlli) &&
ra_id_equals(raid, &ctx->ra))
return ctx;
}
break;
default:
break;
if (tlli_type != TLLI_FOREIGN && tlli_type != TLLI_LOCAL)
return NULL;
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
if ((gprs_tmsi2tlli(ctx->p_tmsi, tlli_type) == tlli ||
gprs_tmsi2tlli(ctx->p_tmsi_old, tlli_type) == tlli) &&
gprs_ra_id_equals(raid, &ctx->ra))
return ctx;
}
return NULL;
@@ -170,7 +181,8 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
return NULL;
memcpy(&ctx->ra, raid, sizeof(ctx->ra));
ctx->tlli = tlli;
ctx->ran_type = MM_CTX_T_GERAN_Gb;
ctx->gb.tlli = tlli;
ctx->mm_state = GMM_DEREGISTERED;
ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, tlli);
@@ -181,9 +193,37 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
return ctx;
}
/* Allocate a new SGSN MM context */
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx)
{
struct sgsn_mm_ctx *ctx;
ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx);
if (!ctx)
return NULL;
ctx->ran_type = MM_CTX_T_UTRAN_Iu;
ctx->iu.ue_ctx = uectx;
ctx->iu.new_key = 1;
ctx->mm_state = GMM_DEREGISTERED;
ctx->pmm_state = PMM_DETACHED;
ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0);
/* Need to get RAID from IU conn */
ctx->ra = ctx->iu.ue_ctx->ra_id;
INIT_LLIST_HEAD(&ctx->pdp_list);
llist_add(&ctx->list, &sgsn_mm_ctxts);
return ctx;
}
/* this is a hard _free_ function, it doesn't clean up the PDP contexts
* in libgtp! */
void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
{
struct sgsn_pdp_ctx *pdp, *pdp2;
@@ -201,9 +241,19 @@ void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
{
struct gprs_llc_llme *llme = mm->llme;
uint32_t tlli = mm->tlli;
struct gprs_llc_llme *llme = mm->gb.llme;
uint32_t tlli = mm->gb.tlli;
struct sgsn_pdp_ctx *pdp, *pdp2;
struct sgsn_signal_data sig_data;
enum sgsn_ran_type ran_type;
/* Forget about ongoing look-ups */
if (mm->ggsn_lookup) {
LOGMMCTXP(LOGL_NOTICE, mm,
"Cleaning mmctx with on-going query.\n");
mm->ggsn_lookup->mmctx = NULL;
mm->ggsn_lookup = NULL;
}
/* delete all existing PDP contexts for this MS */
llist_for_each_entry_safe(pdp, pdp2, &mm->pdp_list, list) {
@@ -217,6 +267,11 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
osmo_timer_del(&mm->timer);
}
memset(&sig_data, 0, sizeof(sig_data));
sig_data.mm = mm;
osmo_signal_dispatch(SS_SGSN, S_SGSN_MM_FREE, &sig_data);
/* Detach from subscriber which is possibly freed then */
if (mm->subscr) {
struct gsm_subscriber *subscr = subscr_get(mm->subscr);
@@ -224,11 +279,15 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
subscr_put(subscr);
}
ran_type = mm->ran_type;
sgsn_mm_ctx_free(mm);
mm = NULL;
/* TLLI unassignment, must be called after sgsn_mm_ctx_free */
gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
if (ran_type == MM_CTX_T_GERAN_Gb) {
/* TLLI unassignment, must be called after sgsn_mm_ctx_free */
gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
}
}
@@ -281,7 +340,6 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
return pdp;
}
#include <pdp.h>
/*
* This function will not trigger any GSM DEACT PDP ACK messages, so you
* probably want to call sgsn_delete_pdp_ctx() instead if the connection
@@ -289,6 +347,8 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
*/
void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
{
struct sgsn_signal_data sig_data;
OSMO_ASSERT(pdp->mm != NULL);
/* There might still be pending callbacks in libgtp. So the parts of
@@ -296,8 +356,14 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
LOGPDPCTXP(LOGL_INFO, pdp, "Forcing release of PDP context\n");
/* Force the deactivation of the SNDCP layer */
sndcp_sm_deactivate_ind(&pdp->mm->llme->lle[pdp->sapi], pdp->nsapi);
if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
/* Force the deactivation of the SNDCP layer */
sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
}
memset(&sig_data, 0, sizeof(sig_data));
sig_data.pdp = pdp;
osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_TERMINATE, &sig_data);
/* Detach from MM context */
llist_del(&pdp->list);
@@ -313,6 +379,12 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
*/
void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
{
struct sgsn_signal_data sig_data;
memset(&sig_data, 0, sizeof(sig_data));
sig_data.pdp = pdp;
osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_FREE, &sig_data);
rate_ctr_group_free(pdp->ctrg);
if (pdp->mm)
llist_del(&pdp->list);
@@ -330,6 +402,8 @@ void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
lib->priv = NULL;
}
if (pdp->destroy_ggsn)
sgsn_ggsn_ctx_free(pdp->ggsn);
talloc_free(pdp);
}
@@ -496,7 +570,9 @@ uint32_t sgsn_alloc_ptmsi(void)
int max_retries = 100;
restart:
ptmsi = rand();
if (RAND_bytes((uint8_t *) &ptmsi, sizeof(ptmsi)) != 1)
goto failed;
/* Enforce that the 2 MSB are set without loosing the distance between
* identical values. Since rand() has no duplicate values within a
* period (because the size of the state is the same like the size of
@@ -595,7 +671,8 @@ static void insert_qos(struct tlv_parsed *tp, struct sgsn_subscriber_pdp_data *p
*/
struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
struct tlv_parsed *tp,
enum gsm48_gsm_cause *gsm_cause)
enum gsm48_gsm_cause *gsm_cause,
char *out_apn_str)
{
char req_apn_str[GSM_APN_LENGTH] = {0};
const struct apn_ctx *apn_ctx = NULL;
@@ -604,6 +681,8 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
struct sgsn_ggsn_ctx *ggsn = NULL;
int allow_any_apn = 0;
out_apn_str[0] = '\0';
if (TLVP_PRESENT(tp, GSM48_IE_GSM_APN)) {
if (TLVP_LEN(tp, GSM48_IE_GSM_APN) >= GSM_APN_LENGTH - 1) {
LOGMMCTXP(LOGL_ERROR, mmctx, "APN IE too long\n");
@@ -619,8 +698,7 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
req_apn_str[0] = 0;
}
if (mmctx->subscr == NULL ||
llist_empty(&mmctx->subscr->sgsn_data->pdp_list))
if (mmctx->subscr == NULL)
allow_any_apn = 1;
if (strlen(req_apn_str) == 0 && !allow_any_apn) {
@@ -677,6 +755,12 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
return NULL;
}
/* copy the selected apn_str */
if (selected_apn_str)
strcpy(out_apn_str, selected_apn_str);
else
out_apn_str[0] = '\0';
if (apn_ctx == NULL && selected_apn_str)
apn_ctx = sgsn_apn_ctx_match(selected_apn_str, mmctx->imsi);
@@ -698,6 +782,13 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
return NULL;
}
if (!ggsn) {
LOGMMCTXP(LOGL_NOTICE, mmctx,
"No static GGSN configured. Selected APN '%s'\n",
selected_apn_str);
return NULL;
}
LOGMMCTXP(LOGL_INFO, mmctx,
"Found GGSN %d for APN '%s' (requested '%s')\n",
ggsn->id, selected_apn_str ? selected_apn_str : "---",
@@ -711,7 +802,7 @@ static void sgsn_llme_cleanup_free(struct gprs_llc_llme *llme)
struct sgsn_mm_ctx *mmctx = NULL;
llist_for_each_entry(mmctx, &sgsn_mm_ctxts, list) {
if (llme == mmctx->llme) {
if (llme == mmctx->gb.llme) {
gsm0408_gprs_access_cancelled(mmctx, SGSN_ERROR_CAUSE_NONE);
return;
}

Some files were not shown because too many files have changed in this diff Show More