pespin has posted comments on this change by pespin. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/39633?usp=email )
Change subject: asp: Make sure asp->fi is set to NULL when freeing the object
......................................................................
Patch Set 1: Code-Review+2
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/39633?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I1e6a25f6db695a16bd05ae4ec481df6e14cf65b5
Gerrit-Change-Number: 39633
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-Comment-Date: Fri, 28 Feb 2025 16:19:03 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Attention is currently required from: daniel, laforge.
pespin has posted comments on this change by pespin. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/39630?usp=email )
Change subject: xua_rkm: Fix dynamic AS destroyed when multiple ASPs are associated
......................................................................
Patch Set 1: Code-Review+2
(1 comment)
Patchset:
PS1:
> Yes, I'm currently adding some tests to validate dynamic ASP/AS/RKM in osmo-stp. […]
Test which can be used to get to the scenario submitted here: https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/39647
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/39630?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I986044944282cea9a13ed59424f2220fee6fe567
Gerrit-Change-Number: 39630
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-Attention: laforge <laforge(a)osmocom.org>
Gerrit-Attention: daniel <dwillmann(a)sysmocom.de>
Gerrit-Comment-Date: Fri, 28 Feb 2025 16:18:59 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: laforge <laforge(a)osmocom.org>
Comment-In-Reply-To: pespin <pespin(a)sysmocom.de>
falconia has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-abis/+/39643?usp=email )
Change subject: TRAU encode: fix handling of OSMO_TRAU16_FT_IDLE
......................................................................
TRAU encode: fix handling of OSMO_TRAU16_FT_IDLE
GSM 08.60 sections 3.4 and 3.5.5 (renumbered to 5.4 and 5.5.5 in
3GPP TS 48.060) define a special frame type called Idle Speech Frame.
It is not clear if any historical BSS vendor actually implemented
these special frames - Nokia documentation explicitly mentions how
they were deemed unnecessary and omitted from implementation - but
libosmotrau includes support for this frame type.
Looking at the referenced spec sections, we can see the designers'
intent: the idle speech frame is just like FRv1 speech frames,
but with different UL/DL frame type codes in C1..C5 and with all
Dn bits replaced with constant-1 filler. Following this design
intent on the part of GSM spec authors, the philophically correct
behavior for osmo_trau_frame_encode() with regard to this frame type
should be to handle it exactly the same as OSMO_TRAU16_FT_FR
(support both DL and UL output, timing alignment in DL, possibility
of changing C6..C21 and T-bits), but don't look at fr->d_bits[],
fill constant 1s in their place instead.
However, the behavior of the encoding function for this frame type
prior to the present change was not like this at all: instead it
would emit a constant (once and for all) frame of 320 bits that was
always for DL no matter which direction was requested, would not
allow time alignment, and would not allow any C-bits to be controlled
by upper layers.
At the present time there is no code anywhere in Osmocom that feeds
OSMO_TRAU16_FT_IDLE to osmo_trau_frame_encode() - thus we don't have
to maintain backward bug compatibility, and we can fix this design bug.
Change-Id: Ibcc9e8628a56c6f089264c9d6b0dd27a1d5a7b60
---
M src/trau/trau_frame.c
1 file changed, 23 insertions(+), 44 deletions(-)
Approvals:
laforge: Looks good to me, but someone else must approve
pespin: Looks good to me, approved
Jenkins Builder: Verified
diff --git a/src/trau/trau_frame.c b/src/trau/trau_frame.c
index fb98247..74f4526 100644
--- a/src/trau/trau_frame.c
+++ b/src/trau/trau_frame.c
@@ -522,52 +522,31 @@
return 0;
}
-static struct osmo_trau_frame fr_idle_frame = {
- .type = OSMO_TRAU16_FT_IDLE,
- .dir = OSMO_TRAU_DIR_DL,
- .t_bits = { 1, 1, 1, 1 },
-};
-#define TRAU_FRAME_BITS (40*8)
-static ubit_t encoded_idle_frame[TRAU_FRAME_BITS];
-static int dbits_initted = 0;
-
-/*! \brief return pointer to global buffer containing a TRAU idle frame */
-static ubit_t *trau_idle_frame(void)
-{
- /* only initialize during the first call */
- if (!dbits_initted) {
- /* set all D-bits to 1 */
- memset(&fr_idle_frame.d_bits, 0x01, 260);
-
- memset(&fr_idle_frame.c_bits, 0x01, 25); /* spare are set to 1 */
- /* set Downlink Idle Speech Frame pattern */
- fr_idle_frame.c_bits[0] = 0; /* C1 */
- fr_idle_frame.c_bits[1] = 1; /* C2 */
- fr_idle_frame.c_bits[2] = 1; /* C3 */
- fr_idle_frame.c_bits[3] = 1; /* C4 */
- fr_idle_frame.c_bits[4] = 0; /* C5 */
- /* set no Time Alignment pattern */
- fr_idle_frame.c_bits[5] = 0; /* C6 */
- fr_idle_frame.c_bits[6] = 0; /* C7 */
- fr_idle_frame.c_bits[7] = 0; /* C8 */
- fr_idle_frame.c_bits[8] = 0; /* C9 */
- fr_idle_frame.c_bits[9] = 0; /* C10 */
- fr_idle_frame.c_bits[10] = 0; /* C11 */
- /* already set to 1, but maybe we need to modify it in the future */
- fr_idle_frame.c_bits[11] = 1; /* C12 (UFE), good frame */
- fr_idle_frame.c_bits[15] = 1; /* C16 (SP), no DTX */
-
- encode16_fr(encoded_idle_frame, &fr_idle_frame, false);
- dbits_initted = 1; /* set it to 1 to not call it again */
- }
- return encoded_idle_frame;
-}
-
/* TS 08.60 Section 3.4 */
static int encode16_idle(ubit_t *trau_bits, const struct osmo_trau_frame *fr)
{
- memcpy(trau_bits, trau_idle_frame(), 40*8);
- return 40 * 8;
+ const ubit_t *cbits5;
+
+ if (fr->dir == OSMO_TRAU_DIR_UL)
+ cbits5 = ft_idle_up_bits;
+ else
+ cbits5 = ft_idle_down_bits;
+
+ encode_sync16(trau_bits);
+
+ /* C1 .. C5 */
+ memcpy(trau_bits + 17, cbits5 + 0, 5);
+ /* C6 .. C15 */
+ memcpy(trau_bits + 17 + 5, fr->c_bits + 5, 15 - 5);
+ /* all 1s in the place of D-bits */
+ memset(trau_bits + 32, 1, 310 - 32);
+ /* C16 .. C21 */
+ memcpy(trau_bits + 310, fr->c_bits + 15, 6);
+ /* T1 .. T4 */
+ memcpy(trau_bits + 316, fr->t_bits, 4);
+
+ /* handle timing adjustment */
+ return encode16_handle_ta(trau_bits, fr);
}
/* TS 08.60 Section 3.3.1 */
@@ -1276,12 +1255,12 @@
case OSMO_TRAU16_FT_EFR:
case OSMO_TRAU16_FT_HR:
case OSMO_TRAU16_FT_AMR:
+ case OSMO_TRAU16_FT_IDLE:
/* timing alignment may happen: increased space requirement */
if (n_bits < 2 * 40 * 8 - 1)
return -ENOSPC;
break;
case OSMO_TRAU16_FT_OAM:
- case OSMO_TRAU16_FT_IDLE:
case OSMO_TRAU16_FT_DATA_HR:
case OSMO_TRAU16_FT_DATA:
case OSMO_TRAU16_FT_D145_SYNC:
--
To view, visit https://gerrit.osmocom.org/c/libosmo-abis/+/39643?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: libosmo-abis
Gerrit-Branch: master
Gerrit-Change-Id: Ibcc9e8628a56c6f089264c9d6b0dd27a1d5a7b60
Gerrit-Change-Number: 39643
Gerrit-PatchSet: 1
Gerrit-Owner: falconia <falcon(a)freecalypso.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: falconia <falcon(a)freecalypso.org>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
falconia has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-abis/+/39642?usp=email )
Change subject: rtp2trau HR: bring TRAU-16k support into alignment with TRAU-8k
......................................................................
rtp2trau HR: bring TRAU-16k support into alignment with TRAU-8k
GSM 08.61 defines two TRAU frame formats for HRv1 codec, using
either 16 kbit/s or 8 kbit/s submultiplexing. The 8k format is
the one actually implemented in legacy E1 BTS hardware, and is
also needed for global interoperability in TFO - whereas HR-16k
TRAU frame format appears to be a paper-only spec that was never
implemented in any hardware.
Despite the lack of hardware implementations, support for TRAU-16k
format for GSM-HR is already present in libosmotrau, originally
implemented along with FR and EFR. Removing this support from
Osmocom would look bad (there is always that off-chance that
perhaps some BSS vendor did implement this format after all),
hence let us do the next best thing: bring TRAU-16k support into
alignment with the actually working TRAU-8k support for the same
codec.
Thanks to previous clean-up patches in this area, rtp2trau support
for GSM-HR TRAU-DL output was already fully consistent between 16k
and 8k formats, but TRAU-UL output code was wildly inconsistent.
TRAU-8k-UL output code is new, takes TW-TS-002 input and can be
used to implement TFO (primary intended use) or emulate an E1 BTS.
However, previous TRAU-16k-UL output code dates back to the initial
creation of TRAU<->RTP code in 2020, has never been updated until
now, and is woefully inadequate for the task of emulating an E1 BTS.
(Because TFO always uses 8k format for HRv1, software emulation of
an E1 BTS is the only remaining plausible application for GSM-HR
TRAU-16k-UL output.)
With the present patch, the behavior of osmo_rtp2trau() for
OSMO_TRAU16_FT_HR UL changes drastically: TS 101 318 input is no
longer accepted, RFC 5993 input is still accepted but is not
functionally complete, and the proper/expected input format becomes
TW-TS-002, of which RFC 5993 is a subset. However, the detailed
behavior of osmo_rtp2trau() for HRv1 codec is now exactly the same
between 8k and 16k formats, in both DL and UL directions.
Change-Id: I1c19592967e7c6becc710990f512da5dee5043d2
---
M src/trau/trau_rtp_conv.c
1 file changed, 128 insertions(+), 47 deletions(-)
Approvals:
Jenkins Builder: Verified
pespin: Looks good to me, approved
laforge: Looks good to me, but someone else must approve
diff --git a/src/trau/trau_rtp_conv.c b/src/trau/trau_rtp_conv.c
index d5ac1fa..867a4e4 100644
--- a/src/trau/trau_rtp_conv.c
+++ b/src/trau/trau_rtp_conv.c
@@ -676,7 +676,7 @@
return 0;
}
-static int rtp2trau_hr16(struct osmo_trau_frame *tf, const uint8_t *data, size_t data_len)
+static int rtp2trau_hr16_dl(struct osmo_trau_frame *tf, const uint8_t *data, size_t data_len)
{
/* accept both TS 101 318 and RFC 5993 payloads */
switch (data_len) {
@@ -695,57 +695,26 @@
tf->type = OSMO_TRAU16_FT_HR;
- if (tf->dir == OSMO_TRAU_DIR_UL) {
- /* C1 .. C5 */
- tf->c_bits[0] = 0;
- tf->c_bits[1] = 0;
- tf->c_bits[2] = 0;
- tf->c_bits[3] = 1;
- tf->c_bits[4] = 1;
- } else {
- /* C1 .. C5 */
- tf->c_bits[0] = 1;
- tf->c_bits[1] = 1;
- tf->c_bits[2] = 1;
- tf->c_bits[3] = 0;
- tf->c_bits[4] = 1;
- }
+ /* C1 .. C5 */
+ tf->c_bits[0] = 1;
+ tf->c_bits[1] = 1;
+ tf->c_bits[2] = 1;
+ tf->c_bits[3] = 0;
+ tf->c_bits[4] = 1;
/* C6.. C11: Time Alignment */
memset(tf->c_bits + 5, 0, 6);
- if (tf->dir == OSMO_TRAU_DIR_UL) {
- /* BFI */
- if (data_len == 0)
- tf->c_bits[11] = 1;
- else
- tf->c_bits[11] = 0;
- if (osmo_hr_check_sid(data, data_len)) {
- /* SID=2 is a valid SID frame */
- tf->c_bits[12] = 1;
- tf->c_bits[13] = 0;
- } else {
- tf->c_bits[12] = 0;
- tf->c_bits[13] = 0;
- }
- /* FIXME: C15: TAF */
+ tf->c_bits[11] = 1; /* C12: UFE */
+ tf->c_bits[12] = 1; /* C13: spare */
+ tf->c_bits[13] = 1; /* C14: spare */
+ tf->c_bits[14] = 1; /* C15: spare */
+ if (osmo_hr_check_sid(data, data_len))
tf->c_bits[15] = 0; /* C16: SP */
- tf->c_bits[16] = 0; /* C17: DTXd shall not be applied */
- } else {
- tf->c_bits[11] = 1; /* C12: UFE */
- tf->c_bits[12] = 1; /* C13: spare */
- tf->c_bits[13] = 1; /* C14: spare */
- tf->c_bits[14] = 1; /* C15: spare */
- if (osmo_hr_check_sid(data, data_len))
- tf->c_bits[15] = 0; /* C16: SP */
- else
- tf->c_bits[15] = 1; /* C16: SP */
- tf->c_bits[16] = 1; /* C17: spare */
- }
+ else
+ tf->c_bits[15] = 1; /* C16: SP */
+ tf->c_bits[16] = 1; /* C17: spare */
memset(tf->c_bits+17, 1, 4); /* C18..C21: spare */
memset(&tf->t_bits[0], 1, 4);
- if (tf->dir == OSMO_TRAU_DIR_UL)
- tf->ufi = 0;
- else
- tf->ufi = 1;
+ tf->ufi = 1; /* spare bit in TRAU-DL */
if (data_len)
osmo_pbit2ubit(tf->d_bits, data, GSM_HR_BYTES * 8);
else
@@ -756,6 +725,118 @@
return 0;
}
+static int rtp2trau_hr16_ul(struct osmo_trau_frame *tf, const uint8_t *data, size_t data_len)
+{
+ uint8_t ft;
+ enum osmo_gsm631_sid_class sidc;
+ bool data_bits_req, bfi;
+
+ /* In TRAU-UL direction we require/expect TW-TS-002 RTP payload format;
+ * RFC 5993 is also accepted because it is a subset of TW-TS-002.
+ * TS 101 318 input is not supported for TRAU-UL output! */
+ if (data_len < 1)
+ return -EINVAL;
+ ft = data[0] >> 4;
+ switch (ft) {
+ case FT_GOOD_SPEECH:
+ bfi = false;
+ sidc = OSMO_GSM631_SID_CLASS_SPEECH;
+ data_bits_req = true;
+ break;
+ case FT_INVALID_SID:
+ /* There are 3 possible BFI/SID combinations in TRAU-16k-UL
+ * format for GSM-HR that all collapse to the same
+ * "invalid SID" code in TRAU-8k-UL and TW-TS-002 formats.
+ * Here we arbitrarily choose BFI=1 SID=1: compared to the
+ * other two options, this one has the greatest Hamming
+ * distance (in C-bits) to good speech or valid SID codes.
+ */
+ bfi = true;
+ sidc = OSMO_GSM631_SID_CLASS_INVALID;
+ data_bits_req = false;
+ break;
+ case FT_GOOD_SID:
+ bfi = false;
+ sidc = OSMO_GSM631_SID_CLASS_VALID;
+ data_bits_req = true;
+ break;
+ case FT_BFI_WITH_DATA:
+ bfi = true;
+ sidc = OSMO_GSM631_SID_CLASS_SPEECH;
+ data_bits_req = true;
+ break;
+ case FT_NO_DATA:
+ bfi = true;
+ sidc = OSMO_GSM631_SID_CLASS_SPEECH;
+ data_bits_req = false;
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* If the frame type is one that includes data bits, the payload length
+ * per RFC 5993 and TW-TS-002 is 15 bytes. If the frame type is one
+ * that does not include data bits, then the payload length per the
+ * same specs is only 1 byte - but we also accept 15-byte payloads
+ * in this case to make life easier for applications that pass the
+ * content of a buffer.
+ *
+ * When we make a TRAU-UL frame from FT=1 or FT=7, we fill all Dn bits
+ * with zeros if we got a short (1 byte) payload. However, if the
+ * application passed us a long (15 byte) payload despite FT being
+ * 1 or 7, we fill Dn bits with application-provided payload.
+ */
+ switch (data_len) {
+ case GSM_HR_BYTES_RTP_RFC5993:
+ break;
+ case 1:
+ if (data_bits_req)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ tf->type = OSMO_TRAU16_FT_HR;
+
+ /* C1 .. C5 */
+ tf->c_bits[0] = 0;
+ tf->c_bits[1] = 0;
+ tf->c_bits[2] = 0;
+ tf->c_bits[3] = 1;
+ tf->c_bits[4] = 1;
+ /* C6.. C11: Time Alignment */
+ memset(tf->c_bits + 5, 0, 6);
+ tf->c_bits[11] = bfi; /* C12: BFI */
+ tf->c_bits[12] = (sidc >> 1) & 1; /* C13: SID msb */
+ tf->c_bits[13] = (sidc >> 0) & 1; /* C14: SID lsb */
+ tf->c_bits[14] = data[0] & 0x01; /* C15: TAF */
+ tf->c_bits[15] = 1; /* C16: spare */
+ tf->c_bits[16] = (data[0] & 0x08) >> 3; /* C17: DTXd */
+ memset(tf->c_bits+17, 1, 4); /* C18..C21: spare */
+ memset(&tf->t_bits[0], 1, 4);
+ tf->ufi = (data[0] & 0x02) >> 1;
+ if (data_len > 1)
+ osmo_pbit2ubit(tf->d_bits, data + 1, GSM_HR_BYTES * 8);
+ else
+ memset(tf->d_bits, 0, GSM_HR_BYTES * 8);
+ /* CRC is *not* computed by TRAU frame encoder - we have to do it */
+ osmo_crc8gen_set_bits(&gsm0860_efr_crc3, tf->d_bits, 44, tf->crc_bits);
+
+ return 0;
+}
+
+static int rtp2trau_hr16(struct osmo_trau_frame *tf, const uint8_t *data, size_t data_len)
+{
+ switch (tf->dir) {
+ case OSMO_TRAU_DIR_DL:
+ return rtp2trau_hr16_dl(tf, data, data_len);
+ case OSMO_TRAU_DIR_UL:
+ return rtp2trau_hr16_ul(tf, data, data_len);
+ default:
+ return -EINVAL;
+ }
+}
+
static int rtp2trau_hr8_dl(struct osmo_trau_frame *tf, const uint8_t *data, size_t data_len)
{
/* accept both TS 101 318 and RFC 5993 payloads */
--
To view, visit https://gerrit.osmocom.org/c/libosmo-abis/+/39642?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: libosmo-abis
Gerrit-Branch: master
Gerrit-Change-Id: I1c19592967e7c6becc710990f512da5dee5043d2
Gerrit-Change-Number: 39642
Gerrit-PatchSet: 1
Gerrit-Owner: falconia <falcon(a)freecalypso.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: falconia <falcon(a)freecalypso.org>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
pespin has posted comments on this change by pespin. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/39640?usp=email )
Change subject: Make sure to NOTIFY current state to peer after ASP UP ACK / REG RESP
......................................................................
Patch Set 4:
This change is ready for review.
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/39640?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I3dffa2e9c554f03c7c721b757ff33a89961665b5
Gerrit-Change-Number: 39640
Gerrit-PatchSet: 4
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Comment-Date: Fri, 28 Feb 2025 16:07:49 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Attention is currently required from: pespin.
osmith has posted comments on this change by pespin. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/39634?usp=email )
Change subject: asp: Refactor osmo_ss7_asp_restart() into smaller chunks
......................................................................
Patch Set 1:
(1 comment)
File src/osmo_ss7_asp.c:
https://gerrit.osmocom.org/c/libosmo-sigtran/+/39634/comment/06297305_d2942… :
PS1, Line 689: /* First tear down previous state if existing: */
> Now, I did it on purpose, I think it helps in both contexts.
Acknowledged
--
To view, visit https://gerrit.osmocom.org/c/libosmo-sigtran/+/39634?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: libosmo-sigtran
Gerrit-Branch: master
Gerrit-Change-Id: I5c3461b724924f528b46f7fe815f017a5b4a1ff5
Gerrit-Change-Number: 39634
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Attention: pespin <pespin(a)sysmocom.de>
Gerrit-Comment-Date: Fri, 28 Feb 2025 12:34:52 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: osmith <osmith(a)sysmocom.de>
Comment-In-Reply-To: pespin <pespin(a)sysmocom.de>