Looking at sending GSUP messages between MSCs via an HLR acting as forwarding
agent, I see that the current decision for GSUP message consumption is
suboptimal:
Depending on the message type sent and received, libvlr of osmo-msc forwards
GSUP messages to the MSC code, and there, again, depending on the message type,
specific callbacks get invoked.
See vlr_gsupc_read_cb() and msc_vlr_route_gsup_msg().
In current osmo-msc it might seem to make sense to first resolve the IMSI to a
vlr_subscr in vlr.c. But if osmo-msc acts as a Handover target for an inter-MSC
Handover, it should be able to handle unknown IMSIs. Also, should we ever go
for a separate SMSC process, the VLR as first stage makes no sense. Finding a
vlr_subscr is a one-liner with vlr_subscr_find_by_imsi().
I would much rather have an explicit destination entity advertised in the GSUP
messages, and an explicit common GSUP MUX stage. In other words, the VLR of
osmo-msc shouldn't act as a GSUP forwarder, it should merely be one of the GSUP
consumers, and shouldn't even be involved when the messages are intended for
inter-MSC, for USSD or for SMS use.
And finally, for GSUP error responses, for example a report that a specific
target could not be reached, it may not be possible to trivially derive the
right GSUP message consumer from the GSUP message (like "Routing Error").
Going towards that idea, I have put in place the following in my temporary dev
source tree:
enum osmo_gsup_entity {
OSMO_GSUP_ENTITY_NONE = 0,
OSMO_GSUP_ENTITY_HLR,
OSMO_GSUP_ENTITY_VLR,
OSMO_GSUP_ENTITY_ESME,
OSMO_GSUP_ENTITY_SMSC,
OSMO_GSUP_ENTITY_USSD, // FIXME: what's an "ESME"/"SMSC" for USSD?
OSMO_GSUP_ENTITY_MSC_A,
OSMO_GSUP_ENTITY_MSC_B,
OSMO_GSUP_ENTITY_COUNT,
};
struct osmo_gsup_message {
[...]
enum osmo_gsup_entity source_entity;
enum osmo_gsup_entity destination_entity;
[...]
};
For calling the right rx_cb, we would need only an explicit target kind, but
for returning errors it is better to also include the source entity kind
explicitly.
A gsup_client_mux API:
struct gsup_client_mux_rx_cb {
int (* func )(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_message *msg);
void *data;
};
struct gsup_client_mux {
struct osmo_gsup_client *gsup_client;
/* Target clients by enum osmo_gsup_entity */
struct gsup_client_mux_rx_cb rx_cb[OSMO_GSUP_ENTITY_COUNT];
};
int gsup_client_mux_init(struct gsup_client_mux *gcm, struct osmo_gsup_client *gsup_client);
int gsup_client_mux_tx(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_msg);
void gsup_client_mux_tx_error_reply(struct gsup_client_mux *gcm, const struct osmo_gsup_message *gsup_orig,
enum gsm48_gmm_cause cause);
For backwards compat, we would still need to do target classification by
message type, but only if no explicit destination_entity is set:
static enum osmo_gsup_entity gsup_client_mux_classify(struct gsup_client_mux *gcm,
const struct osmo_gsup_message *gsup)
{
if (gsup->destination_entity)
return gsup->destination_entity;
/* Legacy message that lacks an explicit target entity. Guess by message type for backwards compat: */
switch (gsup_msg->message_type) {
case OSMO_GSUP_MSGT_PROC_SS_REQUEST:
case OSMO_GSUP_MSGT_PROC_SS_RESULT:
case OSMO_GSUP_MSGT_PROC_SS_ERROR:
return OSMO_GSUP_ENTITY_USSD;
case OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR:
case OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT:
case OSMO_GSUP_MSGT_READY_FOR_SM_ERROR:
case OSMO_GSUP_MSGT_READY_FOR_SM_RESULT:
case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST:
return OSMO_GSUP_ENTITY_SMSC;
default:
/* osmo-hlr capable of forwarding inter-MSC messages always includes the target entity, so any
* other legacy message is for the VLR. */
return OSMO_GSUP_ENTITY_VLR;
}
}
We'd have:
HLR <-> VLR
ESME <-> SMSC
USSD <-> USSD (names??)
MSC_A <-> MSC_B
Thanks for your thoughts.
~N
While working on the talloc context patches, I was wondering if we should
spend a bit of time to further improve libosmocore and collect something
like a wishlist.
I would currently identify the following areas:
1) initialization of the various sub-systems is too complex, there are too
many functions an application has to call. I would like to move more
to a global "application initialization", where an application registers
some large struct [of structs, ...] at start-up and tells the library
the log configuration, the copyright statement, the VTY IP/port, the config
file name, ... (some of those can of course be NULL and hence not used)
2) have some kind of extensible command line options/arguments parser
It would be useful to have common/library parts register some common
command line arguments (like config file, logging, daemonization, ..)
while the actual appliacation extending that with only its application-specific
options. I don't think this is possible with how getopt() works, so
it would require some new/different infrastructure how applications would
register their arguments
3) move global select() state into some kind of structure. This would mean
that there could be multiple lists of file descriptors rather than the
one implicit global one. Alternatively, turn the state into thread-local
storage, so each thread would have its own set of registered file descriptors,
which probably makes most sense. Not sure if one would have diffeent 'sets'
of registered file descriptors in a single thread. The same would apply
for timers: Have a list of timers for each thread; timeouts would then
also always execute on the same thread. This would put talloc context, select
and timers all in the same concept: Have one set of each on each thread,
used automatically.
Any other wishlist items?
--
- Harald Welte <laforge(a)gnumonks.org> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
The templates for GSUP in GSUP_Types.ttcn seem to expect the GSUP IEs in a
specific order, which shouldn't be required.
Also I cannot easily define certain GSUP IEs as not mattering.
Particularly, I added Source Entity and Destination Entity IEs, and now I would
have liked to just add some source_entity := *, destination_entity := *, to
trivially make all tr_GSUP() pass, whether these IEs are present or not.
Instead I have to now add them to a listing of IEs everywhere.
That means the test suite will only work with the new osmo-msc and even if
"nightly" works out, we will see "latest" failing, etc.
I'd like to use the semantics I am used to in e.g. BSSMAP messages:
- order doesn't matter
- easy ':= *' for items in the root tr_GSUP() template
What would it take to make GSUP messages match in this way?
~N
Hi all,
this idea has been floating around for quite some time, and I finally took
some time for a proposed implementation: The introduction of a "volatile"
talloc context which one can use to allocate whatever temporary things from,
and which would automatically be free'd once we leave the select dispatch.
The current proposal is in https://gerrit.osmocom.org/#/c/libosmocore/+/13312
and I'm happy to receive any review.
How this works:
* within a new osmo_select_main_ctx() function, we create a temporary talloc
context before calling the filedescriptor call-back functions, and we
free that after the call-backs have returned
* any of the code running from within the select loop dispatch (which for
"normal" osmocom CNI projects is virtually everything) can use that
temporary context for allocations. There's a OTC_SELECT #define for
convenience. So you could do something like talloc_zero(OTC_SELECT, ...)
which would be automatically free'd after the current select loop
iteration.
Where is this useful? There's at least two common use cases:
* allocation of message buffers without having to worry about msgb ownership
* various temporary buffers e.g. for something-to-string conversions where
currently we use library-internal static buffers with all their known problems
(not being able to use them twice within a single printf() statement, not
being thread-safe, ...)
To Neels' disappointment, this is not all automatic. You
a) have to call the _c suffix of the respective function, e.g. osmo_hexdump_c()
instead of osmo_hexdump() with one extra initial argument:
OTC_SELECT. There's also msgb_alloc_c(), msgb_copy_c() and the like,
allowing msgb allocation from a context of your choice, as opposed
to the library-internal msgb_tall_ctx that we had so far.
b) have to use osmo_select_main_ctx() instead of osmo_select_main(). This is
an arbitrary limitation for optimization that Pau requested, to make sure
applications that don't want this can avoid all the extra talloc+free at
every select iteration. This is debatable, and we can make it automatic
in osmo_select_main(). It's probably worth a benchmark how expensive
that 'empty' allocation + free is.
However, I think that's a rather "OK" price to pay. Converting the existing
callers can be more or less done with "sed" (yes, spatch is of course better).
While introducing this feature, I also tried to address two other topics, which
are not strictly related. However, ignoring those two now would mean
we'd have API/ABI breaks if we'd care about them in the future. Hence I
think we should resolve them right away:
1) introduce another context: OTC_GLOBAL. This is basically a library-internal
replacement for the "g_tall_ctx" that we typically generate as one of the
first things in every application. You can use it anywhere where you'd want
to allocate something form the global talloc context
2) make those contexts thread-local. As you may know, talloc is not thread
safe. So you cannot allocate/free from a single context on multiple
threds. However, it is safe to have separate talloc contexts on each
thread. Making the new OTC_* contexts per-thread, we are enabling the
[limited] use of this functionality in multi-threaded programs. This
is of course very far from making libosmocore thread-safe. There are
many library-internal data structures like timers, file descriptors,
the VTY, ... which are absolutely not thread-safe. However, I think
it's a step in the right direction and I don't expect any performance
impact for single-threaded programs by marking the contexts as
__thread.
--
- Harald Welte <laforge(a)gnumonks.org> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
Hi,
We had a question with regards to the OSMO MSc - as per the documentation , it does support a scaled down version of SMSC. Can we bring up just the SMSc service so that it can talk to another vendor's MSC/HLR .
We are trying to perform CSFB SMS tests with an external MSC / OSMO SMSC and Amarisoft EPC Core . So wanted to check if the OSMO SMSC could be used for this test.
Thanks
Alex
Hello,
openbsc.git doesn't build anymore against libosmocore master:
> ../../src/libcommon/libcommon.a(talloc_ctx.o): In function `talloc_ctx_init':
> /build/openbsc/src/libcommon/talloc_ctx.c:50: undefined reference to `tall_sigh_ctx'
Full build log:
https://jenkins.osmocom.org/jenkins/job/master-openbsc/IU=--disable-iu,MGCP…
Looks like this patch broke it:
https://gerrit.osmocom.org/#/c/libosmocore/+/13337/
Regards,
Oliver
--
- Oliver Smith <osmith(a)sysmocom.de> https://www.sysmocom.de/
=======================================================================
* sysmocom - systems for mobile communications GmbH
* Alt-Moabit 93
* 10559 Berlin, Germany
* Sitz / Registered office: Berlin, HRB 134158 B
* Geschaeftsfuehrer / Managing Director: Harald Welte
Hi.
While experimenting with BTS TTCN-3 tests I've got some of the tests
misteriously failing with:
FBSB Failed with non-zero return code 255
Anyone hit this before? Any ideas what could be causing this?
--
- Max Suraev <msuraev(a)sysmocom.de> http://www.sysmocom.de/
=======================================================================
* sysmocom - systems for mobile communications GmbH
* Alt-Moabit 93
* 10559 Berlin, Germany
* Sitz / Registered office: Berlin, HRB 134158 B
* Geschaeftsfuehrer / Managing Directors: Harald Welte
Hi Neels,
> 21:14 < neeels> LaF0rge, I need a solution for picking a conn_id as an SCCP SAP user. The way osmo-bsc
> does it isn't much good either. There has to be some way to obtain an unused local
> reference without running into potential collisions
> 21:16 < neeels> (I submitted the patch expecting your -1, but just to make sure that I understood
> correctly I wanted to submit as code that has no room for misunderstandings)
> 21:18 < neeels> if I can't use the internal "next_id" thing, then what I would have to do is mimick the
> exact same in osmo-msc by looking up what conn_ids are already in use and pick an unused
> one. That's quite brain damaged IMHO, it's the same thing as that layer violation patch,
> only with much more effort and more chances for id collisions.
Nobody is suggesting that.
> 21:21 < neeels> ideas: add some primitive to hand out a local reference -- but that would be non-standard
> IIUC
I had mentioned and discarded that option in Message-ID: <20190311204817.GA725@nataraja>
here on this list. The reason is not that it's non-standard, but that it again wouldn't
work over any type of asynchronous / message based SAP [and that's how a SAP is conceptualized].
> 21:21 < neeels> give each application some unique number space for local references, like the highest
> byte is configured in .cfg file, and then each SCCP user cycles through its own number
> space of local references
> 21:23 < neeels> ...and libosmo-sccp would have to be constrain-able to its own number space for incoming
> connections
I was quite sure we've had that discussion before. Unfortuantely it doesn't
seem to be on this mailing list or in gerrit. It may have been on IRC or I am
starting to be delusional :/
The correct solution from the spec / SCCP architecutre point of view is rather clear, I think:
* don't recycle the SCCP local reference (protocol) from the SCCP connection ID (SAP),
but use distinct number spaces for that. It was an oversimplification to do that
in the original implementation. I simply missed the different scoping of those
two identifiers. The scoping is the root of our problems here.
* only once we have distinct identifiers, we can fix the scope: One of
the two identifiers has a per-SCCP-user scope, while the other has a
per-SCCP-instance scope
* this way, every SCCP user knows exactly which SCCP connection identifiers are
currently in use between this specific user and the SCCP provider, and it hence
can choose any unused ID for a new connection
* right now, the primitive exchange across the SCCP user SAP is synchronous,
so there can be no races where the SCCP provider and the SCCP user could
chose the same connection ID at the same time. If you want to prepare for
some kind of possible future asynchronous, message-queue based SAP, then you
could use the highest bit as "allocation flag", e.g. highest bit = 0, allocated
by the SCCP provider and highest bit = 1, allocated by SCCP user.
Let me know if you see any problem with above proposal.
Regards,
Harald
--
- Harald Welte <laforge(a)gnumonks.org> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
Hi all,
master-libosmocore was running for 20 hours on jenkins, hanging here:
> make[7]: Entering directory '/home/osmocom-build/jenkins/workspace/master-libosmocore/a2/default/a3/default/a4/default/arch/amd64/label/osmocom-master-debian9/builddir/tests'
> osmo_verify_transcript_vty.py -v \
> -p 42042 \
> -r "../tests/tdef/tdef_vty_test_config_root" \
> /home/osmocom-build/jenkins/workspace/master-libosmocore/a2/default/a3/default/a4/default/arch/amd64/label/osmocom-master-debian9/tests/tdef/tdef_vty_test_config_root.vty
> <0000> /home/osmocom-build/jenkins/workspace/master-libosmocore/a2/default/a3/default/a4/default/arch/amd64/label/osmocom-master-debian9/src/socket.c:367 unable to bind socket:127.0.0.1:42042: Address already in use
> [0;m<0000> /home/osmocom-build/jenkins/workspace/master-libosmocore/a2/default/a3/default/a4/default/arch/amd64/label/osmocom-master-debian9/src/socket.c:378 no suitable addr found for: 127.0.0.1:42042
> [0;m<0000> /home/osmocom-build/jenkins/workspace/master-libosmocore/a2/default/a3/default/a4/default/arch/amd64/label/osmocom-master-debian9/src/vty/telnet_interface.c:100 Cannot bind telnet at 127.0.0.1 42042
https://jenkins.osmocom.org/jenkins/job/master-libosmocore/a2=default,a3=de…
I've stopped the job. Right after that, a new job spawned, and it also
failed to bind telnet at 42042. It did not hang this time, but stopped
there instead:
https://jenkins.osmocom.org/jenkins/job/master-libosmocore/a2=default,a3=de…
After triggering the job once more manually, it went through.
>From a quick analysis, I can not see why this has happened in the first
place. The master-libosmocore job is set to non-concurrent:
https://git.osmocom.org/osmo-ci/tree/jobs/master-builds.yml
And the gerrit verification jobs are running on another machine. Other
than that, none but libosamocore.git of the (almost all) Osmocom
repositories that I have checked out mention port 42042, so nothing else
should bind that in theory.
Regards,
Oliver
--
- Oliver Smith <osmith(a)sysmocom.de> https://www.sysmocom.de/
=======================================================================
* sysmocom - systems for mobile communications GmbH
* Alt-Moabit 93
* 10559 Berlin, Germany
* Sitz / Registered office: Berlin, HRB 134158 B
* Geschaeftsfuehrer / Managing Director: Harald Welte
Avoiding msgb leaks is easiest if the caller retains ownership of the msgb.
Take this hypothetical chain where leaks are obviously avoided:
void send()
{
msg = msgb_alloc();
dispatch(msg);
msgb_free(msg);
}
void dispatch(msg)
{
osmo_fsm_inst_dispatch(fi, msg);
}
void fi_on_event(fi, data)
{
if (socket_is_ok)
socket_write((struct msgb*)data);
}
void socket_write(msgb)
{
if (!ok1)
return;
if (ok2) {
if (!ok3)
return;
write(sock, msg->data);
}
}
However, if the caller passes ownership down to the msgb consumer, things
become nightmarishly complex:
void send()
{
msg = msgb_alloc();
rc = dispatch(msg);
/* dispatching event failed? */
if (rc)
msgb_free(msg);
}
int dispatch(msg)
{
if (osmo_fsm_inst_dispatch(fi, msg))
return -1;
if (something_else())
return -1; // <-- double free!
}
void fi_on_event(fi, data)
{
if (socket_is_ok) {
socket_write((struct msgb*)data);
else
/* socket didn't consume? */
msgb_free(data);
}
int socket_write(msgb)
{
if (!ok1)
return -1; // <-- leak!
if (ok2) {
if (!ok3)
goto out;
write(sock, msg->data);
}
out:
msgb_free(msg);
return -2;
}
If any link in this call chain fails to be aware of the importance to return a
failed RC or to free a msgb if the chain is broken, we have a hidden msgb leak.
This is the case with osmo_sccp_user_sap_down(). In new osmo-msc, passing data
through various FSM instances, there is high potential for leak/double-free
bugs. A very large brain is required to track down every msgb path.
Isn't it possible to provide osmo_sccp_user_sap_down() in the caller-owns
paradigm? Thinking about an osmo_sccp_user_sap_down2() that simply doesn't
msgb_free().
Passing ownership to the consumer is imperative if a msg queue is involved that
might send out asynchronously. (A workaround could be to copy the message
before passing into the wqueue.) However, looks to me like no osmo_wqueue is
involved in osmo_sccp_user_sap_down()? It already frees the msgb right upon
returning, so this should be perfectly fine -- right?
I think I'll just try it, but if anyone knows a definite reason why this will
not work, please let me know.
(Remotely related, I also still have this potential xua msg leak fix lying
around, never got around to verify it:
https://gerrit.osmocom.org/#/c/libosmo-sccp/+/9957/ )
~N
--
- Neels Hofmeyr <nhofmeyr(a)sysmocom.de> http://www.sysmocom.de/
=======================================================================
* sysmocom - systems for mobile communications GmbH
* Alt-Moabit 93
* 10559 Berlin, Germany
* Sitz / Registered office: Berlin, HRB 134158 B
* Geschäftsführer / Managing Directors: Harald Welte
Hi Sylvain,
completely unrelated to the osmo-msc patch, your other patch that was merged to
osmo-bsc breaks voice channel assignment, and I had to revert it. Mentioned so
on IRC, but since you didn't reply I thought it best to also post this here:
tnt, I think you broke voice Assignment in osmo-bsc. Can't get a voice call in current master. It works again if I revert 4d3a21269b25e7164a94fa8ce3ad67ff80904aee
tnt, I'm choosing to revert this from current master now; let's fix it, test and the re-apply the patch when it is ready
https://gerrit.osmocom.org/c/osmo-bsc/+/13256
I hope I'm not annoying you by annulling all of your patches :P
It's definitely not on purpose!
~N
Hi everyone, and in this particular case Sylvain,
I know I'm hogging osmo-msc.git and I don't intend to hinder everyone else's
work, but I doubt that it was really necessary to merge the silent call channel
types patch to master right now. I'm really overloaded with doing the inter-MSC
handover work, I'm again postponing my well earned leave that I would have
liked to have started two months ago, and I don't want to be burdened with also
resolving everyone else's merge conflicts. You all know that pretty much
everything changes in osmo-msc, even if only slightly. As a rule of thumb, if
you see a 'ran_conn', 'vlr_subscr_get()', a Paging callback function or a
'gsm_trans' in a bit of code, likely there will be merge conflicts with my
current branch. Most should be trivial, but they will be stones put in my way.
So please, before you merge onto master, consider doing the same work on the
tip of my branch 'neels/ho' in osmo-msc, rather than on current master. That
would be the ideal situation for me, because then you also test my patches.
There still is ongoing work at the tip of neels/ho, if you want a more stable
point to apply modifications to, look at the commit 'add LOG_TRANS, proper
context for all transactions' and rebase your changes onto that.
If you push those changes onto a private branch, I will even see them in tig
and can simply incorporate them in by branch, carrying them along until we're
ready to merge.
If you prefer working on master, still do me a favor: just try to rebase the
patch onto neels/ho. All the conflicts that you see in such a rebase will end
up on my table and stop me from going forward until I have resolved them.
Consider that before you hit that "Submit" button on gerrit in the osmo-msc.git
repository.
Plus, if I resolve conflicts with *your* code, likely I won't grok some minor
detail and introduce bugs.
So let's work together on this. Thanks!
Working on osmo-msc.git neels/ho branch also needs various patches in other
repositories; all these branches are kept up-to-date every day and all the
time:
libosmocore neels/misc
libosmo-sccp neels/conn_id
osmo-mgw neels/endpoint_fsm
osmo-msc neels/ho
Thanks again!
~N
I'm trying to test inter-BSC Handover in ttcn3.
At first I had problems grasping the concepts, but in the end it worked pretty
nicely to start two distinct BSC handlers like this:
testcase TC_ho_inter_bsc() runs on MTC_CT {
var BSC_ConnHdlr vc_conn0;
var BSC_ConnHdlr vc_conn1;
f_init(2);
vc_conn0 := f_start_handler(refers(f_tc_ho_inter_bsc0), 53, 0);
vc_conn1 := f_start_handler(refers(f_tc_ho_inter_bsc1), 53, 1);
vc_conn0.done;
vc_conn1.done;
}
It's walking all the way through inter-BSC Handover now (!) up until the point
where I want to discard the call.
Now I'm facing the simple problem that I want to call f_call_hangup() in the
second f_tc_ho_inter_bsc1() -- but I have no cpars (CallParameters) with a
valid MNCC callref nor the CC transaction ID, those are in the first function.
How can I share cpars between those functions?
The transaction_id and callref determined by the MNCC and CC messages that
happened in f_tc_ho_inter_bsc0 need to move over to f_tc_ho_inter_bsc1, much
like the MS has moved to the other BSC.
So it would make sense to have some global struct representing the MS which
both BSC_ConnHdlr instances can access, if that is at all possible ... ?
As a bit of a weak workaround, I could inter-BSC handover right back to the
first BSC and then f_call_hangup() there :P
~N
--
- Neels Hofmeyr <nhofmeyr(a)sysmocom.de> http://www.sysmocom.de/
=======================================================================
* sysmocom - systems for mobile communications GmbH
* Alt-Moabit 93
* 10559 Berlin, Germany
* Sitz / Registered office: Berlin, HRB 134158 B
* Geschäftsführer / Managing Directors: Harald Welte
Dear Osmocom community,
starting from 16th of January (until 7th of February) we can apply
Google Summer of Code as an Open source mentor organization. Many
well-known projects, such as Debian, FFmpeg, Apache, Git, GCC,
GNURadio and others, have been participating last year.
Personally, I think it's a great opportunity to move some of our
projects forward. I would like to know your opinions about this
idea, should we participate? I would be happy to be a mentor.
With best regards,
Vadim Yanitskiy.
Hi Neels, from your IRC question today:
> when opening a new conn on SCCP, what's the proper way to get a
> conn_id? I want to feed OSMO_SCU_PRIM_N_CONNECT into
> osmo_sccp_user_sap_down(), but it seems the caller needs to pick a
> conn_id??
Whatever way you can think of to cough up a unique identifer for that connection.
> I assumed that libosmo-sccp implicitly picks an unused local conn
> reference, but that's not the case.
Note that in this sentence you're now talking about the "SCCP local
reference", which is something communicated on the wire between two SCCP
providers (implementations). Hence, it is managed inside the
SCCP provider[s] and can be seen in the source local reference /
destination local reference field of the SCCP messages.
That's *not strictly* the SCCP connection identifier which has
significance only across the SCCP User SAP (i.e. between SCCP User and
SCCP Provider on the same system), and which never is visible on any
SCCP message on the wire. It's just an implementation shortcut of the
Osmocom implementation that uses the same identifiers on both sides,
rather than allocating separate ones.
But getting back to your question: If the SCCP provider was to receive
a N-CONNECT.req without some kind of identifier, and simply allocate
one, how would that identifier be communicated back to the user? Those
primitives work asynchronosuly. You'd have to come up with
yet-another-identifier, like a "primitive tag" where that tag then would
be eacho'ed back in the N-CONNECT.resp - and you end up again having to
allocate some unique identifier :P
> sccp_scoc.c has conn_create() which seems to pick an unused id, but
> that part is static in a .c file
> hnbgw just uses 1:1 the same conn_id from RUA to RANAP and thus doesn't invent new ones
Now I'm confused. RUA isn't running over SCCP, right?
> osmo-bsc goes through its list of &bsc_gsmnet->subscr_conns to pick an unused id
> I can do that in osmo-msc, but it seems to me libosmo-sccp should have common API for that
The SCCP User SAP is modelled strictly after the ITU specs. Always
imagine yourself in a situation where the SCCP user and SCCP provider
are running in different processes and they don't have access to each
others's state - and all they can exchange are the SCCP User SAP
primitives in some serialized form. While libosmo-sccp doesn't work
like this (so far), we should always keep that in mind and keep the SAP
boundary clean.
As there's no primitive in ITU-T Q.7xx for "allocate me a local
reference", we don't have one :/
I'm not sure what we should do here. If we introduce that kind of SCU
primitive, then the questions is how are they allocated/released? Who
is in charge of that? What kind of object would the SCCP provider use
to keep track of allocated IDs for which there is no connection yet, as
the N-CONNECT.req was not yet received?
The current situation is not great. After all, theoretically there
could be an incoming new SCCP connection for which the provider choses
the same ID that the user at the same time choses for a new outbound
connection -> boom. One could use something like the highest-order bit
to distinguish between user-allocated and provider-allocated
identifiers.
Regards,
Harald
--
- Harald Welte <laforge(a)gnumonks.org> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
Hello Keith,
> 2) 3G data instabilities
> ( Just a quick observation note, no pcap! )
> I happened to notice that pinging a 3G handset from the network side
> (default ping: 1 sec internal, 64 ICMP bytes) keeps the connection
> "alive" and using 3G data is then a pleasant experience, IM, email,
> browsing, SIP call all working nicely. peak max download speed of 16Mbps
> was reported at one time by m.speedof.me
Can I ask you to expand a bit more on the topic? Sorry, it's been a while after
you sent the original email.
>From where did you perform a ping? From the machine where GGSN is running?
And that also means that to run 3G PS network now it is needed to make some type
of a service which will ping all the handsets registered, right? (Actually, that
is what I am going to do now while the SGSN isn't fixed by somebody or us)
Thank You!
Kind regards,
Mykola
Hi all,
Neels has recently proposed an osmo_ip_port API, see
https://gerrit.osmocom.org/#/c/libosmocore/+/13123
I'm somewhat reluctant to get this merged into libosmocore, as from my point
of view, it's reinventing what sockaddr_storage is doing in libc, but storign
the address in host byte order and string format. So I would argue we should
rather create helper/utility functions around sockaddr_storage and do any
string/binary and endianness conversions hidden by/within that API.
Irrespective of the above, I would want to hear what other developers think. Do
you think that it's worthwhile to
1) have some utility functions / infrastructure (irrespective of the data type)
1a) in libosmocore, or
1b) keep it to osmo-mgw
2) prefer to
2a) have strings for IP adresses and host-byte-order port numbers like the proposed patchset, or
2b) go with native sockaddr_storage?
If others think it should be merged, I won't try to veto it. I just want to
hear some more voices rather than just my own point-of-view.
Regards,
Harald
--
- Harald Welte <laforge(a)gnumonks.org> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
The new product from Lime is marked to start shipping tomorrow. As far
as I understand it is basically the LimeSDR mini with a GPS disciplined
clock and a Raspberry Pi module, so it /should/ run osmo-bts +
osmo-trx-lms fine, and without clocking issues.
It also has POE.
I was wondering if anybody else has looked at it, has comments, or has
or is thinking of ordering one?
Thanks!
As a bit of relaxation in-between the serious hacking, I gave a little idea of
mine a spin, which could improve our use of static string buffers.
My idea is to use one common static buffer string, as a ring buffer, for all
our osmo_xxx_name() functions, that returns new chunks of static string every
time. Why?
The point is that we have many osmo_xxx_name() functions that return a string
in one single static buffer. When you call it a second time, it overwrites the
buffer. So this doesn't work:
printf("PLMN changed from %s to %s\n",
osmo_plmn_name(old_plmn),
osmo_plmn_name(new_plmn));
No matter what, this will always print the same string twice, and probably
no-one would notice.
For this, I have previously often invented xxx_name2() functions:
printf("PLMN changed from %s to %s\n",
osmo_plmn_name(old_plmn),
osmo_plmn_name2(new_plmn));
With osmo_plmn_name2() being:
"Same as osmo_plmn_name(), but returning in a different static buffer."
That is bad for these reasons:
- each new separate function adds another static buffer to the program size,
which remains unused all the other time.
- each new separate function adds more API signatures.
Alternatively we have xxx_buf() functions, but they are more cumbersome to use:
char buf[123];
gsm0808_cell_id_list_name_buf(buf, sizeof(buf), cil);
LOGP(DMSC, LOGL_DEBUG, "%s\n", buf);
Particularly for logging, that would always run even though the logging
category might be switched off.
So I came up with these patches, and changing all of current libosmocore's
static buffers to using this does work:
http://git.osmocom.org/libosmocore/log/?h=neels/static_strings
(second last patch introduces the API, last patch changes all libosmocore callers)
Also pushed to gerrit for easier review:
https://gerrit.osmocom.org/13061
the benefits:
- All osmo_xxx_name() functions can be called N times in a single printf()
statement, without the need for managing buffers.
- No osmo_xxx_name2() functions for "separate static buffer"
- Just fire off LOGP() args and the code gets skipped if the category / log
level is switched off:
LOGP(DMSC, LOGL_DEBUG,
"PLMN changed from %s to %s, but Fred says it was %s\n",
osmo_plmn_name(old_plmn),
osmo_plmn_name(new_plmn),
osmo_plmn_name(freds_plmn));
I think it would be nice to have this mechanism for easier string hacking,
but not sure if the tradeoffs / vague side effects are worth it.
So this might as well remain a fun idea that never made it.
Thoughts welcome.
Implementation considerations...
At first I thought a plain ring buffer returning the next bit of memory every
time would suffice, but I didn't like the need to vaguely trust that we never
use overlapping memory.
The best I could come up with was to guarantee up to N subsequent static
strings as non-overlapping. See the semantics around the 'recent' members.
But that entails an uncomfortable tradeoff:
I kind of expected to reduce the size of static char buffers in libosmocore,
but if I want to disallow overlapping N uses, the buffer has to be able to hold
N subsequent allocations of the largest buffer, which currently is 4100. So I
end up with a larger static char buffer. The advantage however is that every
libosmocore using program with its own xxx_name() functions can now use the
same static string space and does not need to add more static buffers all over
the place.
To make the buffer smaller, I considered taking the largest buffer callers out
of this, i.e. osmo_hexdump() and msgb_hexdump(). But particularly
osmo_hexdump() is one of the functions that I would like to be able to call
more than once in a printf() arg list. Actually that would in practice be of
smaller size than the maximum 4096 currently allowed. But the 'recent' check
above requires the *largest* size to fully fit N times.
Consider: if I choose a total buffer of 4096 bytes and print one hexdump of
3084 bytes, then I can't print another such buffer: the osmo_static_string()
function can't know that the first printf() has already concluded, and still
considers that large chunk as in-use. So to be able to allow any number of
subsequent printf()s of the same huge size, I need the number-of-recent-checks
times that large size to fit in the static buffer.
So there is a tradeoff between how many previous buffers I can guarantee to be
unchanged vs. the maximum buffer size allowed per allocation.
I would actually like to ensure 10 or more recent buffers, so that a caller can
say: I can use up to 10 various osmo_xxx_name() functions in the same printf()
statement, and libosmocore will barf if I use too much.
I would also like to use less static char buffer -- but is ten times 4096 as
static string buffer really a lot? Not for an x86_64 desktop machine, but what
about embedded targets?
Since in practice the name buffer sizes we use are more like <80 chars each, in
practice we would be totally fine with one 4096 char buffer.
I have never seen a hexdump of 4Kb in practice.
I'm considering actually removing the 'recent' check again and just offloading
the responsibilty for name buffer usage to the caller.
Or I'm considering to reduce the max hexdump / msgb_hexdump size to something
saner like 1024 chars or even 256 chars. (Actually, hexdump could also loop in
chunks of 64 bytes or something like that).
Another consideration was about how to effect bounds checking. I don't want to
evaluate return values in printf() args. So I decided to provide generalized
API that returns NULL pointers if the size did not fit, but for convenience use
have one osmo_static_string() function that OSMO_ASSERT()s as soon as the size
doesn't fit, instead.
~N
--
- Neels Hofmeyr <nhofmeyr(a)sysmocom.de> http://www.sysmocom.de/
=======================================================================
* sysmocom - systems for mobile communications GmbH
* Alt-Moabit 93
* 10559 Berlin, Germany
* Sitz / Registered office: Berlin, HRB 134158 B
* Geschäftsführer / Managing Directors: Harald Welte
Dear Osmocom community,
for the last 10 days our "Debian installation test" job is consistently failing,
see https://jenkins.osmocom.org/jenkins/job/Osmocom-Debian-install-latest/
It somehow seems to be related to soapySDR mismatching versions where we use a 0.5 package
from the debian feed:
> Get:358 http://deb.debian.org/debian stretch/main amd64 libsoapysdr0.5-2 amd64 0.5.4-1 [64.4 kB]
and mix that with a 0.7 lms7 module from our feed:
> Get:425 http://download.opensuse.org/repositories/network:/osmocom:/latest/Debian_9… ./ soapysdr0.7-module-lms7 19.01.0-1 [49.9 kB]
> Unpacking soapysdr0.7-module-lms7:amd64 (19.01.0-1) ...
> dpkg: error processing archive /tmp/apt-dpkg-install-aYn9qf/398-soapysdr0.7-module-lms7_19.01.0-1_amd64.deb (--unpack):
> trying to overwrite '/usr/lib/x86_64-linux-gnu/SoapySDR/modules0.5-2/libLMS7Support.so', which is also in package
...
> Errors were encountered while processing: /tmp/apt-dpkg-install-aYn9qf/398-soapysdr0.7-module-lms7_19.01.0-1_amd64.deb
> E: Sub-process /usr/bin/dpkg returned an error code (1)
> Build step 'Execute shell' marked build as failure
> Finished: FAILURE
Does anyone know of any change that would have triggered this?
I've created https://osmocom.org/issues/3809 to track this.
Regards,
Harald
--
- Harald Welte <hwelte(a)sysmocom.de> http://www.sysmocom.de/
=======================================================================
* sysmocom - systems for mobile communications GmbH
* Alt-Moabit 93
* 10559 Berlin, Germany
* Sitz / Registered office: Berlin, HRB 134158 B
* Geschaeftsfuehrer / Managing Director: Harald Welte
Hi ! i'm very interested about GSUP <-> GSM MAP protocol conversion to
perform HLR interrogation (at least for plastic roaming support) ... is
there some related activity at OSMOCOM project ?
Wbr,
Alex