reported by _dev_zero in #osmocom
Change-Id: Ib5679ab5d06b6ef735725b4a68eeb1e9cbcc11ba
Depends-On: libosmocore I52b9f6b5f3e96d85a390ba2af21d7814df8aaeec
During the recent refactoring, some code parts has been moved out
of 'gsm_04_08.c', but the related header files were forgotten.
Change-Id: I61e728069a1e79bf72c01ef9d9fc5fb171d3892e
It is expected that establish_nc_ss_trans() returns an allocated
transaction in successful case, or NULL in case of error. The
function assumes two scenarios:
- the subscriber already has an active RAN connection,
- RAN connection needs to be established (Paging).
In the first case, a pointer to the transaction is returned as
expected, but in case of Paging, NULL has always been returned,
even if there were no errors. Let's fix this.
Change-Id: I9dcee64dd0b435ef29630c223132b81724701f93
The SM-RP-MR (Message Reference for SM Service) value in the response
(no matter result or error) shall match the value from the request.
Change-Id: Ifb6e749928548e6febfe7768aefe9a2a3ecf4de0
Found using the new TC_mt_ussd_for_unknown_subscr test case.
Change-Id: Id00a99b713a6b97c455b8e6ae49abea163e8281f
Related: (TTCN-3) Id35cd3ec15d1bab15260312d7bbb41e2d10349fe
Related: OS#2931
For SS/USSD, it's important to have both session state and ID IEs.
Found using the new TC_mt_ussd_for_unknown_subscr test case.
Change-Id: I57317a7b8036d1ffd36e2021efc146db4633da84
Related: (TTCN-3) Id35cd3ec15d1bab15260312d7bbb41e2d10349fe
Related: OS#2931
I am not a big fan of using such syntax sugar for initializing
structures, and this is one of the reasons: it's much easier
to shoot yourself in the foot.
IMSI was copied to the new GSUP message, but then overridden.
Found using the new TC_mt_ussd_for_unknown_subscr test case.
Change-Id: If81c3fa56951185339f33a523ab6364594101be1
Related: (TTCN-3) Id35cd3ec15d1bab15260312d7bbb41e2d10349fe
Related: OS#2931
The initial idea of the SMS expiry threshold was to avoid storing
SMS messages with too long validity time (e.g. 63 weeks).
Unfortunately, neither this feature was properly documented, nor
the expiry threshold is configurable. Moreover, it has been
implemented in a wrong way, so instead of deleting the oldest
expired message, it would delete the youngest one or nothing:
SELECT ... FROM SMS ORDER BY created LIMIT 1;
while it should be sorted by 'valid_until' in ascending order:
SELECT .. FROM SMS ORDER BY valid_until LIMIT 1;
Thus, if the oldest message is expired, it gets deleted. If the
oldest message is not expired yet, there is nothing to delete.
Change-Id: I0ce6b1ab50986dc69a2be4ea62b6a24c7f3f8f0a
In general, neither TP-User-Data nor decoded text should be
truncated. If the SMSC's database for some reason does contain
such weird messages, let's at least let the user know about it.
Change-Id: I75e852ebe44ba4784572cbffa029e13f0d3c430c
The following functions:
- sms_from_result(),
- sms_from_result_v3(),
- sms_from_result_v4(),
do retrieve the TP-UD, TP-UDL and text in the same way.
A consequence of such duplication is [1], which fixed potential
NULL-pointer dereference for sms_from_result(), but not for two
other functions: sms_from_result_v3() and sms_from_result_v4().
[1] I545967464c406348b8505d1729213cfb4afcd3e2
Change-Id: If67dfb9f7d2a55fa3d45dc4689a2acff9909faf6
The value of 'sms->user_data_len' is fetched from the database:
sms->user_data_len = dbi_result_get_field_length(result, "user_data");
and this is where the problem is. As per the libdbi's documentation
(see 3.5.3), dbi_result_get_field_length() returns the length in
bytes of the value stored in the specified field:
unsigned int dbi_result_get_field_length(dbi_result Result,
const char *fieldname)
so 'unsigned int' is assigned to 'uint8_t', what could lead to an
integer overflow if the value is grather than 0xff. As a result,
if the database for some reason does contain such odd TP-UD,
the truncation of 'user_data' would be done incorrectly.
Let's avoid such direct assignment, and use a separate variable.
Also, let's warn user if TP-UDL value is grether than 140, as
per 3GPP TS 03.40.
Change-Id: Ibbd588545e1a4817504c806a3d02cf59d5938ee2
Related: OS#3684
Newer versions of libdbi print to stderr unconditionally when trying to
load drivers from /usr/lib/dbd. This makes test output to change
depending on host/distro set up (installed modules).
Let's get those messages out to make it easier for people having tests
pass.
We swap stderr/stdout instead of mixing to avoud future possible race
conditions if both get content writen into them.
Change-Id: Iec78826d28435f464be22e81b3776a6ae8326d59
The libdbd-sqlite3 provides SQLite3 driver for libdbi. We use it
by default for the built-in SMS Centre. Since [1], we have unit
test coverage for the db_sms_* API, thus we need libdbd-sqlite3
to be installed at build-time.
[1] Id94ad35b6f78f839137db2e17010fbf9b40111a3
Change-Id: Ice9fb11f5b8a39abecee426d2fadcf62b7ee47c4
man memcp doesn't define exact values for returned integer, it only
specifices a meaning for the sign of it.
So it happens that different versions/implementations actually return
different values when this test is run, making it fail.
Let's simply drop that info from logs since anyways it's not useful.
Change-Id: I771fb8f4fc56f337b16561d005ff1803a386d1c6
Catched by ASan on db_sms_test unit test:
DDB NOTICE test_db_sms_get('Empty TP-UD'): osmo-msc/src/libmsc/db.c:796:2: runtime error: null pointer passed as argument 2, which is declared to never be null
That happens on empty PDU because dbi_result_get_binary returns NULL,
and sms->user_data_len is 0, so it's harmless but we can avoid calling
mempcy and make ASan happy.
Change-Id: I545967464c406348b8505d1729213cfb4afcd3e2
Thanks to db_sms_test, it was discovered that storing an SMS with
empty TP-User-Data (TP-UDL=1) causes buffer overruns in libdbi
and it's SQLite3 driver (libdbdsqlite3):
DDB NOTICE test_db_sms_store('Empty TP-UD'): ==7791== Invalid write of size 2
==7791== at 0x857DC60: dbd_quote_binary (in /usr/lib/x86_64-linux-gnu/dbd/libdbdsqlite3.so)
==7791== by 0x5B2B321: dbi_conn_quote_binary_copy (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==7791== by 0x4073B1: db_sms_store (db.c:701)
==7791== by 0x405BB5: test_db_sms_store (db_sms_test.c:310)
==7791== by 0x405BB5: main (db_sms_test.c:546)
==7791== Address 0x7ed1cf0 is 0 bytes after a block of size 0 alloc'd
==7791== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7791== by 0x857DC4B: dbd_quote_binary (in /usr/lib/x86_64-linux-gnu/dbd/libdbdsqlite3.so)
==7791== by 0x5B2B321: dbi_conn_quote_binary_copy (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==7791== by 0x4073B1: db_sms_store (db.c:701)
==7791== by 0x405BB5: test_db_sms_store (db_sms_test.c:310)
==7791== by 0x405BB5: main (db_sms_test.c:546)
...
DDB NOTICE test_db_sms_get('Empty TP-UD'): ==8051== Invalid read of size 1
==8051== at 0x5B30510: _dbd_decode_binary (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==8051== by 0x857D957: dbd_fetch_row (in /usr/lib/x86_64-linux-gnu/dbd/libdbdsqlite3.so)
==8051== by 0x5B2C86E: dbi_result_seek_row (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==8051== by 0x40828F: next_row (db.c:188)
==8051== by 0x40828F: db_sms_get (db.c:805)
==8051== by 0x406C29: test_db_sms_get (db_sms_test.c:390)
==8051== by 0x405C14: main (db_sms_test.c:547)
==8051== Address 0x8f74641 is 0 bytes after a block of size 1 alloc'd
==8051== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8051== by 0x5DBEB49: strdup (strdup.c:42)
==8051== by 0x857D93C: dbd_fetch_row (in /usr/lib/x86_64-linux-gnu/dbd/libdbdsqlite3.so)
==8051== by 0x5B2C86E: dbi_result_seek_row (in /usr/lib/x86_64-linux-gnu/libdbi.so.1.1.0)
==8051== by 0x40828F: next_row (db.c:188)
==8051== by 0x40828F: db_sms_get (db.c:805)
==8051== by 0x406C29: test_db_sms_get (db_sms_test.c:390)
==8051== by 0x405C14: main (db_sms_test.c:547)
==8051==
success, as expected
DDB NOTICE verify_sms('Empty TP-UD'): user_data_len mismatch: E0 vs A3
Apparently, dbi_conn_quote_binary_copy() doesn't properly handle
zero-length input. Let's guard against this.
Observed with:
- libdbi-dev 0.9.0-1
- libdbd-sqlite3:amd64 0.9.0-2ubuntu2
Change-Id: If0b2bb557118c5f0e520a2e6c2816336f6028661
Since OsmoMSC has built-in SMSC, it needs to store the messages
somewhere. Currently we use libdbi and SQLite3 back-end for that.
For a long time, the db_sms_* API remained uncovered by unit tests.
This change aims to fix that, and does cover the following calls:
- db_sms_store(),
- db_sms_get(),
- db_sms_get_next_unsent(),
- db_sms_mark_delivered(),
- db_sms_delete_sent_message_by_id(),
- db_sms_delete_by_msisdn(),
- db_sms_delete_oldest_expired_message().
Due to performance reasons, the test database is initialized in
RAM using the magic filename ':memory:'. This is a feature of
SQLite3 (and not libdbi), see:
https://www.sqlite.org/inmemorydb.html
Of course, this unit test helped to discover some problems:
1) Storing an SMS with empty TP-User-Data (TP-UDL=0) causes
buffer overruns in both db_sms_store() and db_sms_get().
2) TP-User-Data-Length is always being interpreted in octets,
regardless of DCS (Data Coding Scheme). This results in
storing garbage in the database if the default 7-bit
encoding is used. Fortunately, the 'user_data' buffer
in structure 'gsm_sms' is large emough, so we don't
experience buffer overruns.
3) db_sms_delete_oldest_expired_message() doesn't work
as expected. Instead of removing the *oldest* expired
message, it tries to remove the *newest* one.
The current test expectations do reflect these problems.
All of them will be fixed in the follow-up patches.
Change-Id: Id94ad35b6f78f839137db2e17010fbf9b40111a3
We also need stubs for the upcoming db_sms tests.
Due to a known bug of automake [1], we cannot use 'subdir-objects',
so as a side effect this change introduces some autoreconf warnings.
[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=752993
Change-Id: I8846c940f2695fd33e1007fecac83e73f508bb34
In the most cases we need to check whether particular char buffer
is empty or not. Using strlen() for that involves more CPU power,
so let's just check the first character against '\0'.
Change-Id: I8728876b80c870e82247e6e56f719e10ed322a95
The current way of printing subscriber, connection, and transaction
info is ugly (sorry) and has several problems:
- the terminal width should be large enough to fit quite long lines,
otherwise the output is unreadable and looks misaligned;
- some fields (such as subscriber name) can be larger than it's
expected, so either they're getting truncated, or again, the
output is misaligned and unreadable;
- adding new info fields would require one to think about the
alignment and would make the output even more cumbersome.
Here is an example output of 'show connection' command:
_Subscriber_______________________________________ _LAC_ _RAN___________________ _MSC-A_state_________ _MSC-A_use_
IMSI-123456789012345:MSISDN-12345:TMSI-0x12345678 1 GERAN-A-4294967295:A5-3 WAIT_CLASSMARK_UPDATE 2=cm_service,trans_cc
IMSI-123456789012356:MSISDN-234567:TMSI-0x123ABC78 65535 UTRAN-Iu-4294967295 COMMUNICATING 2=cm_service,trans_sms
IMSI-262073993158656:MSISDN-123456:TMSI-0x493026BA 1 GERAN-A-1 MSC_A_ST_COMMUNICATING 1=1 (silent_call)
Another 'show subscriber' command mixes the information about
subscriber, its connections and transactions without any alignment,
what also decreases the readability.
This change introduces a hierarchical approach, based on the old
'field per line' formatting. First of all, the VTY commands were
extended with optional flags:
show connection [trans]
show subscriber cache [(conn|trans|conn+trans)]
show subscriber TYPE ID [(conn|trans|conn+trans)]
so it can be decided, whether to print child connections and/or
transaction, or not. For example:
show connection trans
would print all connections and their child transactions with
hierarchical alignment:
Connection #00:
Subscriber: IMSI-262073993158656:MSISDN-123456:TMSI-0x76760B75
RAN connection: GERAN-A-1
RAN connection state: MSC_A_ST_COMMUNICATING
LAC / cell ID: 1 / 0
Use count total: 1
Use count: 1 (silent_call)
Transaction #00:
Unique (global) identifier: 0x00000000
GSM 04.07 identifier (MT): 0
Type: silent-call
another example is:
show subscriber cache conn+trans
which would print all known subscribers,
their active connections and transactions:
Subscriber #00:
MSISDN: 123456
LAC / cell ID: 1 / 0
RAN type: GERAN-A
IMSI: 262073993158656
TMSI: 76760B75
...
Connection:
RAN connection: GERAN-A-1
RAN connection state: MSC_A_ST_COMMUNICATING
...
Transaction #00:
Unique (global) identifier: 0x00000000
GSM 04.07 identifier (MT): 0
Type: silent-call
Transaction #01:
Unique (global) identifier: 0x00000001
GSM 04.07 identifier (MO): 0
Type: SMS
Transaction #02:
Unique (global) identifier: 0x00000002
GSM 04.07 identifier (MT): 0
Type: SMS
Please note that we don't print redundant info in child nodes
(i.e. connection and transaction info), such as subscriber name
in connection info, nor connection name in transaction info - it
is clear from the hierarchical formatting.
Change-Id: I5e58b56204c3f3d019e8d4c3c96cefdbb4af4d47
The HLR (which is connected via the GSUP interface) may fail and
disconnect. On the next location update the VLR will try to talk to the
HLR and fail. This failure event is not communicated towards the SGs
related code and the SGs-association will remain in the LA-PRESENT state
forever. Lets add code to report the problem to the SGs code and trigger
a RESET an the SGs interface.
- Add a flag to report an HLR problem back to the SGs code
- Fix the FSM that controls the reset
- Make sure the all SGs associations are reset when the failure occurs.
Change-Id: Icc7df92879728bc98c85fc1d5d8b4c6246501b12
Related: OS#3859
According to 3GPP TS 29.002, section 7.6.8.7, MMS (More Messages to Send)
is an optional IE of MT-ForwardSM-Req message which is used by SMSC to
indicate that there are more (multi-part) MT SMS messages to be sent.
The MSC needs to use this indication in order to decide whether to
keep the RAN connection with a given subscriber open.
Related Change-Id: (TTCN) I6308586a70c4fb3254c519330a61a9667372149f
Change-Id: Ic46b04913b2e8cc5d11a39426dcc1bfe11f1d31e
Related: OS#3587
in osmo-msc/Makefile.am, osmo-msc was actually missing the LIBASN1C_LIBS even
though it included LIBASN1C_CFLAGS. Probably libasn1c is implicitly linked from
libranap.so, but doesn't hurt to name it.
When building without Iu support, the LIBOSMORANAP* and LIBASN1C* vars are
empty, so no need to explicitly switch on BUILD_IU, just name them.
Change-Id: I39ae5e3f0f7661ca9ee5c17a500be28c461d7ec7
DB counters has been used to save osmo_counters & osmo_rate_ctr to a local
sqlite databases every 60 seconds.
This is quite slow e.g. 1000 subscriber might slow the msc down.
Change-Id: Id64f1839a55b5326f74ec04b7a5dbed9d269b89c
Later on we want to do extra steps upon receiving a Rx Reset Ack
(checking for Osmux support from peer). Let's move handling of this
message into its own function to have handling implementation in one
place.
Change-Id: I516c4baf6071d26f6c530726d93677bed968efd1
When 'check-imei-rqd 1 early' is set in the config, send the IMEI to
the HLR before doing the location update with the HLR.
The OsmoHLR documentation referenced in the code will be added in
osmo-hlr.git's Change-Id I2dd4a56f7b8be8b5d0e6fc32e04459e5e278d0a9.
Related: OS#2542
Change-Id: I88283cad23793b475445d814ff49db534cb41244
Copy IMEISV to IMEI when IMEISV changes. The additional SV digits will
get cut off then. This is needed for the subscriber on demand use case,
since we can get the IMEISV early (see [1]), but need to send the IMEI
to the Check IMEI procedure.
While adjusting the tests, I have noticed that there are code paths
where we ask the MS for the IMEISV first, and later ask the MS for the
IMEI, although we already have the IMEISV. This could be improved in a
future patch.
[1] Change-Id I256224194c3b8caf2b58a88d11dccd32c569201f
Related: OS#2542
Change-Id: I02e7b66848bf7dddb31b105e2ae981432817ae1e
Set the length of vlr_subscr->imei to
GSM23003_IMEI_NUM_DIGITS_NO_CHK (14)
instead of
GSM23003_IMEISV_NUM_DIGITS (16).
Note that there is also GSM23003_IMEI_NUM_DIGITS (15), which includes
an additional checksum digit. This digit is not intended for digital
transmission, so we don't need to store it. Also by not storing it, we
can simply copy the IMEI-part from the IMEISV to the IMEI without
worrying about the checksum (will be done in a follow up patch).
A good overview of the IMEI/IMEISV structure is here:
https://en.wikipedia.org/wiki/International_Mobile_Equipment_Identity#Structure_of_the_IMEI_and_IMEISV_(IMEI_software_version)
Related: OS#2542
Change-Id: Iaf2569c099874b55acbd748b776394726cc5ce54
Prepare for Rhizomatica's subscriber on demand use case, in which the
network access is disabled by default for new subscribers, but the IMEI
is required in the HLR to find out which user has which IMSI. Due to the
network access being disabled, the location update request towards the
HLR fails and the MS gets rejected, so we need to get the IMEI early.
Related: OS#2542, OS#3755
Change-Id: I256224194c3b8caf2b58a88d11dccd32c569201f
Previous patch [1] removed NULL-safety from LOG_TRANS(). Fix that.
In case a trans is NULL, it is fine to log in the DMSC category, since the
context should still be general (erratic message or other initial problems).
[1] 7f85acea9b / I6dfe5b98fb9e884c2dde61d603832dafceb12123
"LOG_TRANS: store subsys in trans, unify USSD logging back to DMM"
Change-Id: I6e36c47bf828dd073b36c6301bbeabcc28e101e6